]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/model/SGMaterialAnimation.cxx
Work around apparent OSG 3.2.0 normal binding bug.
[simgear.git] / simgear / scene / model / SGMaterialAnimation.cxx
index d726a59c5a6a4a0abb628f9e21a0b4596c8af7b4..cc5c660c6ae93355779e3f8600e1e6c2791b3f0c 100644 (file)
 #include <simgear/scene/material/Pass.hxx>
 #include <simgear/scene/material/Technique.hxx>
 #include <simgear/scene/model/model.hxx>
+#include <simgear/scene/model/ConditionNode.hxx>
+#include <simgear/scene/util/OsgMath.hxx>
 
 using namespace std;
+using namespace simgear;
 
 namespace {
 /**
@@ -339,9 +342,7 @@ public:
 class UpdateCallback : public osg::NodeCallback {
 public:
   UpdateCallback(const osgDB::FilePathList& texturePathList,
-                 const SGCondition* condition,
                  const SGPropertyNode* configNode, SGPropertyNode* modelRoot) :
-    _condition(condition),
     _materialProps(configNode, modelRoot),
     _texturePathList(texturePathList),
     _prevState(false)
@@ -359,7 +360,7 @@ public:
   virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
   {
     osg::StateSet* stateSet = node->getStateSet();
-    if ((!_condition || _condition->test()) && stateSet) {
+    if (stateSet) {
       if (_textureProp) {
         std::string textureName = _textureProp->getStringValue();
         if (_textureName != textureName) {
@@ -399,7 +400,6 @@ public:
     traverse(node, nv);
   }
 private:
-  SGSharedPtr<const SGCondition> _condition;
   SGSharedPtr<const SGPropertyNode> _textureProp;
   SGSharedPtr<const SGPropertyNode> _thresholdProp;
   std::string _textureName;
@@ -412,14 +412,15 @@ private:
 
 SGMaterialAnimation::SGMaterialAnimation(const SGPropertyNode* configNode,
                                          SGPropertyNode* modelRoot,
-                                         const osgDB::ReaderWriter::Options*
-                                         options) :
+                                         const osgDB::Options*
+                                         options, const string &path) :
   SGAnimation(configNode, modelRoot),
   texturePathList(options->getDatabasePathList())
 {
   if (configNode->hasChild("global"))
-    SG_LOG(SG_IO, SG_ALERT, "Use of <global> in material animation is "
-           "no longer supported");
+    SG_LOG(SG_IO, SG_ALERT, path <<
+           ": Use of <global> in material animation is "
+           "no longer supported.");
 }
 
 osg::Group*
@@ -485,6 +486,8 @@ SGMaterialAnimation::createAnimationGroup(osg::Group& parent)
     mat->setDataVariance(osg::Object::DYNAMIC);
     unsigned defaultColorModeMask = 0;
     mat->setUpdateCallback(0); // Just to make sure.
+    // XXX This should probably go away, as ac3d models always have a
+    // DIFFUSE color mode.
     switch (mat->getColorMode()) {
     case osg::Material::OFF:
       defaultColorModeMask = 0;
@@ -554,13 +557,23 @@ SGMaterialAnimation::createAnimationGroup(osg::Group& parent)
       || getConfig()->hasChild("threshold-prop") || getCondition()) {
     stateSet->setDataVariance(osg::Object::DYNAMIC);
     group->setUpdateCallback(new UpdateCallback(texturePathList,
-                                                getCondition(),
                                                 getConfig(), inputRoot));
   } else {
     stateSet->setDataVariance(osg::Object::STATIC);
   }
-  parent.addChild(group);
-  return group;
+  if (getCondition()) {
+    ConditionNode* cn = new ConditionNode;
+    cn->setCondition(getCondition());
+    osg::Group* modelGroup = new osg::Group;
+    group->addChild(modelGroup);
+    cn->addChild(group);
+    cn->addChild(modelGroup);
+    parent.addChild(cn);
+    return modelGroup;
+  } else {
+    parent.addChild(group);
+    return group;
+  }
 }
 
 void
@@ -576,3 +589,32 @@ SGMaterialAnimation::install(osg::Node& node)
     }
     defaultAmbientDiffuse = defaultsVisitor.ambientDiffuse;
 }
+
+const char* colorNames[] =
+{
+    "ambient",
+    "diffuse",
+    "specular",
+    "emission"
+};
+
+// Build an effect which mimics the material color mode in a
+// shader. The OpenGL material values will be overridden by the
+// material animation's material.
+//
+// This is a hack to get the effect to respect the values set in the
+// material, set up by the animation, which overrides the values in
+// the effect's material attributes. Things will be different when
+// material animations are implemented purely by manipulating effects.
+
+SGPropertyNode_ptr
+SGMaterialAnimation::makeEffectProperties(const SGPropertyNode* animProp)
+{
+    SGPropertyNode_ptr eRoot = new SGPropertyNode;
+    SGPropertyNode* inherit = makeNode(eRoot, "inherits-from");
+    if (animProp->hasChild("diffuse") || animProp->hasChild("transparency"))
+        inherit->setStringValue("Effects/material-off");
+    else
+        inherit->setStringValue("Effects/material-diffuse");
+    return eRoot;
+}