1
0
Fork 0

Updated WalkView:

- Added support for additional manager objects, e.g.
  for animating a 3d model or move a JSBSim pointmass.
- Improved the documentation.
- Some bugs removed.
This commit is contained in:
Anders Gidenstam 2010-08-16 22:55:58 +02:00
parent 8fd716f2ca
commit 049d98ad8e

View file

@ -11,7 +11,7 @@
# Global API. Automatically selects the right walker for the current view. # 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. # The coordinate system is the same as the main 3d model one.
# X - back, Y - right and Z - up. # X - back, Y - right and Z - up.
@ -58,10 +58,17 @@ var active_walker = func {
# Class for a moving view. # Class for a moving view.
# #
# CONSTRUCTOR: # CONSTRUCTOR:
# walker.new(<view name>, <constraints>); # walker.new(<view name>, <constraints>, <managers>);
# #
# view name ... The name of the view : string # view name ... The name of the view : string
# constraints ... The movement constraints : constraint hash # 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: # METHODS:
# active() : bool # active() : bool
@ -82,7 +89,7 @@ var active_walker = func {
# get_eye_height() : int (meter) # get_eye_height() : int (meter)
# #
# set_constraints(constraints) # set_constraints(constraints)
# get_constraints() : contraint hash # get_constraints() : constraint hash
# #
# EXAMPLE: # EXAMPLE:
# var constraint = # var constraint =
@ -95,10 +102,11 @@ var active_walker = func {
# walk view should not have any other view manager. # walk view should not have any other view manager.
# #
var walker = { var walker = {
new : func (view_name, constraints = nil) { new : func (view_name, constraints = nil, managers = nil) {
var obj = { parents : [walker] }; var obj = { parents : [walker] };
obj.view = view.views[view.indexof(view_name)]; obj.view = view.views[view.indexof(view_name)];
obj.constraints = constraints; obj.constraints = constraints;
obj.managers = managers;
obj.position = [ obj.position = [
obj.view.getNode("config/z-offset-m").getValue(), obj.view.getNode("config/z-offset-m").getValue(),
obj.view.getNode("config/x-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.view.getNode("config/heading-offset-deg").getValue();
obj.speed_fwd = 0.0; obj.speed_fwd = 0.0;
obj.speed_side = 0.0; obj.speed_side = 0.0;
obj.id = 0;
obj.isactive = 0; obj.isactive = 0;
obj.eye_height = 1.60; obj.eye_height = 1.60;
obj.goal_height = obj.position[2] + obj.eye_height; obj.goal_height = obj.position[2] + obj.eye_height;
@ -135,7 +142,7 @@ var walker = {
me.position[2] = pos[2]; me.position[2] = pos[2];
}, },
get_pos : func { get_pos : func {
return me.position; return [me.position[0], me.position[1], me.position[2]];
}, },
set_eye_height : func (h) { set_eye_height : func (h) {
me.eye_height = h; me.eye_height = h;
@ -157,13 +164,11 @@ var walker = {
me.last_time = getprop("/sim/time/elapsed-sec") - 0.0001; me.last_time = getprop("/sim/time/elapsed-sec") - 0.0001;
me.update(); me.update();
me.position[2] = me.goal_height; me.position[2] = me.goal_height;
settimer(func { me._loop_(me.id); }, 0.0);
}, },
stop : func { stop : func {
me.isactive = 0; me.isactive = 0;
me.id += 1;
}, },
# Internals. # The update function is called by the view manager when the view is active.
update : func { update : func {
var t = getprop("/sim/time/elapsed-sec"); var t = getprop("/sim/time/elapsed-sec");
var dt = t - me.last_time; var dt = t - me.last_time;
@ -173,11 +178,11 @@ var walker = {
me.heading = cur.getNode("heading-offset-deg").getValue(); me.heading = cur.getNode("heading-offset-deg").getValue();
me.position[0] -= me.position[0] -=
me.speed_fwd * dt * math.cos(me.heading * RAD) + me.speed_fwd * dt * math.cos(me.heading * TO_RAD) +
me.speed_side * dt * math.sin(me.heading * RAD); me.speed_side * dt * math.sin(me.heading * TO_RAD);
me.position[1] -= me.position[1] -=
me.speed_fwd * dt * math.sin(me.heading * RAD) - me.speed_fwd * dt * math.sin(me.heading * TO_RAD) -
me.speed_side * dt * math.cos(me.heading * RAD); me.speed_side * dt * math.cos(me.heading * TO_RAD);
var cur_height = me.position[2]; var cur_height = me.position[2];
if (me.constraints != nil) { if (me.constraints != nil) {
@ -198,19 +203,23 @@ var walker = {
cur.getNode("x-offset-m").setValue(me.position[1]); cur.getNode("x-offset-m").setValue(me.position[1]);
cur.getNode("y-offset-m").setValue(me.position[2]); cur.getNode("y-offset-m").setValue(me.position[2]);
me.last_time = t; if (me.managers != nil) {
}, foreach(var m; me.managers) {
_loop_ : func (id) { m.update(me);
if (me.id != id) return;
me.update();
settimer(func { me._loop_(id); }, 0.0);
} }
}
me.last_time = t;
return 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 = { var unionConstraint = {
new : func (c1, c2) { new : func (c1, c2) {
var obj = { parents : [unionConstraint] }; var obj = { parents : [unionConstraint] };
@ -236,6 +245,7 @@ var unionConstraint = {
}; };
# Build a unionConstraint hierarchy from a list of constraints. # Build a unionConstraint hierarchy from a list of constraints.
# cs - list of constraints : [constraint]
var makeUnionConstraint = func (cs) { var makeUnionConstraint = func (cs) {
if (size(cs) < 2) return cs[0]; if (size(cs) < 2) return cs[0];
@ -247,8 +257,8 @@ var makeUnionConstraint = func (cs) {
} }
# Mostly aligned plane sloping along the X axis. # Mostly aligned plane sloping along the X axis.
# minp - the X,Y minimum point # minp - the X,Y minimum point : position (meter)
# maxp - the X,Y maximum point # maxp - the X,Y maximum point : position (meter)
var slopingYAlignedPlane = { var slopingYAlignedPlane = {
new : func (minp, maxp) { new : func (minp, maxp) {
var obj = { parents : [slopingYAlignedPlane] }; var obj = { parents : [slopingYAlignedPlane] };
@ -270,8 +280,8 @@ var slopingYAlignedPlane = {
# Action constraint # Action constraint
# Triggers an action when entering or exiting the constraint. # Triggers an action when entering or exiting the constraint.
# contraint - the area in question. # constraint - the area in question : constraint
# on_enter - function that is called when the walker enters the area. # 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. # 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) # x and y are <0, 0 or >0 depending on in which direction(s)
# the walker left the constraint. # 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>);
#
# 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 # Module implementation below
var RAD = math.pi/180; var TO_RAD = math.pi/180;
var DEG = 180/math.pi; var TO_DEG = 180/math.pi;
var walkers = {}; var walkers = {};