]> git.mxchange.org Git - simgear.git/commitdiff
Jim Wilson:
authorehofman <ehofman>
Sun, 8 Jun 2003 13:19:34 +0000 (13:19 +0000)
committerehofman <ehofman>
Sun, 8 Jun 2003 13:19:34 +0000 (13:19 +0000)
1. Added support for defining arbitrary rotation axes using (x1,y1,z1), (x2,y2,z2).  The center is calculated automatically (midpoint on line) or you may specify an alternate "center" using the current scheme.  This makes it about  100 times easier to animate flaps, ailerons, etc.

2. Added support for plib's ssgTexTrans.  This will allow more sophisticated 3D instrument features by allowing the texture mapping itself to be animated. Included function for "texrotate" and "textranslate".  They configure the same as the geometry, except the arbitrary axis definition is not necessary (textures are flat).

simgear/scene/model/animation.cxx
simgear/scene/model/animation.hxx
simgear/scene/model/model.cxx

index a258a1c726d250db8f5e7497f1c5c776afeb5762..f9ebc188e81c690ef0325f7490d4f62eb59063cf 100644 (file)
@@ -1,4 +1,4 @@
-// animation.hxx - classes to manage model animation.
+// animation.cxx - classes to manage model animation.
 // Written by David Megginson, started 2002.
 //
 // This file is in the Public Domain, and comes with no warranty.
@@ -221,12 +221,34 @@ SGSpinAnimation::SGSpinAnimation( SGPropertyNode *prop_root,
     _position_deg(props->getDoubleValue("starting-position-deg", 0)),
     _last_time_sec( sim_time_sec )
 {
-    _center[0] = props->getFloatValue("center/x-m", 0);
-    _center[1] = props->getFloatValue("center/y-m", 0);
-    _center[2] = props->getFloatValue("center/z-m", 0);
-    _axis[0] = props->getFloatValue("axis/x", 0);
-    _axis[1] = props->getFloatValue("axis/y", 0);
-    _axis[2] = props->getFloatValue("axis/z", 0);
+    _center[0] = 0;
+    _center[1] = 0;
+    _center[2] = 0;
+    if (props->hasValue("axis/x1-m")) {
+        double x1,y1,z1,x2,y2,z2;
+        x1 = props->getFloatValue("axis/x1-m");
+        y1 = props->getFloatValue("axis/y1-m");
+        z1 = props->getFloatValue("axis/z1-m");
+        x2 = props->getFloatValue("axis/x2-m");
+        y2 = props->getFloatValue("axis/y2-m");
+        z2 = props->getFloatValue("axis/z2-m");
+        _center[0] = (x1+x2)/2;
+        _center[1]= (y1+y2)/2;
+        _center[2] = (z1+z2)/2;
+        float vector_length = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1));
+        _axis[0] = (x2-x1)/vector_length;
+        _axis[1] = (y2-y1)/vector_length;
+        _axis[2] = (z2-z1)/vector_length;
+    } else {
+       _axis[0] = props->getFloatValue("axis/x", 0);
+       _axis[1] = props->getFloatValue("axis/y", 0);
+       _axis[2] = props->getFloatValue("axis/z", 0);
+    }
+    if (props->hasValue("center/x-m")) {
+       _center[0] = props->getFloatValue("center/x-m", 0);
+       _center[1] = props->getFloatValue("center/y-m", 0);
+       _center[2] = props->getFloatValue("center/z-m", 0);
+    }
     sgNormalizeVec3(_axis);
 }
 
@@ -299,13 +321,35 @@ SGRotateAnimation::SGRotateAnimation( SGPropertyNode *prop_root,
       _max_deg(props->getDoubleValue("max-deg")),
       _position_deg(props->getDoubleValue("starting-position-deg", 0))
 {
-  _center[0] = props->getFloatValue("center/x-m", 0);
-  _center[1] = props->getFloatValue("center/y-m", 0);
-  _center[2] = props->getFloatValue("center/z-m", 0);
-  _axis[0] = props->getFloatValue("axis/x", 0);
-  _axis[1] = props->getFloatValue("axis/y", 0);
-  _axis[2] = props->getFloatValue("axis/z", 0);
-  sgNormalizeVec3(_axis);
+    _center[0] = 0;
+    _center[1] = 0;
+    _center[2] = 0;
+    if (props->hasValue("axis/x1-m")) {
+        double x1,y1,z1,x2,y2,z2;
+        x1 = props->getFloatValue("axis/x1-m");
+        y1 = props->getFloatValue("axis/y1-m");
+        z1 = props->getFloatValue("axis/z1-m");
+        x2 = props->getFloatValue("axis/x2-m");
+        y2 = props->getFloatValue("axis/y2-m");
+        z2 = props->getFloatValue("axis/z2-m");
+        _center[0] = (x1+x2)/2;
+        _center[1]= (y1+y2)/2;
+        _center[2] = (z1+z2)/2;
+        float vector_length = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1));
+        _axis[0] = (x2-x1)/vector_length;
+        _axis[1] = (y2-y1)/vector_length;
+        _axis[2] = (z2-z1)/vector_length;
+    } else {
+       _axis[0] = props->getFloatValue("axis/x", 0);
+       _axis[1] = props->getFloatValue("axis/y", 0);
+       _axis[2] = props->getFloatValue("axis/z", 0);
+    }
+    if (props->hasValue("center/x-m")) {
+       _center[0] = props->getFloatValue("center/x-m", 0);
+       _center[1] = props->getFloatValue("center/y-m", 0);
+       _center[2] = props->getFloatValue("center/z-m", 0);
+    }
+    sgNormalizeVec3(_axis);
 }
 
 SGRotateAnimation::~SGRotateAnimation ()
@@ -376,4 +420,97 @@ SGTranslateAnimation::update()
 }
 
 
+////////////////////////////////////////////////////////////////////////
+// Implementation of SGTexRotateAnimation
+////////////////////////////////////////////////////////////////////////
+
+SGTexRotateAnimation::SGTexRotateAnimation( SGPropertyNode *prop_root,
+                                  SGPropertyNode_ptr props )
+    : SGAnimation(props, new ssgTexTrans),
+      _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
+      _offset_deg(props->getDoubleValue("offset-deg", 0.0)),
+      _factor(props->getDoubleValue("factor", 1.0)),
+      _table(read_interpolation_table(props)),
+      _has_min(props->hasValue("min-deg")),
+      _min_deg(props->getDoubleValue("min-deg")),
+      _has_max(props->hasValue("max-deg")),
+      _max_deg(props->getDoubleValue("max-deg")),
+      _position_deg(props->getDoubleValue("starting-position-deg", 0))
+{
+  _center[0] = props->getFloatValue("center/x-m", 0);
+  _center[1] = props->getFloatValue("center/y-m", 0);
+  _center[2] = props->getFloatValue("center/z-m", 0);
+  _axis[0] = props->getFloatValue("axis/x", 0);
+  _axis[1] = props->getFloatValue("axis/y", 0);
+  _axis[2] = props->getFloatValue("axis/z", 0);
+  sgNormalizeVec3(_axis);
+}
+
+SGTexRotateAnimation::~SGTexRotateAnimation ()
+{
+  delete _table;
+}
+
+void
+SGTexRotateAnimation::update()
+{
+  if (_table == 0) {
+   _position_deg = _prop->getDoubleValue() * _factor + _offset_deg;
+   if (_has_min && _position_deg < _min_deg)
+     _position_deg = _min_deg;
+   if (_has_max && _position_deg > _max_deg)
+     _position_deg = _max_deg;
+  } else {
+    _position_deg = _table->interpolate(_prop->getDoubleValue());
+  }
+  set_rotation(_matrix, _position_deg, _center, _axis);
+  ((ssgTexTrans *)_branch)->setTransform(_matrix);
+}
+
+
+////////////////////////////////////////////////////////////////////////
+// Implementation of SGTexTranslateAnimation
+////////////////////////////////////////////////////////////////////////
+
+SGTexTranslateAnimation::SGTexTranslateAnimation( SGPropertyNode *prop_root,
+                                        SGPropertyNode_ptr props )
+  : SGAnimation(props, new ssgTexTrans),
+      _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
+    _offset_m(props->getDoubleValue("offset-m", 0.0)),
+    _factor(props->getDoubleValue("factor", 1.0)),
+    _table(read_interpolation_table(props)),
+    _has_min(props->hasValue("min-m")),
+    _min_m(props->getDoubleValue("min-m")),
+    _has_max(props->hasValue("max-m")),
+    _max_m(props->getDoubleValue("max-m")),
+    _position_m(props->getDoubleValue("starting-position-m", 0))
+{
+  _axis[0] = props->getFloatValue("axis/x", 0);
+  _axis[1] = props->getFloatValue("axis/y", 0);
+  _axis[2] = props->getFloatValue("axis/z", 0);
+  sgNormalizeVec3(_axis);
+}
+
+SGTexTranslateAnimation::~SGTexTranslateAnimation ()
+{
+  delete _table;
+}
+
+void
+SGTexTranslateAnimation::update()
+{
+  if (_table == 0) {
+    _position_m = (_prop->getDoubleValue() + _offset_m) * _factor;
+    if (_has_min && _position_m < _min_m)
+      _position_m = _min_m;
+    if (_has_max && _position_m > _max_m)
+      _position_m = _max_m;
+  } else {
+    _position_m = _table->interpolate(_prop->getDoubleValue());
+  }
+  set_translation(_matrix, _position_m, _axis);
+  ((ssgTexTrans *)_branch)->setTransform(_matrix);
+}
+
+
 // end of animation.cxx
index 4bbdf829468c1551b188f06883b889f66cff2bbd..f365ec970fc21965a48ee03bdb2ec384045ea60b 100644 (file)
@@ -220,5 +220,55 @@ private:
   sgVec3 _axis;
 };
 
+/**
+ * Animation to rotate texture mappings around a center point.
+ *
+ * This animation rotates to a specific position.
+ */
+class SGTexRotateAnimation : public SGAnimation
+{
+public:
+  SGTexRotateAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props );
+  virtual ~SGTexRotateAnimation ();
+  virtual void update();
+private:
+  SGPropertyNode_ptr _prop;
+  double _offset_deg;
+  double _factor;
+  SGInterpTable * _table;
+  bool _has_min;
+  double _min_deg;
+  bool _has_max;
+  double _max_deg;
+  double _position_deg;
+  sgMat4 _matrix;
+  sgVec3 _center;
+  sgVec3 _axis;
+};
+
+
+/**
+ * Animation to slide texture mappings along an axis.
+ */
+class SGTexTranslateAnimation : public SGAnimation
+{
+public:
+  SGTexTranslateAnimation( SGPropertyNode *prop_root,
+                      SGPropertyNode_ptr props );
+  virtual ~SGTexTranslateAnimation ();
+  virtual void update();
+private:
+  SGPropertyNode_ptr _prop;
+  double _offset_m;
+  double _factor;
+  SGInterpTable * _table;
+  bool _has_min;
+  double _min_m;
+  bool _has_max;
+  double _max_m;
+  double _position_m;
+  sgMat4 _matrix;
+  sgVec3 _axis;
+};
 
 #endif // _SG_ANIMATION_HXX
index 425d558d99f0e2832c50e7d9781856dace2be517..1ece4c5b726792e8a15127b454a4dc13ebf61234 100644 (file)
@@ -121,6 +121,10 @@ sgMakeAnimation( ssgBranch * model,
     animation = new SGRotateAnimation(prop_root, node);
   } else if (!strcmp("translate", type)) {
     animation = new SGTranslateAnimation(prop_root, node);
+  } else if (!strcmp("texrotate", type)) {
+    animation = new SGTexRotateAnimation(prop_root, node);
+  } else if (!strcmp("textranslate", type)) {
+    animation = new SGTexTranslateAnimation(prop_root, node);
   } else {
     animation = new SGNullAnimation(node);
     SG_LOG(SG_INPUT, SG_WARN, "Unknown animation type " << type);