From 55e9d8d944d5dc0ba59b159b801af11d6e39923b Mon Sep 17 00:00:00 2001
From: Tim Moore <timoore@redhat.com>
Date: Tue, 13 Jan 2009 14:10:15 +0100
Subject: [PATCH] SGMaterialAnimation: Don't install an update callback if
 values are static

---
 simgear/scene/model/SGMaterialAnimation.cxx | 160 ++++++++++----------
 1 file changed, 82 insertions(+), 78 deletions(-)

diff --git a/simgear/scene/model/SGMaterialAnimation.cxx b/simgear/scene/model/SGMaterialAnimation.cxx
index cce40c62..72df88e5 100644
--- a/simgear/scene/model/SGMaterialAnimation.cxx
+++ b/simgear/scene/model/SGMaterialAnimation.cxx
@@ -406,16 +406,12 @@ SGMaterialAnimation::createAnimationGroup(osg::Group& parent)
   const SGPropertyNode* node = getConfig()->getChild("property-base");
   if (node)
     inputRoot = getModelRoot()->getNode(node->getStringValue(), true);
-  if (getConfig()->hasChild("texture-prop")) {
-      osg::StateSet* stateSet = group->getOrCreateStateSet();
-      stateSet->setDataVariance(osg::Object::DYNAMIC);
-  }
+  osg::StateSet* stateSet = group->getOrCreateStateSet();  
   if (getConfig()->hasChild("texture")) {
     std::string textureName = getConfig()->getStringValue("texture");
     std::string textureFile;
     textureFile = osgDB::findFileInPath(textureName, texturePathList);
     if (!textureFile.empty()) {
-      osg::StateSet* stateSet = group->getOrCreateStateSet();
       osg::Texture2D* texture2D = SGLoadTexture2D(textureFile);
       if (texture2D) {
         stateSet->setTextureAttribute(0, texture2D,
@@ -430,7 +426,6 @@ SGMaterialAnimation::createAnimationGroup(osg::Group& parent)
   }
   if (getConfig()->hasChild("threshold-prop") ||
       getConfig()->hasChild("threshold")) {
-    osg::StateSet* stateSet = group->getOrCreateStateSet();
     osg::AlphaFunc* alphaFunc = new osg::AlphaFunc;
     alphaFunc->setFunction(osg::AlphaFunc::GREATER);
     float threshold = getConfig()->getFloatValue("threshold", 0);
@@ -452,83 +447,92 @@ SGMaterialAnimation::createAnimationGroup(osg::Group& parent)
     suppliedColors |= SHININESS;
   if (getConfig()->hasChild("transparency"))
     suppliedColors |= TRANSPARENCY;
-
+  osg::Material* mat = 0;
   if (suppliedColors != 0) {
-      osg::StateSet* stateSet = group->getOrCreateStateSet();
-      osg::Material* mat;
-
-      if (defaultMaterial.valid()) {
-	mat = defaultMaterial.get();
+    if (defaultMaterial.valid()) {
+      mat = defaultMaterial.get();
 
+    } else {
+      mat = new osg::Material;
+      mat->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
+    }
+    mat->setDataVariance(osg::Object::DYNAMIC);
+    unsigned defaultColorModeMask = 0;
+    mat->setUpdateCallback(0); // Just to make sure.
+    switch (mat->getColorMode()) {
+    case osg::Material::OFF:
+      defaultColorModeMask = 0;
+      break;
+    case osg::Material::AMBIENT:
+      defaultColorModeMask = AMBIENT;
+      break;
+    case osg::Material::DIFFUSE:
+      defaultColorModeMask = DIFFUSE;
+      break;
+    case osg::Material::AMBIENT_AND_DIFFUSE:
+      defaultColorModeMask = AMBIENT | DIFFUSE;
+      break;
+    case osg::Material::SPECULAR:
+      defaultColorModeMask = SPECULAR;
+      break;
+    case osg::Material::EMISSION:
+      defaultColorModeMask = EMISSION;
+      break;
+    }
+    // Copy the color found by traversing geometry into the material
+    // in case we need to specify it (e.g., transparency) and it is
+    // not specified by the animation.
+    if (defaultAmbientDiffuse.x() >= 0) {
+      if (defaultColorModeMask & AMBIENT)
+        mat->setAmbient(osg::Material::FRONT_AND_BACK, defaultAmbientDiffuse);
+      if (defaultColorModeMask & DIFFUSE)
+        mat->setDiffuse(osg::Material::FRONT_AND_BACK, defaultAmbientDiffuse);
+    }
+    // Compute which colors in the animation override colors set via
+    // colorMode / glColor, and set the colorMode for the animation's
+    // material accordingly. 
+    if (suppliedColors & TRANSPARENCY) {
+      // All colors will be affected by the material. Hope all the
+      // defaults are fine, if needed.
+      mat->setColorMode(osg::Material::OFF);
+    } else if ((suppliedColors & defaultColorModeMask) != 0) {
+      // First deal with the complicated AMBIENT/DIFFUSE case.
+      if ((defaultColorModeMask & AMBIENT_DIFFUSE) != 0) {
+        // glColor can supply colors not specified by the animation.
+        unsigned matColorModeMask = ((~suppliedColors & defaultColorModeMask)
+                                     & AMBIENT_DIFFUSE);
+        if ((matColorModeMask & DIFFUSE) != 0)
+          mat->setColorMode(osg::Material::DIFFUSE);
+        else if ((matColorModeMask & AMBIENT) != 0)
+          mat->setColorMode(osg::Material::AMBIENT);
+        else
+          mat->setColorMode(osg::Material::OFF);
       } else {
-	mat = new osg::Material;
-	mat->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
-      }
-      mat->setDataVariance(osg::Object::DYNAMIC);
-      unsigned defaultColorModeMask = 0;
-      mat->setUpdateCallback(0); // Just to make sure.
-      switch (mat->getColorMode()) {
-      case osg::Material::OFF:
-	defaultColorModeMask = 0;
-	break;
-      case osg::Material::AMBIENT:
-	defaultColorModeMask = AMBIENT;
-	break;
-      case osg::Material::DIFFUSE:
-	defaultColorModeMask = DIFFUSE;
-	break;
-      case osg::Material::AMBIENT_AND_DIFFUSE:
-	defaultColorModeMask = AMBIENT | DIFFUSE;
-	break;
-      case osg::Material::SPECULAR:
-	defaultColorModeMask = SPECULAR;
-	break;
-      case osg::Material::EMISSION:
-	defaultColorModeMask = EMISSION;
-	break;
-      }
-      // Copy the color found by traversing geometry into the material
-      // in case we need to specify it (e.g., transparency) and it is
-      // not specified by the animation.
-      if (defaultAmbientDiffuse.x() >= 0) {
-	if (defaultColorModeMask & AMBIENT)
-	  mat->setAmbient(osg::Material::FRONT_AND_BACK, defaultAmbientDiffuse);
-	if (defaultColorModeMask & DIFFUSE)
-	  mat->setDiffuse(osg::Material::FRONT_AND_BACK, defaultAmbientDiffuse);
-      }
-      // Compute which colors in the animation override colors set via
-      // colorMode / glColor, and set the colorMode for the animation's
-      // material accordingly. 
-      if (suppliedColors & TRANSPARENCY) {
-	// All colors will be affected by the material. Hope all the
-	// defaults are fine, if needed.
-	mat->setColorMode(osg::Material::OFF);
-      } else if ((suppliedColors & defaultColorModeMask) != 0) {
-	// First deal with the complicated AMBIENT/DIFFUSE case.
-	if ((defaultColorModeMask & AMBIENT_DIFFUSE) != 0) {
-	  // glColor can supply colors not specified by the animation.
-	  unsigned matColorModeMask = ((~suppliedColors & defaultColorModeMask)
-				       & AMBIENT_DIFFUSE);
-	  if ((matColorModeMask & DIFFUSE) != 0)
-	    mat->setColorMode(osg::Material::DIFFUSE);
-	  else if ((matColorModeMask & AMBIENT) != 0)
-	    mat->setColorMode(osg::Material::AMBIENT);
-	  else
-	    mat->setColorMode(osg::Material::OFF);
-	} else {
-	  // The animation overrides the glColor color.
-	  mat->setColorMode(osg::Material::OFF);
-	}
-      } else {
-	// No overlap between the animation and color mode, so leave
-	// the color mode alone.
+        // The animation overrides the glColor color.
+        mat->setColorMode(osg::Material::OFF);
       }
-      stateSet->setAttribute(mat,(osg::StateAttribute::ON
-				  | osg::StateAttribute::OVERRIDE));
+    } else {
+      // No overlap between the animation and color mode, so leave
+      // the color mode alone.
+    }
+    stateSet->setAttribute(mat,(osg::StateAttribute::ON
+                                | osg::StateAttribute::OVERRIDE));
+  }
+  bool matAnimated = false;
+  if (mat) {
+    MaterialPropertyAdapter adapter(getConfig(), inputRoot);
+    adapter.setMaterialValues(stateSet);
+    matAnimated = adapter.isAnimated();
+  }
+  if (matAnimated || getConfig()->hasChild("texture-prop")
+      || getConfig()->hasChild("threshold-prop") || getCondition()) {
+    stateSet->setDataVariance(osg::Object::DYNAMIC);
+    group->setUpdateCallback(new UpdateCallback(texturePathList,
+                                                getCondition(),
+                                                getConfig(), inputRoot));
+  } else {
+    stateSet->setDataVariance(osg::Object::STATIC);
   }
-  group->setUpdateCallback(new UpdateCallback(texturePathList,
-					      getCondition(),
-					      getConfig(), inputRoot));
   parent.addChild(group);
   return group;
 }
-- 
2.39.5