From 03e25d91cd89d8d4a5f68cd5a6210f0743646e39 Mon Sep 17 00:00:00 2001
From: Anders Gidenstam <anders@gidenstam.org>
Date: Wed, 3 Nov 2010 20:35:06 +0100
Subject: [PATCH] Updated WalkView: Added a "class" for conditional
 constraints.

---
 Aircraft/Generic/WalkView/walkview.nas | 49 +++++++++++++++++++++-----
 1 file changed, 41 insertions(+), 8 deletions(-)

diff --git a/Aircraft/Generic/WalkView/walkview.nas b/Aircraft/Generic/WalkView/walkview.nas
index b7bad57c1..59e256437 100644
--- a/Aircraft/Generic/WalkView/walkview.nas
+++ b/Aircraft/Generic/WalkView/walkview.nas
@@ -107,6 +107,7 @@ var active_walker = func {
 var Walker = {
     new : func (view_name, constraints = nil, managers = nil) {
         var obj = { parents : [Walker] };
+        obj.view_name   = view_name;
         obj.view        = view.views[view.indexof(view_name)];
         obj.constraints = constraints;
         obj.managers    = managers;
@@ -180,17 +181,26 @@ var Walker = {
         var cur = props.globals.getNode("/sim/current-view");
         me.heading = cur.getNode("heading-offset-deg").getValue();
 
-        me.position[0] -=
-            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 * TO_RAD) -
-            me.speed_side * dt * math.cos(me.heading * TO_RAD);
+        var new_pos =
+            [me.position[0] -
+             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 * TO_RAD) -
+             me.speed_side * dt * math.cos(me.heading * TO_RAD),
+             me.position[2]];
 
         var cur_height = me.position[2];
         if (me.constraints != nil) {
-            me.position     = me.constraints.constrain(me.position);
-            me.goal_height  = me.position[2] + me.eye_height;
+            new_pos = me.constraints.constrain(new_pos);
+            if (new_pos == NO_POS) {
+                printlog("warn",
+                         "WalkView: Constraint for " ~ me.view_name ~
+                         " returned NO_POS.");
+            } else {
+                me.position     = new_pos;
+                me.goal_height  = me.position[2] + me.eye_height;
+            }
         }
         # Change the view height smoothly
         if (math.abs(me.goal_height - cur_height) > 2.0 * dt) {
@@ -399,6 +409,27 @@ var ActionConstraint = {
     }
 };
 
+# Conditional constraint
+#   The area is only available when the predicate function returns true.
+#   constraint      - the area in question : constraint
+#   predicate()     - boolean function that determines if the area is available.
+var ConditionalConstraint = {
+    new : func (constraint, predicate = nil) {
+        var obj = { parents : [ConditionalConstraint] };
+        obj.constraint = constraint;
+        obj.predicate  = predicate;
+        return obj;
+    },
+    constrain : func (pos) {
+        if (me.predicate == nil or me.predicate()) {
+            return me.constraint.constrain(pos);
+        } else {
+            return NO_POS;
+        }
+    }
+};
+
+
 ###############################################################################
 # Manager classes.
 
@@ -443,6 +474,8 @@ var JSBSimPointmass = {
 var TO_RAD = math.pi/180;
 var TO_DEG = 180/math.pi;
 
+var NO_POS = [-9999.0, -9999.0, -9999.0];
+
 var walkers = {};
 
 var closerXY = func (pos, p1, p2) {