diff --git a/Aircraft/Generic/WalkView/walkview.nas b/Aircraft/Generic/WalkView/walkview.nas index c44467216..0824dc229 100644 --- a/Aircraft/Generic/WalkView/walkview.nas +++ b/Aircraft/Generic/WalkView/walkview.nas @@ -11,7 +11,7 @@ # Global API. Automatically selects the right walker for the current view. -# NOTE: Coordinates are always 3 component lists: [x, y, z]. +# NOTE: Coordinates are always 3 component lists: [x, y, z] in meters. # The coordinate system is the same as the main 3d model one. # X - back, Y - right and Z - up. @@ -58,10 +58,17 @@ var active_walker = func { # Class for a moving view. # # CONSTRUCTOR: -# walker.new(, ); +# walker.new(, , ); # # view name ... The name of the view : string # constraints ... The movement constraints : constraint hash +# Determines where the view can go. +# managers ... Optional list of custom managers. A manager is a +# a hash that contains an update function of the type +# func(walker instance). The update function +# of each manager will be called as the last part of +# each walker update. Intended for controlling a +# a 3d model or similar. # # METHODS: # active() : bool @@ -82,7 +89,7 @@ var active_walker = func { # get_eye_height() : int (meter) # # set_constraints(constraints) -# get_constraints() : contraint hash +# get_constraints() : constraint hash # # EXAMPLE: # var constraint = @@ -95,10 +102,11 @@ var active_walker = func { # walk view should not have any other view manager. # var walker = { - new : func (view_name, constraints = nil) { + new : func (view_name, constraints = nil, managers = nil) { var obj = { parents : [walker] }; obj.view = view.views[view.indexof(view_name)]; obj.constraints = constraints; + obj.managers = managers; obj.position = [ obj.view.getNode("config/z-offset-m").getValue(), obj.view.getNode("config/x-offset-m").getValue(), @@ -108,7 +116,6 @@ var walker = { obj.view.getNode("config/heading-offset-deg").getValue(); obj.speed_fwd = 0.0; obj.speed_side = 0.0; - obj.id = 0; obj.isactive = 0; obj.eye_height = 1.60; obj.goal_height = obj.position[2] + obj.eye_height; @@ -135,7 +142,7 @@ var walker = { me.position[2] = pos[2]; }, get_pos : func { - return me.position; + return [me.position[0], me.position[1], me.position[2]]; }, set_eye_height : func (h) { me.eye_height = h; @@ -157,13 +164,11 @@ var walker = { me.last_time = getprop("/sim/time/elapsed-sec") - 0.0001; me.update(); me.position[2] = me.goal_height; - settimer(func { me._loop_(me.id); }, 0.0); }, stop : func { me.isactive = 0; - me.id += 1; }, - # Internals. + # The update function is called by the view manager when the view is active. update : func { var t = getprop("/sim/time/elapsed-sec"); var dt = t - me.last_time; @@ -173,11 +178,11 @@ var walker = { me.heading = cur.getNode("heading-offset-deg").getValue(); me.position[0] -= - me.speed_fwd * dt * math.cos(me.heading * RAD) + - me.speed_side * dt * math.sin(me.heading * RAD); + me.speed_fwd * dt * math.cos(me.heading * TO_RAD) + + me.speed_side * dt * math.sin(me.heading * TO_RAD); me.position[1] -= - me.speed_fwd * dt * math.sin(me.heading * RAD) - - me.speed_side * dt * math.cos(me.heading * RAD); + me.speed_fwd * dt * math.sin(me.heading * TO_RAD) - + me.speed_side * dt * math.cos(me.heading * TO_RAD); var cur_height = me.position[2]; if (me.constraints != nil) { @@ -198,19 +203,23 @@ var walker = { cur.getNode("x-offset-m").setValue(me.position[1]); cur.getNode("y-offset-m").setValue(me.position[2]); + if (me.managers != nil) { + foreach(var m; me.managers) { + m.update(me); + } + } + me.last_time = t; + return 0.0; }, - _loop_ : func (id) { - if (me.id != id) return; - me.update(); - settimer(func { me._loop_(id); }, 0.0); - } }; ############################################################################### -# Constraint classes. +# Constraint classes. Determines where the view can walk. -# Assumes that the constraints are convex. +# The union of two constraints. +# c1, c2 - the constraints : constraint +# NOTE: Assumes that the constraints are convex. var unionConstraint = { new : func (c1, c2) { var obj = { parents : [unionConstraint] }; @@ -236,6 +245,7 @@ var unionConstraint = { }; # Build a unionConstraint hierarchy from a list of constraints. +# cs - list of constraints : [constraint] var makeUnionConstraint = func (cs) { if (size(cs) < 2) return cs[0]; @@ -247,8 +257,8 @@ var makeUnionConstraint = func (cs) { } # Mostly aligned plane sloping along the X axis. -# minp - the X,Y minimum point -# maxp - the X,Y maximum point +# minp - the X,Y minimum point : position (meter) +# maxp - the X,Y maximum point : position (meter) var slopingYAlignedPlane = { new : func (minp, maxp) { var obj = { parents : [slopingYAlignedPlane] }; @@ -270,8 +280,8 @@ var slopingYAlignedPlane = { # Action constraint # Triggers an action when entering or exiting the constraint. -# contraint - the area in question. -# on_enter - function that is called when the walker enters the area. +# constraint - the area in question : constraint +# on_enter() - function that is called when the walker enters the area. # on_exit(x, y) - function that is called when the walker leaves the area. # x and y are <0, 0 or >0 depending on in which direction(s) # the walker left the constraint. @@ -305,11 +315,49 @@ var actionConstraint = { } }; +############################################################################### +# Manager classes. + +# JSBSim pointmass manager. +# Moves a pointmass representing the crew member together with the view. +# CONSTRUCTOR: +# JSBSimPointmass.new(); +# +# pointmass index ... The index of the pointmass : int +# offsets ... [x, y ,z] position in meter of the origin of the +# JSBSim structural frame in the 3d model frame. +# +# NOTE: Only supports aligned frames (yet). +# +var JSBSimPointmass = { + new : func (index, offsets = nil) { + var base = props.globals.getNode("fdm/jsbsim/inertia"); + var prefix = "pointmass-location-"; + var postfix = "-inches[" ~ index ~"]"; + var obj = { parents : [JSBSimPointmass] }; + obj.pos_ft = + [ + base.getNode(prefix ~ "X" ~ postfix), + base.getNode(prefix ~ "Y" ~ postfix), + base.getNode(prefix ~ "Z" ~ postfix) + ]; + obj.offset = (offsets == nil) ? [0.0, 0.0, 0.0] : offsets; + return obj; + }, + update : func (walker) { + var pos = walker.get_pos(); + pos[2] += walker.get_eye_height()/2; + forindex (var i; pos) { + me.pos_ft[i].setValue((pos[i] - me.offset[i])*M2FT*12); + } + } +}; + ############################################################################### # Module implementation below -var RAD = math.pi/180; -var DEG = 180/math.pi; +var TO_RAD = math.pi/180; +var TO_DEG = 180/math.pi; var walkers = {};