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.
# 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(<view name>, <constraints>);
# walker.new(<view name>, <constraints>, <managers>);
#
# 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>);
#
# 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 = {};