added a /sim/view-name-popup bool to enable / disable the viewname popup ... enabled by default
This commit is contained in:
parent
a2a0534aab
commit
4dbe45348c
1 changed files with 371 additions and 371 deletions
742
Nasal/view.nas
742
Nasal/view.nas
|
@ -6,19 +6,19 @@
|
||||||
var index = nil; # current view index
|
var index = nil; # current view index
|
||||||
var views = nil; # list of all view branches (/sim/view[n]) as props.Node
|
var views = nil; # list of all view branches (/sim/view[n]) as props.Node
|
||||||
var current = nil; # current view branch (e.g. /sim/view[1]) as props.Node
|
var current = nil; # current view branch (e.g. /sim/view[1]) as props.Node
|
||||||
|
var view_popup = props.globals.initNode("/sim/view-name-popup",1,"BOOL");
|
||||||
|
|
||||||
var hasmember = func(class, member) {
|
var hasmember = func(class, member) {
|
||||||
if (contains(class, member))
|
if (contains(class, member))
|
||||||
return 1;
|
return 1;
|
||||||
if (!contains(class, "parents"))
|
if (!contains(class, "parents"))
|
||||||
return 0;
|
return 0;
|
||||||
if (typeof(class.parents) != "vector")
|
if (typeof(class.parents) != "vector")
|
||||||
return 0;
|
return 0;
|
||||||
foreach (var parent; class.parents)
|
foreach (var parent; class.parents)
|
||||||
if (hasmember(parent, member))
|
if (hasmember(parent, member))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ var stepView = func(step, force = 0) {
|
||||||
setprop("/sim/current-view/view-number", n);
|
setprop("/sim/current-view/view-number", n);
|
||||||
|
|
||||||
# And pop up a nice reminder
|
# And pop up a nice reminder
|
||||||
gui.popupTip(views[n].getNode("name").getValue());
|
if (view_popup.getValue()) gui.popupTip(views[n].getNode("name").getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -153,7 +153,7 @@ var panViewPitch = func(step) {
|
||||||
# Reset view to default using current view manager (see default_handler).
|
# Reset view to default using current view manager (see default_handler).
|
||||||
#
|
#
|
||||||
var resetView = func {
|
var resetView = func {
|
||||||
manager.reset();
|
manager.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -161,10 +161,10 @@ var resetView = func {
|
||||||
# Default view handler used by view.manager.
|
# Default view handler used by view.manager.
|
||||||
#
|
#
|
||||||
var default_handler = {
|
var default_handler = {
|
||||||
reset : func {
|
reset : func {
|
||||||
resetViewDir();
|
resetViewDir();
|
||||||
resetFOV();
|
resetFOV();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -193,279 +193,279 @@ var default_handler = {
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
var manager = {
|
var manager = {
|
||||||
current : { node: nil, handler: default_handler },
|
current : { node: nil, handler: default_handler },
|
||||||
init : func {
|
init : func {
|
||||||
me.views = {};
|
me.views = {};
|
||||||
me.loopid = 0;
|
me.loopid = 0;
|
||||||
var viewnodes = props.globals.getNode("sim").getChildren("view");
|
var viewnodes = props.globals.getNode("sim").getChildren("view");
|
||||||
forindex (var i; viewnodes)
|
forindex (var i; viewnodes)
|
||||||
me.views[i] = { node: viewnodes[i], handler: default_handler };
|
me.views[i] = { node: viewnodes[i], handler: default_handler };
|
||||||
setlistener("/sim/current-view/view-number", func(n) {
|
setlistener("/sim/current-view/view-number", func(n) {
|
||||||
manager.set_view(n.getValue());
|
manager.set_view(n.getValue());
|
||||||
}, 1);
|
}, 1);
|
||||||
},
|
},
|
||||||
register : func(which, handler = nil) {
|
register : func(which, handler = nil) {
|
||||||
if (num(which) == nil)
|
if (num(which) == nil)
|
||||||
which = indexof(which);
|
which = indexof(which);
|
||||||
if (handler == nil)
|
if (handler == nil)
|
||||||
handler = default_handler;
|
handler = default_handler;
|
||||||
me.views[which]["handler"] = handler;
|
me.views[which]["handler"] = handler;
|
||||||
if (hasmember(handler, "init"))
|
if (hasmember(handler, "init"))
|
||||||
handler.init(me.views[which].node);
|
handler.init(me.views[which].node);
|
||||||
me.set_view();
|
me.set_view();
|
||||||
},
|
},
|
||||||
set_view : func(which = nil) {
|
set_view : func(which = nil) {
|
||||||
if (which == nil)
|
if (which == nil)
|
||||||
which = index;
|
which = index;
|
||||||
elsif (num(which) == nil)
|
elsif (num(which) == nil)
|
||||||
which = indexof(which);
|
which = indexof(which);
|
||||||
|
|
||||||
me.loopid += 1;
|
me.loopid += 1;
|
||||||
if (hasmember(me.current.handler, "stop"))
|
if (hasmember(me.current.handler, "stop"))
|
||||||
me.current.handler.stop();
|
me.current.handler.stop();
|
||||||
|
|
||||||
me.current = me.views[which];
|
me.current = me.views[which];
|
||||||
|
|
||||||
if (hasmember(me.current.handler, "start"))
|
if (hasmember(me.current.handler, "start"))
|
||||||
me.current.handler.start();
|
me.current.handler.start();
|
||||||
if (hasmember(me.current.handler, "update"))
|
if (hasmember(me.current.handler, "update"))
|
||||||
me._loop_(me.loopid += 1);
|
me._loop_(me.loopid += 1);
|
||||||
},
|
},
|
||||||
reset : func {
|
reset : func {
|
||||||
if (hasmember(me.current.handler, "reset"))
|
if (hasmember(me.current.handler, "reset"))
|
||||||
me.current.handler.reset();
|
me.current.handler.reset();
|
||||||
else
|
else
|
||||||
default_handler.reset();
|
default_handler.reset();
|
||||||
},
|
},
|
||||||
_loop_ : func(id) {
|
_loop_ : func(id) {
|
||||||
id == me.loopid or return;
|
id == me.loopid or return;
|
||||||
settimer(func { me._loop_(id) }, me.current.handler.update() or 0);
|
settimer(func { me._loop_(id) }, me.current.handler.update() or 0);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var fly_by_view_handler = {
|
var fly_by_view_handler = {
|
||||||
init : func {
|
init : func {
|
||||||
me.latN = props.globals.getNode("/sim/viewer/latitude-deg", 1);
|
me.latN = props.globals.getNode("/sim/viewer/latitude-deg", 1);
|
||||||
me.lonN = props.globals.getNode("/sim/viewer/longitude-deg", 1);
|
me.lonN = props.globals.getNode("/sim/viewer/longitude-deg", 1);
|
||||||
me.altN = props.globals.getNode("/sim/viewer/altitude-ft", 1);
|
me.altN = props.globals.getNode("/sim/viewer/altitude-ft", 1);
|
||||||
me.hdgN = props.globals.getNode("/orientation/heading-deg", 1);
|
me.hdgN = props.globals.getNode("/orientation/heading-deg", 1);
|
||||||
|
|
||||||
setlistener("/sim/signals/reinit", func(n) { n.getValue() or me.reset() });
|
setlistener("/sim/signals/reinit", func(n) { n.getValue() or me.reset() });
|
||||||
setlistener("/sim/crashed", func(n) { n.getValue() and me.reset() });
|
setlistener("/sim/crashed", func(n) { n.getValue() and me.reset() });
|
||||||
setlistener("/sim/freeze/replay-state", func {
|
setlistener("/sim/freeze/replay-state", func {
|
||||||
settimer(func { me.reset() }, 1); # time for replay to catch up
|
settimer(func { me.reset() }, 1); # time for replay to catch up
|
||||||
});
|
});
|
||||||
me.reset();
|
me.reset();
|
||||||
},
|
},
|
||||||
start : func {
|
start : func {
|
||||||
me.reset();
|
me.reset();
|
||||||
},
|
},
|
||||||
reset: func {
|
reset: func {
|
||||||
me.chase = -getprop("/sim/chase-distance-m");
|
me.chase = -getprop("/sim/chase-distance-m");
|
||||||
me.course = me.hdgN.getValue();
|
me.course = me.hdgN.getValue();
|
||||||
me.last = geo.aircraft_position();
|
me.last = geo.aircraft_position();
|
||||||
me.setpos(1);
|
me.setpos(1);
|
||||||
me.dist = 20;
|
me.dist = 20;
|
||||||
},
|
},
|
||||||
setpos : func(force = 0) {
|
setpos : func(force = 0) {
|
||||||
var pos = geo.aircraft_position();
|
var pos = geo.aircraft_position();
|
||||||
|
|
||||||
# check if the aircraft has moved enough
|
# check if the aircraft has moved enough
|
||||||
var dist = me.last.distance_to(pos);
|
var dist = me.last.distance_to(pos);
|
||||||
if (dist < 1.7 * me.chase and !force)
|
if (dist < 1.7 * me.chase and !force)
|
||||||
return 1.13;
|
return 1.13;
|
||||||
|
|
||||||
# "predict" and remember next aircraft position
|
# "predict" and remember next aircraft position
|
||||||
var course = me.hdgN.getValue();
|
var course = me.hdgN.getValue();
|
||||||
var delta_alt = (pos.alt() - me.last.alt()) * 0.5;
|
var delta_alt = (pos.alt() - me.last.alt()) * 0.5;
|
||||||
pos.apply_course_distance(course, dist * 0.8);
|
pos.apply_course_distance(course, dist * 0.8);
|
||||||
pos.set_alt(pos.alt() + delta_alt);
|
pos.set_alt(pos.alt() + delta_alt);
|
||||||
me.last.set(pos);
|
me.last.set(pos);
|
||||||
|
|
||||||
# apply random deviation
|
# apply random deviation
|
||||||
var radius = me.chase * (0.5 * rand() + 0.7);
|
var radius = me.chase * (0.5 * rand() + 0.7);
|
||||||
var agl = getprop("/position/altitude-agl-ft") * FT2M;
|
var agl = getprop("/position/altitude-agl-ft") * FT2M;
|
||||||
if (agl > me.chase)
|
if (agl > me.chase)
|
||||||
var angle = rand() * 2 * math.pi;
|
var angle = rand() * 2 * math.pi;
|
||||||
else
|
else
|
||||||
var angle = ((2 * rand() - 1) * 0.15 + 0.5) * (rand() < 0.5 ? -math.pi : math.pi);
|
var angle = ((2 * rand() - 1) * 0.15 + 0.5) * (rand() < 0.5 ? -math.pi : math.pi);
|
||||||
|
|
||||||
var dev_alt = math.cos(angle) * radius;
|
var dev_alt = math.cos(angle) * radius;
|
||||||
var dev_side = math.sin(angle) * radius;
|
var dev_side = math.sin(angle) * radius;
|
||||||
pos.apply_course_distance(course + 90, dev_side);
|
pos.apply_course_distance(course + 90, dev_side);
|
||||||
|
|
||||||
# and make sure it's not under ground
|
# and make sure it's not under ground
|
||||||
var lat = pos.lat();
|
var lat = pos.lat();
|
||||||
var lon = pos.lon();
|
var lon = pos.lon();
|
||||||
var alt = pos.alt();
|
var alt = pos.alt();
|
||||||
var elev = geo.elevation(lat, lon);
|
var elev = geo.elevation(lat, lon);
|
||||||
if (elev != nil) {
|
if (elev != nil) {
|
||||||
elev += 2; # min elevation
|
elev += 2; # min elevation
|
||||||
if (alt + dev_alt < elev and dev_alt < 0)
|
if (alt + dev_alt < elev and dev_alt < 0)
|
||||||
dev_alt = -dev_alt;
|
dev_alt = -dev_alt;
|
||||||
if (alt + dev_alt < elev)
|
if (alt + dev_alt < elev)
|
||||||
alt = elev;
|
alt = elev;
|
||||||
else
|
else
|
||||||
alt += dev_alt;
|
alt += dev_alt;
|
||||||
}
|
}
|
||||||
|
|
||||||
# set new view point
|
# set new view point
|
||||||
me.latN.setValue(lat);
|
me.latN.setValue(lat);
|
||||||
me.lonN.setValue(lon);
|
me.lonN.setValue(lon);
|
||||||
me.altN.setValue(alt * M2FT);
|
me.altN.setValue(alt * M2FT);
|
||||||
return 7.3;
|
return 7.3;
|
||||||
},
|
},
|
||||||
update : func {
|
update : func {
|
||||||
return me.setpos();
|
return me.setpos();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var model_view_handler = {
|
var model_view_handler = {
|
||||||
init: func(node) {
|
init: func(node) {
|
||||||
me.viewN = node;
|
me.viewN = node;
|
||||||
me.current = nil;
|
me.current = nil;
|
||||||
me.legendN = props.globals.initNode("/sim/current-view/model-view", "");
|
me.legendN = props.globals.initNode("/sim/current-view/model-view", "");
|
||||||
me.dialog = props.Node.new({ "dialog-name": "model-view" });
|
me.dialog = props.Node.new({ "dialog-name": "model-view" });
|
||||||
},
|
},
|
||||||
start: func {
|
start: func {
|
||||||
me.listener = setlistener("/sim/signals/multiplayer-updated", func me._update_(), 1);
|
me.listener = setlistener("/sim/signals/multiplayer-updated", func me._update_(), 1);
|
||||||
me.reset();
|
me.reset();
|
||||||
fgcommand("dialog-show", me.dialog);
|
fgcommand("dialog-show", me.dialog);
|
||||||
},
|
},
|
||||||
stop: func {
|
stop: func {
|
||||||
fgcommand("dialog-close", me.dialog);
|
fgcommand("dialog-close", me.dialog);
|
||||||
removelistener(me.listener);
|
removelistener(me.listener);
|
||||||
},
|
},
|
||||||
reset: func {
|
reset: func {
|
||||||
me.select(0);
|
me.select(0);
|
||||||
},
|
},
|
||||||
find: func(callsign) {
|
find: func(callsign) {
|
||||||
forindex (var i; me.list)
|
forindex (var i; me.list)
|
||||||
if (me.list[i].callsign == callsign)
|
if (me.list[i].callsign == callsign)
|
||||||
return i;
|
return i;
|
||||||
return nil;
|
return nil;
|
||||||
},
|
},
|
||||||
select: func(which) {
|
select: func(which) {
|
||||||
if (num(which) == nil)
|
if (num(which) == nil)
|
||||||
which = me.find(which) or 0; # turn callsign into index
|
which = me.find(which) or 0; # turn callsign into index
|
||||||
|
|
||||||
me.setup(me.list[which]);
|
me.setup(me.list[which]);
|
||||||
},
|
},
|
||||||
next: func(step) {
|
next: func(step) {
|
||||||
var i = me.find(me.current);
|
var i = me.find(me.current);
|
||||||
i = i == nil ? 0 : math.mod(i + step, size(me.list));
|
i = i == nil ? 0 : math.mod(i + step, size(me.list));
|
||||||
me.setup(me.list[i]);
|
me.setup(me.list[i]);
|
||||||
},
|
},
|
||||||
_update_: func {
|
_update_: func {
|
||||||
var self = { callsign: getprop("/sim/multiplay/callsign"), model:,
|
var self = { callsign: getprop("/sim/multiplay/callsign"), model:,
|
||||||
node: props.globals, root: '/' };
|
node: props.globals, root: '/' };
|
||||||
me.list = [self] ~ multiplayer.model.list;
|
me.list = [self] ~ multiplayer.model.list;
|
||||||
if (!me.find(me.current))
|
if (!me.find(me.current))
|
||||||
me.select(0);
|
me.select(0);
|
||||||
},
|
},
|
||||||
setup: func(data) {
|
setup: func(data) {
|
||||||
if (data.root == '/') {
|
if (data.root == '/') {
|
||||||
var zoffset = getprop("/sim/chase-distance-m");
|
var zoffset = getprop("/sim/chase-distance-m");
|
||||||
var ident = '[' ~ data.callsign ~ ']';
|
var ident = '[' ~ data.callsign ~ ']';
|
||||||
} else {
|
} else {
|
||||||
var zoffset = 70;
|
var zoffset = 70;
|
||||||
var ident = '"' ~ data.callsign ~ '" (' ~ data.model ~ ')';
|
var ident = '"' ~ data.callsign ~ '" (' ~ data.model ~ ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
me.current = data.callsign;
|
me.current = data.callsign;
|
||||||
me.legendN.setValue(ident);
|
me.legendN.setValue(ident);
|
||||||
setprop("/sim/current-view/z-offset-m", zoffset);
|
setprop("/sim/current-view/z-offset-m", zoffset);
|
||||||
|
|
||||||
me.viewN.getNode("config").setValues({
|
me.viewN.getNode("config").setValues({
|
||||||
"eye-lat-deg-path": data.root ~ "/position/latitude-deg",
|
"eye-lat-deg-path": data.root ~ "/position/latitude-deg",
|
||||||
"eye-lon-deg-path": data.root ~ "/position/longitude-deg",
|
"eye-lon-deg-path": data.root ~ "/position/longitude-deg",
|
||||||
"eye-alt-ft-path": data.root ~ "/position/altitude-ft",
|
"eye-alt-ft-path": data.root ~ "/position/altitude-ft",
|
||||||
"eye-heading-deg-path": data.root ~ "/orientation/heading-deg",
|
"eye-heading-deg-path": data.root ~ "/orientation/heading-deg",
|
||||||
"target-lat-deg-path": data.root ~ "/position/latitude-deg",
|
"target-lat-deg-path": data.root ~ "/position/latitude-deg",
|
||||||
"target-lon-deg-path": data.root ~ "/position/longitude-deg",
|
"target-lon-deg-path": data.root ~ "/position/longitude-deg",
|
||||||
"target-alt-ft-path": data.root ~ "/position/altitude-ft",
|
"target-alt-ft-path": data.root ~ "/position/altitude-ft",
|
||||||
"target-heading-deg-path": data.root ~ "/orientation/heading-deg",
|
"target-heading-deg-path": data.root ~ "/orientation/heading-deg",
|
||||||
"target-pitch-deg-path": data.root ~ "/orientation/pitch-deg",
|
"target-pitch-deg-path": data.root ~ "/orientation/pitch-deg",
|
||||||
"target-roll-deg-path": data.root ~ "/orientation/roll-deg",
|
"target-roll-deg-path": data.root ~ "/orientation/roll-deg",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var pilot_view_limiter = {
|
var pilot_view_limiter = {
|
||||||
new : func {
|
new : func {
|
||||||
return { parents: [pilot_view_limiter] };
|
return { parents: [pilot_view_limiter] };
|
||||||
},
|
},
|
||||||
init : func {
|
init : func {
|
||||||
me.hdgN = props.globals.getNode("/sim/current-view/heading-offset-deg");
|
me.hdgN = props.globals.getNode("/sim/current-view/heading-offset-deg");
|
||||||
me.xoffsetN = props.globals.getNode("/sim/current-view/x-offset-m");
|
me.xoffsetN = props.globals.getNode("/sim/current-view/x-offset-m");
|
||||||
me.xoffset_lowpass = aircraft.lowpass.new(0.1);
|
me.xoffset_lowpass = aircraft.lowpass.new(0.1);
|
||||||
me.last_offset = 0;
|
me.last_offset = 0;
|
||||||
},
|
},
|
||||||
start : func {
|
start : func {
|
||||||
var limits = current.getNode("config/limits", 1);
|
var limits = current.getNode("config/limits", 1);
|
||||||
me.left = {
|
me.left = {
|
||||||
heading_max : abs(limits.getNode("left/heading-max-deg", 1).getValue() or 1000),
|
heading_max : abs(limits.getNode("left/heading-max-deg", 1).getValue() or 1000),
|
||||||
threshold : abs(limits.getNode("left/x-offset-threshold-deg", 1).getValue() or 0),
|
threshold : abs(limits.getNode("left/x-offset-threshold-deg", 1).getValue() or 0),
|
||||||
xoffset_max : abs(limits.getNode("left/x-offset-max-m", 1).getValue() or 0),
|
xoffset_max : abs(limits.getNode("left/x-offset-max-m", 1).getValue() or 0),
|
||||||
};
|
};
|
||||||
me.right = {
|
me.right = {
|
||||||
heading_max : -abs(limits.getNode("right/heading-max-deg", 1).getValue() or 1000),
|
heading_max : -abs(limits.getNode("right/heading-max-deg", 1).getValue() or 1000),
|
||||||
threshold : -abs(limits.getNode("right/x-offset-threshold-deg", 1).getValue() or 0),
|
threshold : -abs(limits.getNode("right/x-offset-threshold-deg", 1).getValue() or 0),
|
||||||
xoffset_max : -abs(limits.getNode("right/x-offset-max-m", 1).getValue() or 0),
|
xoffset_max : -abs(limits.getNode("right/x-offset-max-m", 1).getValue() or 0),
|
||||||
};
|
};
|
||||||
me.left.scale = me.left.xoffset_max / (me.left.heading_max - me.left.threshold);
|
me.left.scale = me.left.xoffset_max / (me.left.heading_max - me.left.threshold);
|
||||||
me.right.scale = me.right.xoffset_max / (me.right.heading_max - me.right.threshold);
|
me.right.scale = me.right.xoffset_max / (me.right.heading_max - me.right.threshold);
|
||||||
me.last_hdg = normdeg(me.hdgN.getValue());
|
me.last_hdg = normdeg(me.hdgN.getValue());
|
||||||
me.enable_xoffset = me.right.xoffset_max > 0.001 or me.left.xoffset_max > 0.001;
|
me.enable_xoffset = me.right.xoffset_max > 0.001 or me.left.xoffset_max > 0.001;
|
||||||
},
|
},
|
||||||
update : func {
|
update : func {
|
||||||
if (getprop("/devices/status/keyboard/ctrl"))
|
if (getprop("/devices/status/keyboard/ctrl"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var hdg = normdeg(me.hdgN.getValue());
|
var hdg = normdeg(me.hdgN.getValue());
|
||||||
if (abs(me.last_hdg - hdg) > 180) # avoid wrap-around skips
|
if (abs(me.last_hdg - hdg) > 180) # avoid wrap-around skips
|
||||||
me.hdgN.setDoubleValue(hdg = me.last_hdg);
|
me.hdgN.setDoubleValue(hdg = me.last_hdg);
|
||||||
elsif (hdg > me.left.heading_max)
|
elsif (hdg > me.left.heading_max)
|
||||||
me.hdgN.setDoubleValue(hdg = me.left.heading_max);
|
me.hdgN.setDoubleValue(hdg = me.left.heading_max);
|
||||||
elsif (hdg < me.right.heading_max)
|
elsif (hdg < me.right.heading_max)
|
||||||
me.hdgN.setDoubleValue(hdg = me.right.heading_max);
|
me.hdgN.setDoubleValue(hdg = me.right.heading_max);
|
||||||
me.last_hdg = hdg;
|
me.last_hdg = hdg;
|
||||||
|
|
||||||
# translate view on X axis to look far right or far left
|
# translate view on X axis to look far right or far left
|
||||||
if (me.enable_xoffset) {
|
if (me.enable_xoffset) {
|
||||||
var offset = 0;
|
var offset = 0;
|
||||||
if (hdg > me.left.threshold)
|
if (hdg > me.left.threshold)
|
||||||
offset = (me.left.threshold - hdg) * me.left.scale;
|
offset = (me.left.threshold - hdg) * me.left.scale;
|
||||||
elsif (hdg < me.right.threshold)
|
elsif (hdg < me.right.threshold)
|
||||||
offset = (me.right.threshold - hdg) * me.right.scale;
|
offset = (me.right.threshold - hdg) * me.right.scale;
|
||||||
|
|
||||||
var new_offset = me.xoffset_lowpass.filter(offset);
|
var new_offset = me.xoffset_lowpass.filter(offset);
|
||||||
me.xoffsetN.setDoubleValue(me.xoffsetN.getValue() - me.last_offset + new_offset);
|
me.xoffsetN.setDoubleValue(me.xoffsetN.getValue() - me.last_offset + new_offset);
|
||||||
me.last_offset = new_offset;
|
me.last_offset = new_offset;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var panViewDir = func(step) { # FIXME overrides panViewDir function from above; needs better integration
|
var panViewDir = func(step) { # FIXME overrides panViewDir function from above; needs better integration
|
||||||
if (getprop("/sim/freeze/master"))
|
if (getprop("/sim/freeze/master"))
|
||||||
var prop = "/sim/current-view/heading-offset-deg";
|
var prop = "/sim/current-view/heading-offset-deg";
|
||||||
else
|
else
|
||||||
var prop = "/sim/current-view/goal-heading-offset-deg";
|
var prop = "/sim/current-view/goal-heading-offset-deg";
|
||||||
var viewVal = getprop(prop);
|
var viewVal = getprop(prop);
|
||||||
var delta = step * VIEW_PAN_RATE * getprop("/sim/time/delta-realtime-sec");
|
var delta = step * VIEW_PAN_RATE * getprop("/sim/time/delta-realtime-sec");
|
||||||
var viewValSlew = normdeg(viewVal + delta);
|
var viewValSlew = normdeg(viewVal + delta);
|
||||||
var headingMax = abs(current.getNode("config/limits/left/heading-max-deg", 1).getValue() or 1000);
|
var headingMax = abs(current.getNode("config/limits/left/heading-max-deg", 1).getValue() or 1000);
|
||||||
var headingMin = -abs(current.getNode("config/limits/right/heading-max-deg", 1).getValue() or 1000);
|
var headingMin = -abs(current.getNode("config/limits/right/heading-max-deg", 1).getValue() or 1000);
|
||||||
if (viewValSlew > headingMax)
|
if (viewValSlew > headingMax)
|
||||||
viewValSlew = headingMax;
|
viewValSlew = headingMax;
|
||||||
elsif (viewValSlew < headingMin)
|
elsif (viewValSlew < headingMin)
|
||||||
viewValSlew = headingMin;
|
viewValSlew = headingMin;
|
||||||
setprop(prop, viewValSlew);
|
setprop(prop, viewValSlew);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -506,11 +506,11 @@ var panViewDir = func(step) { # FIXME overrides panViewDir function from above;
|
||||||
# Normalize angle to -180 <= angle < 180
|
# Normalize angle to -180 <= angle < 180
|
||||||
#
|
#
|
||||||
var normdeg = func(a) {
|
var normdeg = func(a) {
|
||||||
while (a >= 180)
|
while (a >= 180)
|
||||||
a -= 360;
|
a -= 360;
|
||||||
while (a < -180)
|
while (a < -180)
|
||||||
a += 360;
|
a += 360;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -519,24 +519,24 @@ var normdeg = func(a) {
|
||||||
# field-of-view parameter is also managed by this class.)
|
# field-of-view parameter is also managed by this class.)
|
||||||
#
|
#
|
||||||
var ViewAxis = {
|
var ViewAxis = {
|
||||||
new : func(prop) {
|
new : func(prop) {
|
||||||
var m = { parents : [ViewAxis] };
|
var m = { parents : [ViewAxis] };
|
||||||
m.prop = props.globals.getNode(prop, 1);
|
m.prop = props.globals.getNode(prop, 1);
|
||||||
if (m.prop.getType() == "NONE")
|
if (m.prop.getType() == "NONE")
|
||||||
m.prop.setDoubleValue(0);
|
m.prop.setDoubleValue(0);
|
||||||
|
|
||||||
m.from = m.to = m.prop.getValue();
|
m.from = m.to = m.prop.getValue();
|
||||||
return m;
|
return m;
|
||||||
},
|
},
|
||||||
reset : func {
|
reset : func {
|
||||||
me.from = me.to = normdeg(me.prop.getValue());
|
me.from = me.to = normdeg(me.prop.getValue());
|
||||||
},
|
},
|
||||||
target : func(v) {
|
target : func(v) {
|
||||||
me.to = normdeg(v);
|
me.to = normdeg(v);
|
||||||
},
|
},
|
||||||
move : func(blend) {
|
move : func(blend) {
|
||||||
me.prop.setValue(me.from + blend * (me.to - me.from));
|
me.prop.setValue(me.from + blend * (me.to - me.from));
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -545,62 +545,62 @@ var ViewAxis = {
|
||||||
# view.point: handles smooth view movements
|
# view.point: handles smooth view movements
|
||||||
#
|
#
|
||||||
var point = {
|
var point = {
|
||||||
init : func {
|
init : func {
|
||||||
me.axes = {
|
me.axes = {
|
||||||
"heading-offset-deg" : ViewAxis.new("/sim/current-view/goal-heading-offset-deg"),
|
"heading-offset-deg" : ViewAxis.new("/sim/current-view/goal-heading-offset-deg"),
|
||||||
"pitch-offset-deg" : ViewAxis.new("/sim/current-view/goal-pitch-offset-deg"),
|
"pitch-offset-deg" : ViewAxis.new("/sim/current-view/goal-pitch-offset-deg"),
|
||||||
"roll-offset-deg" : ViewAxis.new("/sim/current-view/goal-roll-offset-deg"),
|
"roll-offset-deg" : ViewAxis.new("/sim/current-view/goal-roll-offset-deg"),
|
||||||
"x-offset-m" : ViewAxis.new("/sim/current-view/x-offset-m"),
|
"x-offset-m" : ViewAxis.new("/sim/current-view/x-offset-m"),
|
||||||
"y-offset-m" : ViewAxis.new("/sim/current-view/y-offset-m"),
|
"y-offset-m" : ViewAxis.new("/sim/current-view/y-offset-m"),
|
||||||
"z-offset-m" : ViewAxis.new("/sim/current-view/z-offset-m"),
|
"z-offset-m" : ViewAxis.new("/sim/current-view/z-offset-m"),
|
||||||
"field-of-view" : ViewAxis.new("/sim/current-view/field-of-view"),
|
"field-of-view" : ViewAxis.new("/sim/current-view/field-of-view"),
|
||||||
};
|
};
|
||||||
me.storeN = props.Node.new();
|
me.storeN = props.Node.new();
|
||||||
me.dtN = props.globals.getNode("/sim/time/delta-realtime-sec", 1);
|
me.dtN = props.globals.getNode("/sim/time/delta-realtime-sec", 1);
|
||||||
me.currviewN = props.globals.getNode("/sim/current-view", 1);
|
me.currviewN = props.globals.getNode("/sim/current-view", 1);
|
||||||
me.blend = 0;
|
me.blend = 0;
|
||||||
me.loop_id = 0;
|
me.loop_id = 0;
|
||||||
props.copy(props.globals.getNode("/sim/view/config"), me.storeN);
|
props.copy(props.globals.getNode("/sim/view/config"), me.storeN);
|
||||||
},
|
},
|
||||||
save : func {
|
save : func {
|
||||||
me.storeN = props.Node.new();
|
me.storeN = props.Node.new();
|
||||||
props.copy(me.currviewN, me.storeN);
|
props.copy(me.currviewN, me.storeN);
|
||||||
return me.storeN;
|
return me.storeN;
|
||||||
},
|
},
|
||||||
restore : func {
|
restore : func {
|
||||||
me.move(me.storeN);
|
me.move(me.storeN);
|
||||||
},
|
},
|
||||||
move : func(prop, time = nil) {
|
move : func(prop, time = nil) {
|
||||||
prop != nil or return;
|
prop != nil or return;
|
||||||
foreach (var a; keys(me.axes)) {
|
foreach (var a; keys(me.axes)) {
|
||||||
var n = prop.getNode(a);
|
var n = prop.getNode(a);
|
||||||
me.axes[a].reset();
|
me.axes[a].reset();
|
||||||
if (n != nil)
|
if (n != nil)
|
||||||
me.axes[a].target(n.getValue());
|
me.axes[a].target(n.getValue());
|
||||||
}
|
}
|
||||||
var m = prop.getNode("move-time-sec");
|
var m = prop.getNode("move-time-sec");
|
||||||
if (m != nil)
|
if (m != nil)
|
||||||
time = m.getValue();
|
time = m.getValue();
|
||||||
|
|
||||||
if (time == nil)
|
if (time == nil)
|
||||||
time = 1;
|
time = 1;
|
||||||
|
|
||||||
me.blend = -1; # range -1 .. 1
|
me.blend = -1; # range -1 .. 1
|
||||||
me._loop_(me.loop_id += 1, time);
|
me._loop_(me.loop_id += 1, time);
|
||||||
},
|
},
|
||||||
_loop_ : func(id, time) {
|
_loop_ : func(id, time) {
|
||||||
me.loop_id == id or return;
|
me.loop_id == id or return;
|
||||||
me.blend += me.dtN.getValue() / time;
|
me.blend += me.dtN.getValue() / time;
|
||||||
if (me.blend > 1)
|
if (me.blend > 1)
|
||||||
me.blend = 1;
|
me.blend = 1;
|
||||||
|
|
||||||
var b = (math.sin(me.blend * math.pi / 2) + 1) / 2; # range 0 .. 1
|
var b = (math.sin(me.blend * math.pi / 2) + 1) / 2; # range 0 .. 1
|
||||||
foreach (var a; keys(me.axes))
|
foreach (var a; keys(me.axes))
|
||||||
me.axes[a].move(b);
|
me.axes[a].move(b);
|
||||||
|
|
||||||
if (me.blend < 1)
|
if (me.blend < 1)
|
||||||
settimer(func { me._loop_(id, time) }, 0);
|
settimer(func { me._loop_(id, time) }, 0);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -609,52 +609,52 @@ var fovProp = nil;
|
||||||
|
|
||||||
|
|
||||||
_setlistener("/sim/signals/nasal-dir-initialized", func {
|
_setlistener("/sim/signals/nasal-dir-initialized", func {
|
||||||
views = props.globals.getNode("/sim").getChildren("view");
|
views = props.globals.getNode("/sim").getChildren("view");
|
||||||
fovProp = props.globals.getNode("/sim/current-view/field-of-view");
|
fovProp = props.globals.getNode("/sim/current-view/field-of-view");
|
||||||
point.init();
|
point.init();
|
||||||
|
|
||||||
setlistener("/sim/current-view/view-number", func(n) {
|
setlistener("/sim/current-view/view-number", func(n) {
|
||||||
current = views[index = n.getValue()];
|
current = views[index = n.getValue()];
|
||||||
}, 1);
|
}, 1);
|
||||||
|
|
||||||
props.globals.initNode("/position/altitude-agl-ft"); # needed by Fly-By View
|
props.globals.initNode("/position/altitude-agl-ft"); # needed by Fly-By View
|
||||||
manager.init();
|
manager.init();
|
||||||
manager.register("Fly-By View", fly_by_view_handler);
|
manager.register("Fly-By View", fly_by_view_handler);
|
||||||
manager.register("Model View", model_view_handler);
|
manager.register("Model View", model_view_handler);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
_setlistener("/sim/signals/fdm-initialized", func {
|
_setlistener("/sim/signals/fdm-initialized", func {
|
||||||
var zoffset = nil;
|
var zoffset = nil;
|
||||||
foreach (var v; views) {
|
foreach (var v; views) {
|
||||||
var index = v.getIndex();
|
var index = v.getIndex();
|
||||||
if (index > 7 and index < 100) {
|
if (index > 7 and index < 100) {
|
||||||
globals["view"] = nil;
|
globals["view"] = nil;
|
||||||
die("\n***\n*\n* Illegal use of reserved view index "
|
die("\n***\n*\n* Illegal use of reserved view index "
|
||||||
~ index ~ ". Use indices >= 100!\n*\n***");
|
~ index ~ ". Use indices >= 100!\n*\n***");
|
||||||
} elsif (index >= 100 and index < 200) {
|
} elsif (index >= 100 and index < 200) {
|
||||||
if (v.getNode("name") == nil)
|
if (v.getNode("name") == nil)
|
||||||
continue;
|
continue;
|
||||||
var e = v.getNode("enabled");
|
var e = v.getNode("enabled");
|
||||||
if (e != nil) {
|
if (e != nil) {
|
||||||
aircraft.data.add(e);
|
aircraft.data.add(e);
|
||||||
e.setAttribute("userarchive", 0);
|
e.setAttribute("userarchive", 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
forindex (var i; views) {
|
forindex (var i; views) {
|
||||||
var limits = views[i].getNode("config/limits/enabled");
|
var limits = views[i].getNode("config/limits/enabled");
|
||||||
if (limits != nil) {
|
if (limits != nil) {
|
||||||
func (i) {
|
func (i) {
|
||||||
var limiter = pilot_view_limiter.new();
|
var limiter = pilot_view_limiter.new();
|
||||||
setlistener(limits, func(n) {
|
setlistener(limits, func(n) {
|
||||||
manager.register(i, n.getBoolValue() ? limiter : nil);
|
manager.register(i, n.getBoolValue() ? limiter : nil);
|
||||||
manager.set_view();
|
manager.set_view();
|
||||||
}, 1);
|
}, 1);
|
||||||
}(i);
|
}(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue