- first stab at making dynamic view parameters configurable on a per-aircraft
basis; see bo105.nas for an example; expect some changes, though - move "lookat" feature here from bo105.nas (used by "flaps up" bindings)
This commit is contained in:
parent
354a0f59ff
commit
0529f66842
1 changed files with 90 additions and 77 deletions
|
@ -84,7 +84,7 @@ ViewAxis = {
|
||||||
# sim/current-view/goal-*-offset-deg properties.
|
# sim/current-view/goal-*-offset-deg properties.
|
||||||
#
|
#
|
||||||
ViewManager = {
|
ViewManager = {
|
||||||
new : func(c) {
|
new : func {
|
||||||
var m = { parents : [ViewManager] };
|
var m = { parents : [ViewManager] };
|
||||||
m.elapsedN = props.globals.getNode("/sim/time/elapsed-sec", 1);
|
m.elapsedN = props.globals.getNode("/sim/time/elapsed-sec", 1);
|
||||||
m.deltaN = props.globals.getNode("/sim/time/delta-realtime-sec", 1);
|
m.deltaN = props.globals.getNode("/sim/time/delta-realtime-sec", 1);
|
||||||
|
@ -102,27 +102,33 @@ ViewManager = {
|
||||||
m.pitch_axis = ViewAxis.new("/sim/current-view/goal-pitch-offset-deg");
|
m.pitch_axis = ViewAxis.new("/sim/current-view/goal-pitch-offset-deg");
|
||||||
m.roll_axis = ViewAxis.new("/sim/current-view/goal-roll-offset-deg");
|
m.roll_axis = ViewAxis.new("/sim/current-view/goal-roll-offset-deg");
|
||||||
|
|
||||||
# accerations are converted to G (one G is subtraced from z-accel)
|
# accelerations are converted to G (one G is subtraced from z-accel)
|
||||||
m.ax = Input.new("/accelerations/pilot/x-accel-fps_sec", 0.03108095, 0, 0.58, 0);
|
m.axI = Input.new("/accelerations/pilot/x-accel-fps_sec", 0.03108095, 0, 0.58, 0);
|
||||||
m.ay = Input.new("/accelerations/pilot/y-accel-fps_sec", 0.03108095, 0, 0.95);
|
m.ayI = Input.new("/accelerations/pilot/y-accel-fps_sec", 0.03108095, 0, 0.95);
|
||||||
m.az = Input.new("/accelerations/pilot/z-accel-fps_sec", -0.03108095, -1, 0.46);
|
m.azI = Input.new("/accelerations/pilot/z-accel-fps_sec", -0.03108095, -1, 0.46);
|
||||||
|
|
||||||
# velocities are converted to knots
|
# velocities are converted to knots
|
||||||
m.vx = Input.new("/velocities/uBody-fps", 0.5924838, 0, 0.45);
|
m.vxI = Input.new("/velocities/uBody-fps", 0.5924838, 0, 0.45);
|
||||||
m.vy = Input.new("/velocities/vBody-fps", 0.5924838, 0);
|
m.vyI = Input.new("/velocities/vBody-fps", 0.5924838, 0);
|
||||||
m.vz = Input.new("/velocities/wBody-fps", 0.5924838, 0);
|
m.vzI = Input.new("/velocities/wBody-fps", 0.5924838, 0);
|
||||||
|
|
||||||
# turn WoW bool into smooth values ranging from 0 to 1
|
# turn WoW bool into smooth values ranging from 0 to 1
|
||||||
m.wow = Input.new("/gear/gear/wow", 1, 0, 0.74);
|
m.wowI = Input.new("/gear/gear/wow", 1, 0, 0.74);
|
||||||
m.hdg_change = aircraft.lowpass.new(0.95);
|
m.hdg_change = aircraft.lowpass.new(0.95);
|
||||||
m.ubody = aircraft.lowpass.new(0.95);
|
m.ubody = aircraft.lowpass.new(0.95);
|
||||||
m.last_heading = m.headingN.getValue();
|
m.last_heading = m.headingN.getValue();
|
||||||
m.size_factor = -getprop("/sim/chase-distance-m") / 25;
|
m.size_factor = -getprop("/sim/chase-distance-m") / 25;
|
||||||
m.is_helicopter = props.globals.getNode("rotors", 0) != nil;
|
|
||||||
|
if (props.globals.getNode("rotors", 0) != nil) {
|
||||||
|
m.default_helicopter();
|
||||||
|
} else {
|
||||||
|
m.default_plane();
|
||||||
|
}
|
||||||
m.reset();
|
m.reset();
|
||||||
return m;
|
return m;
|
||||||
},
|
},
|
||||||
reset : func {
|
reset : func {
|
||||||
|
me.lookat_active = 0;
|
||||||
me.heading_axis.reset();
|
me.heading_axis.reset();
|
||||||
me.pitch_axis.reset();
|
me.pitch_axis.reset();
|
||||||
me.roll_axis.reset();
|
me.roll_axis.reset();
|
||||||
|
@ -134,55 +140,88 @@ ViewManager = {
|
||||||
me.roll_axis.add_offset();
|
me.roll_axis.add_offset();
|
||||||
},
|
},
|
||||||
apply : func {
|
apply : func {
|
||||||
var pitch = me.pitchN.getValue();
|
if (me.lookat_active) {
|
||||||
var roll = me.rollN.getValue();
|
me.heading_axis.prop.setValue(me.lookat_heading);
|
||||||
var wow = me.wow.get();
|
me.pitch_axis.prop.setValue(me.lookat_pitch);
|
||||||
var az = me.az.get();
|
return;
|
||||||
var vx = me.vx.get();
|
}
|
||||||
|
|
||||||
# calculate sideslip factor (zeroed when no forward ground speed)
|
me.pitch = me.pitchN.getValue();
|
||||||
var wspd = me.wind_speedN.getValue();
|
me.roll = me.rollN.getValue();
|
||||||
var wdir = me.headingN.getValue() - me.wind_dirN.getValue();
|
me.wow = me.wowI.get();
|
||||||
var u = vx - wspd * cos(wdir);
|
|
||||||
var slip = sin(me.slipN.getValue()) * me.ubody.filter(normatan(u / 10));
|
|
||||||
|
|
||||||
|
me.calc != nil and me.calc();
|
||||||
|
me.calc_heading != nil and me.heading_axis.apply(me.calc_heading());
|
||||||
|
me.calc_pitch != nil and me.pitch_axis.apply(me.calc_pitch());
|
||||||
|
me.calc_roll != nil and me.roll_axis.apply(me.calc_roll());
|
||||||
|
},
|
||||||
|
lookat : func(h = nil, p = nil) {
|
||||||
|
if (h == nil) {
|
||||||
|
view.resetView();
|
||||||
|
me.lookat_active = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
me.lookat_heading = h;
|
||||||
|
me.lookat_pitch = p;
|
||||||
|
me.lookat_active = 1;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ViewManager.default_plane = func {
|
||||||
|
me.calc = func {
|
||||||
# calculate steering factor
|
# calculate steering factor
|
||||||
var hdg = me.headingN.getValue();
|
var hdg = me.headingN.getValue();
|
||||||
var hdiff = normdeg(me.last_heading - hdg);
|
var hdiff = normdeg(me.last_heading - hdg);
|
||||||
me.last_heading = hdg;
|
me.last_heading = hdg;
|
||||||
var steering = normatan(me.hdg_change.filter(hdiff)) * me.size_factor;
|
me.steering = normatan(me.hdg_change.filter(hdiff)) * me.size_factor;
|
||||||
|
|
||||||
if (me.is_helicopter) {
|
me.az = me.azI.get();
|
||||||
var speed = 1 - normatan(me.speedN.getValue() / 20);
|
me.vx = me.vxI.get();
|
||||||
|
|
||||||
me.heading_axis.apply( # view heading due to ...
|
# calculate sideslip factor (zeroed when no forward ground speed)
|
||||||
(roll < 0 ? -50 : -25) * npow(sin(roll) * cos(pitch), 2) # roll
|
var wspd = me.wind_speedN.getValue();
|
||||||
);
|
var wdir = me.headingN.getValue() - me.wind_dirN.getValue();
|
||||||
me.pitch_axis.apply( # view pitch due to ...
|
var u = me.vx - wspd * cos(wdir);
|
||||||
(pitch < 0 ? -35 : -40) * sin(pitch) * speed # pitch
|
me.slip = sin(me.slipN.getValue()) * me.ubody.filter(normatan(u / 10));
|
||||||
+ 15 * sin(roll) * sin(roll) # roll
|
}
|
||||||
);
|
|
||||||
me.roll_axis.apply( # view roll due to ...
|
|
||||||
-15 * sin(roll) * cos(pitch) * speed # roll
|
|
||||||
);
|
|
||||||
|
|
||||||
} else {
|
me.calc_heading = func { # heading
|
||||||
me.heading_axis.apply( # heading ...
|
-15 * sin(me.roll) * cos(me.pitch) # due to roll
|
||||||
-15 * sin(roll) * cos(pitch) # due to roll
|
+ 40 * me.steering * me.wow # due to ground steering
|
||||||
+ 40 * steering * wow # due to ground steering
|
+ 10 * me.slip * (1 - me.wow) # due to sideslip (in air)
|
||||||
+ 10 * slip * (1 - wow) # due to sideslip (in air)
|
}
|
||||||
);
|
|
||||||
me.pitch_axis.apply( # pitch ...
|
me.calc_pitch = func { # pitch
|
||||||
10 * sin(roll) * sin(roll) # due to roll
|
10 * sin(me.roll) * sin(me.roll) # due to roll
|
||||||
+ 30 * (1 / (1 + math.exp(2 - az)) # due to G load
|
+ 30 * (1 / (1 + math.exp(2 - me.az)) # due to G load
|
||||||
- 0.119202922) # [move to origin; 1/(1+exp(2)) ]
|
- 0.119202922) # [move to origin; 1/(1+exp(2)) ]
|
||||||
);
|
}
|
||||||
me.roll_axis.apply( # roll ...
|
|
||||||
0.0 * sin(roll) * cos(pitch) # due to roll (none)
|
me.calc_roll = nil;
|
||||||
);
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
ViewManager.default_helicopter = func {
|
||||||
|
me.calc = func {
|
||||||
|
me.lowspeed = 1 - normatan(me.speedN.getValue() / 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
me.calc_heading = func { # view heading due to
|
||||||
|
-50 * npow(sin(me.roll) * cos(me.pitch), 2) # roll
|
||||||
|
}
|
||||||
|
|
||||||
|
me.calc_pitch = func { # view pitch due to
|
||||||
|
(me.pitch < 0 ? -35 : -40) * sin(me.pitch) * me.lowspeed # pitch
|
||||||
|
+ 15 * sin(me.roll) * sin(me.roll) # roll
|
||||||
|
}
|
||||||
|
|
||||||
|
me.calc_roll = func { # view roll due to
|
||||||
|
-15 * sin(me.roll) * cos(me.pitch) * me.lowspeed # roll
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -201,17 +240,6 @@ main_loop = func(id) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Register new, aircraft specific manager. (Needs to offer the
|
|
||||||
# same methods, of course.)
|
|
||||||
#
|
|
||||||
register = func(mgr) {
|
|
||||||
view_manager = mgr;
|
|
||||||
var p = "/sim/view/dynamic/enabled";
|
|
||||||
setprop(p, getprop(p)); # fire listener
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var original_resetView = nil;
|
var original_resetView = nil;
|
||||||
var panel_visibilityN = nil;
|
var panel_visibilityN = nil;
|
||||||
var dynamic_view = nil;
|
var dynamic_view = nil;
|
||||||
|
@ -265,22 +293,7 @@ setlistener("/sim/signals/fdm-initialized", func {
|
||||||
mouse_button = cmdarg().getBoolValue();
|
mouse_button = cmdarg().getBoolValue();
|
||||||
}, 1));
|
}, 1));
|
||||||
|
|
||||||
var config = props.Node.new({
|
view_manager = ViewManager.new();
|
||||||
"heading-due-to" : {
|
|
||||||
"roll" : -15,
|
|
||||||
"ground-steering" : 40,
|
|
||||||
"side-slip" : 0.4,
|
|
||||||
},
|
|
||||||
"pitch-due-to" : {
|
|
||||||
"roll" : 10,
|
|
||||||
"g-load" : 30,
|
|
||||||
},
|
|
||||||
"roll-due-to" : {
|
|
||||||
"roll" : 0,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
props.copy(props.globals.getNode("/sim/view/dynamic", 1), config);
|
|
||||||
view_manager = ViewManager.new(config);
|
|
||||||
|
|
||||||
original_resetView = view.resetView;
|
original_resetView = view.resetView;
|
||||||
view.resetView = func {
|
view.resetView = func {
|
||||||
|
|
Loading…
Add table
Reference in a new issue