1
0
Fork 0

added a /sim/view-name-popup bool to enable / disable the viewname popup ... enabled by default

This commit is contained in:
sydadams 2009-10-08 02:21:18 +00:00
parent a2a0534aab
commit 4dbe45348c

View file

@ -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);
} }
} }
}); });