]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/model/animation.cxx
Work around apparent OSG 3.2.0 normal binding bug.
[simgear.git] / simgear / scene / model / animation.cxx
index edc9e16c83b9cfb61aa98d140399eaa397cef662..30cab2e3d244b81efd720a9bbe0e736648200fac 100644 (file)
@@ -57,6 +57,7 @@
 #include "SGScaleTransform.hxx"
 #include "SGInteractionAnimation.hxx"
 #include "SGPickAnimation.hxx"
+#include "SGTrackToAnimation.hxx"
 
 #include "ConditionNode.hxx"
 
@@ -65,7 +66,6 @@ using OpenThreads::ReentrantMutex;
 using OpenThreads::ScopedLock;
 
 using namespace simgear;
-\f
 ////////////////////////////////////////////////////////////////////////
 // Static utility functions.
 ////////////////////////////////////////////////////////////////////////
@@ -206,7 +206,6 @@ read_value(const SGPropertyNode* configNode, SGPropertyNode* modelRoot,
   return 0;
 }
 
-\f
 ////////////////////////////////////////////////////////////////////////
 // Animation installer
 ////////////////////////////////////////////////////////////////////////
@@ -345,7 +344,7 @@ SGAnimation::~SGAnimation()
   if (!_found)
   {
       std::list<std::string>::const_iterator i;
-      string info;
+      std::string info;
       for (i = _objectNames.begin(); i != _objectNames.end(); ++i)
       {
           if (!info.empty())
@@ -366,7 +365,7 @@ bool
 SGAnimation::animate(osg::Node* node, const SGPropertyNode* configNode,
                      SGPropertyNode* modelRoot,
                      const osgDB::Options* options,
-                     const string &path, int i)
+                     const std::string &path, int i)
 {
   std::string type = configNode->getStringValue("type", "none");
   if (type == "alpha-test") {
@@ -396,6 +395,12 @@ SGAnimation::animate(osg::Node* node, const SGPropertyNode* configNode,
   } else if (type == "pick") {
     SGPickAnimation animInst(configNode, modelRoot);
     animInst.apply(node);
+  } else if (type == "knob") {
+    SGKnobAnimation animInst(configNode, modelRoot);
+    animInst.apply(node);
+  } else if (type == "slider") {
+    SGSliderAnimation animInst(configNode, modelRoot);
+    animInst.apply(node);
   } else if (type == "range") {
     SGRangeAnimation animInst(configNode, modelRoot);
     animInst.apply(node);
@@ -418,6 +423,9 @@ SGAnimation::animate(osg::Node* node, const SGPropertyNode* configNode,
   } else if (type == "timed") {
     SGTimedAnimation animInst(configNode, modelRoot);
     animInst.apply(node);
+  } else if (type == "locked-track") {
+    SGTrackToAnimation animInst(node, configNode, modelRoot);
+    animInst.apply(node);
   } else if (type == "translate") {
     SGTranslateAnimation animInst(configNode, modelRoot);
     animInst.apply(node);
@@ -524,6 +532,65 @@ SGAnimation::installInGroup(const std::string& name, osg::Group& group,
   }
 }
 
+//------------------------------------------------------------------------------
+SGVec3d SGAnimation::readVec3( const std::string& name,
+                               const std::string& suffix,
+                               const SGVec3d& def ) const
+{
+  SGVec3d vec;
+  vec[0] = _configNode->getDoubleValue(name + "/x" + suffix, def.x());
+  vec[1] = _configNode->getDoubleValue(name + "/y" + suffix, def.y());
+  vec[2] = _configNode->getDoubleValue(name + "/z" + suffix, def.z());
+  return vec;
+}
+
+//------------------------------------------------------------------------------
+// factored out to share with SGKnobAnimation
+void SGAnimation::readRotationCenterAndAxis( SGVec3d& center,
+                                             SGVec3d& axis ) const
+{
+  center = SGVec3d::zeros();
+  if( _configNode->hasValue("axis/x1-m") )
+  {
+    SGVec3d v1 = readVec3("axis", "1-m"), // axis/[xyz]1-m
+            v2 = readVec3("axis", "2-m"); // axis/[xyz]2-m
+    center = 0.5*(v1+v2);
+    axis = v2 - v1;
+  }
+  else
+  {
+    axis = readVec3("axis");
+  }
+  if( 8 * SGLimitsd::min() < norm(axis) )
+    axis = normalize(axis);
+
+  center = readVec3("center", "-m", center);
+}
+
+//------------------------------------------------------------------------------
+SGExpressiond* SGAnimation::readOffsetValue(const char* tag_name) const
+{
+  const SGPropertyNode* node = _configNode->getChild(tag_name);
+  if( !node )
+    return 0;
+
+  SGExpressiond_ref expression;
+  if( !node->nChildren() )
+    expression = new SGConstExpression<double>(node->getDoubleValue());
+  else
+    expression = SGReadDoubleExpression(_modelRoot, node->getChild(0));
+
+  if( !expression )
+    return 0;
+
+  expression = expression->simplify();
+
+  if( expression->isConst() && expression->getValue() == 0 )
+    return 0;
+
+  return expression.release();
+}
+
 void
 SGAnimation::removeMode(osg::Node& node, osg::StateAttribute::GLMode mode)
 {
@@ -578,7 +645,7 @@ SGAnimation::getCondition() const
 }
 
 
-\f
+
 ////////////////////////////////////////////////////////////////////////
 // Implementation of null animation
 ////////////////////////////////////////////////////////////////////////
@@ -600,7 +667,7 @@ SGGroupAnimation::createAnimationGroup(osg::Group& parent)
   return group;
 }
 
-\f
+
 ////////////////////////////////////////////////////////////////////////
 // Implementation of translate animation
 ////////////////////////////////////////////////////////////////////////
@@ -642,22 +709,7 @@ SGTranslateAnimation::SGTranslateAnimation(const SGPropertyNode* configNode,
   else
     _initialValue = 0;
 
-  if (configNode->hasValue("axis/x1-m")) {
-    SGVec3d v1, v2;
-    v1[0] = configNode->getDoubleValue("axis/x1-m", 0);
-    v1[1] = configNode->getDoubleValue("axis/y1-m", 0);
-    v1[2] = configNode->getDoubleValue("axis/z1-m", 0);
-    v2[0] = configNode->getDoubleValue("axis/x2-m", 0);
-    v2[1] = configNode->getDoubleValue("axis/y2-m", 0);
-    v2[2] = configNode->getDoubleValue("axis/z2-m", 0);
-    _axis = v2 - v1;
-  } else {
-    _axis[0] = configNode->getDoubleValue("axis/x", 0);
-    _axis[1] = configNode->getDoubleValue("axis/y", 0);
-    _axis[2] = configNode->getDoubleValue("axis/z", 0);
-  }
-  if (8*SGLimitsd::min() < norm(_axis))
-    _axis = normalize(_axis);
+  _axis = readTranslateAxis(configNode);
 }
 
 osg::Group*
@@ -675,7 +727,7 @@ SGTranslateAnimation::createAnimationGroup(osg::Group& parent)
   return transform;
 }
 
-\f
+
 ////////////////////////////////////////////////////////////////////////
 // Implementation of rotate/spin animation
 ////////////////////////////////////////////////////////////////////////
@@ -798,7 +850,7 @@ void SpinAnimCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
     if (!cv)
         return;
     if (!_condition || _condition->test()) {
-        double t = nv->getFrameStamp()->getReferenceTime();
+        double t = nv->getFrameStamp()->getSimulationTime();
         double rps = _animationValue->getValue() / 60.0;
         ref_ptr<ReferenceValues>
             refval(static_cast<ReferenceValues*>(_referenceValues.get()));
@@ -846,6 +898,30 @@ void SpinAnimCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
     }
 }
 
+SGVec3d readTranslateAxis(const SGPropertyNode* configNode)
+{
+    SGVec3d axis;
+    
+    if (configNode->hasValue("axis/x1-m")) {
+        SGVec3d v1, v2;
+        v1[0] = configNode->getDoubleValue("axis/x1-m", 0);
+        v1[1] = configNode->getDoubleValue("axis/y1-m", 0);
+        v1[2] = configNode->getDoubleValue("axis/z1-m", 0);
+        v2[0] = configNode->getDoubleValue("axis/x2-m", 0);
+        v2[1] = configNode->getDoubleValue("axis/y2-m", 0);
+        v2[2] = configNode->getDoubleValue("axis/z2-m", 0);
+        axis = v2 - v1;
+    } else {
+        axis[0] = configNode->getDoubleValue("axis/x", 0);
+        axis[1] = configNode->getDoubleValue("axis/y", 0);
+        axis[2] = configNode->getDoubleValue("axis/z", 0);
+    }
+    if (8*SGLimitsd::min() < norm(axis))
+        axis = normalize(axis);
+
+    return axis;
+}
+
 SGRotateAnimation::SGRotateAnimation(const SGPropertyNode* configNode,
                                      SGPropertyNode* modelRoot) :
   SGAnimation(configNode, modelRoot)
@@ -862,28 +938,8 @@ SGRotateAnimation::SGRotateAnimation(const SGPropertyNode* configNode,
     _initialValue = _animationValue->getValue();
   else
     _initialValue = 0;
-  _center = SGVec3d::zeros();
-  if (configNode->hasValue("axis/x1-m")) {
-    SGVec3d v1, v2;
-    v1[0] = configNode->getDoubleValue("axis/x1-m", 0);
-    v1[1] = configNode->getDoubleValue("axis/y1-m", 0);
-    v1[2] = configNode->getDoubleValue("axis/z1-m", 0);
-    v2[0] = configNode->getDoubleValue("axis/x2-m", 0);
-    v2[1] = configNode->getDoubleValue("axis/y2-m", 0);
-    v2[2] = configNode->getDoubleValue("axis/z2-m", 0);
-    _center = 0.5*(v1+v2);
-    _axis = v2 - v1;
-  } else {
-    _axis[0] = configNode->getDoubleValue("axis/x", 0);
-    _axis[1] = configNode->getDoubleValue("axis/y", 0);
-    _axis[2] = configNode->getDoubleValue("axis/z", 0);
-  }
-  if (8*SGLimitsd::min() < norm(_axis))
-    _axis = normalize(_axis);
-
-  _center[0] = configNode->getDoubleValue("center/x-m", _center[0]);
-  _center[1] = configNode->getDoubleValue("center/y-m", _center[1]);
-  _center[2] = configNode->getDoubleValue("center/z-m", _center[2]);
+  
+  readRotationCenterAndAxis(_center, _axis);
 }
 
 osg::Group*
@@ -913,7 +969,7 @@ SGRotateAnimation::createAnimationGroup(osg::Group& parent)
     }
 }
 
-\f
+
 ////////////////////////////////////////////////////////////////////////
 // Implementation of scale animation
 ////////////////////////////////////////////////////////////////////////
@@ -1047,7 +1103,7 @@ SGScaleAnimation::createAnimationGroup(osg::Group& parent)
   return transform;
 }
 
-\f
+
 // Don't create a new state state everytime we need GL_NORMALIZE!
 
 namespace
@@ -1193,7 +1249,7 @@ namespace
    &SGDistScaleAnimation::Transform::writeLocalData
    );
 }
-\f
+
 ////////////////////////////////////////////////////////////////////////
 // Implementation of flash animation
 ////////////////////////////////////////////////////////////////////////
@@ -1349,7 +1405,7 @@ namespace
    &SGFlashAnimation::Transform::writeLocalData
    );
 }
-\f
+
 ////////////////////////////////////////////////////////////////////////
 // Implementation of billboard animation
 ////////////////////////////////////////////////////////////////////////
@@ -1434,7 +1490,7 @@ namespace
    &SGBillboardAnimation::Transform::writeLocalData
    );
 }
-\f
+
 ////////////////////////////////////////////////////////////////////////
 // Implementation of a range animation
 ////////////////////////////////////////////////////////////////////////
@@ -1539,7 +1595,7 @@ SGRangeAnimation::createAnimationGroup(osg::Group& parent)
   return group;
 }
 
-\f
+
 ////////////////////////////////////////////////////////////////////////
 // Implementation of a select animation
 ////////////////////////////////////////////////////////////////////////
@@ -1569,7 +1625,7 @@ SGSelectAnimation::createAnimationGroup(osg::Group& parent)
 }
 
 
-\f
+
 ////////////////////////////////////////////////////////////////////////
 // Implementation of alpha test animation
 ////////////////////////////////////////////////////////////////////////
@@ -1639,7 +1695,7 @@ SGAlphaTestAnimation::install(osg::Node& node)
   }
 }
 
-\f
+
 //////////////////////////////////////////////////////////////////////
 // Blend animation installer
 //////////////////////////////////////////////////////////////////////
@@ -1758,7 +1814,7 @@ SGBlendAnimation::install(osg::Node& node)
   node.accept(visitor);
 }
 
-\f
+
 //////////////////////////////////////////////////////////////////////
 // Timed animation installer
 //////////////////////////////////////////////////////////////////////
@@ -1806,7 +1862,7 @@ public:
     _current_index = _current_index % nChildren;
 
     // update the time and compute the current systems time value
-    double t = nv->getFrameStamp()->getReferenceTime();
+    double t = nv->getFrameStamp()->getSimulationTime();
     if (_last_time_sec == SGLimitsd::max()) {
       _last_time_sec = t;
     } else {
@@ -1869,7 +1925,7 @@ SGTimedAnimation::createAnimationGroup(osg::Group& parent)
   return sw;
 }
 
-\f
+
 ////////////////////////////////////////////////////////////////////////
 // dynamically switch on/off shadows
 ////////////////////////////////////////////////////////////////////////
@@ -1915,7 +1971,7 @@ SGShadowAnimation::createAnimationGroup(osg::Group& parent)
   return group;
 }
 
-\f
+
 ////////////////////////////////////////////////////////////////////////
 // Implementation of SGTexTransformAnimation
 ////////////////////////////////////////////////////////////////////////