diff --git a/Nasal/view.nas b/Nasal/view.nas
index 8decf1d24..9d7b8094b 100644
--- a/Nasal/view.nas
+++ b/Nasal/view.nas
@@ -192,7 +192,7 @@ var manager = {
},
register : func(which, handler = nil) {
if (num(which) == nil)
- which = view.indexof(which);
+ which = indexof(which);
if (handler == nil)
handler = default_handler;
me.views[which]["handler"] = handler;
@@ -204,7 +204,7 @@ var manager = {
if (which == nil)
which = index;
elsif (num(which) == nil)
- which = view.indexof(which);
+ which = indexof(which);
me.loopid += 1;
if (contains(me.current.handler, "stop"))
@@ -303,7 +303,7 @@ var fly_by_view_handler = {
me.latN.setValue(lat);
me.lonN.setValue(lon);
me.altN.setValue(alt * geo.M2FT);
- return 9.3;
+ return 8.3;
},
update : func {
return me.setpos();
@@ -311,6 +311,69 @@ var fly_by_view_handler = {
};
+var pilot_view_limiter = {
+ init : func {
+ me.hdgN = props.globals.getNode("/sim/current-view/heading-offset-deg");
+ me.xoffsetN = props.globals.getNode("/sim/current-view/x-offset-m");
+ me.xoffset_lowpass = aircraft.lowpass.new(0.1);
+ me.old_offset = 0;
+ },
+ start : func {
+ var limits = current.getNode("config/limits", 1);
+ me.heading_min = limits.getNode("heading-min-deg", 1).getValue();
+ me.heading_max = limits.getNode("heading-max-deg", 1).getValue();
+ me.max_xoffset = limits.getNode("x-offset-max-m", 1).getValue() or 0;
+ me.threshold_min = limits.getNode("x-offset-heading-min-deg", 1).getValue() or 0;
+ me.threshold_max = limits.getNode("x-offset-heading-max-deg", 1).getValue() or 0;
+
+ if (me.heading_max == nil)
+ me.heading_max = 1000;
+ if (me.heading_min == nil)
+ me.heading_min = -1000;
+ },
+ update : func {
+ var hdg = normdeg(me.hdgN.getValue());
+
+ if (hdg > me.heading_max)
+ me.hdgN.setDoubleValue(hdg = me.heading_max);
+ elsif (hdg < me.heading_min)
+ me.hdgN.setDoubleValue(hdg = me.heading_min);
+
+ # translate view on X axis to look far right or far left
+ if (me.max_xoffset) {
+ var norm = 0;
+ if (hdg <= me.threshold_min)
+ norm = (hdg - me.threshold_min) / (me.heading_min - me.threshold_min);
+ elsif (hdg >= me.threshold_max)
+ norm = -(hdg - me.threshold_max) / (me.heading_max - me.threshold_max);
+
+ var new_offset = me.xoffset_lowpass.filter(norm * me.max_xoffset);
+ me.xoffsetN.setDoubleValue(me.xoffsetN.getValue() - me.old_offset + new_offset);
+ me.old_offset = new_offset;
+ }
+ return 0;
+ },
+};
+
+
+var panViewDir = func(step) { # FIXME overrides panViewDir function from above; needs better integration
+ if (getprop("/sim/freeze/master"))
+ var prop = "/sim/current-view/heading-offset-deg";
+ else
+ var prop = "/sim/current-view/goal-heading-offset-deg";
+ var viewVal = getprop(prop);
+ var delta = step * VIEW_PAN_RATE * getprop("/sim/time/delta-realtime-sec");
+ var viewValSlew = normdeg(viewVal + delta);
+ var headingMax = current.getNode("config/limits/heading-max-deg", 1).getValue() or 1000;
+ var headingMin = current.getNode("config/limits/heading-min-deg", 1).getValue() or -1000;
+ if (viewValSlew > headingMax)
+ viewValSlew = headingMax;
+ elsif (viewValSlew < headingMin)
+ viewValSlew = headingMin;
+ setprop(prop, viewValSlew);
+}
+
+
#------------------------------------------------------------------------------
#
# Saves/restores/moves the view point (position, orientation, field-of-view).
@@ -485,6 +548,18 @@ _setlistener("/sim/signals/fdm-initialized", func {
manager.init();
manager.register("Fly-By View", fly_by_view_handler);
+
+ forindex (var i; views) {
+ var limits = views[i].getNode("config/limits/enabled");
+ if (limits != nil) {
+ func (index) {
+ setlistener(limits, func(n) {
+ manager.register(index, n.getValue() ? pilot_view_limiter : nil);
+ manager.set_view();
+ }, 1);
+ }(i);
+ }
+ }
});
diff --git a/preferences.xml b/preferences.xml
index d23d07362..9916e5668 100644
--- a/preferences.xml
+++ b/preferences.xml
@@ -282,6 +282,14 @@ Started September 2000 by David Megginson, david@megginson.com
270
315
true
+
+ false
+ -140
+ 140
+ 0.15
+ -65
+ 65
+