Create a different default effect for objects that have material animations

This commit is contained in:
Tim Moore 2010-01-27 18:34:27 +01:00
parent 59fc902cfb
commit eefb069d08
3 changed files with 67 additions and 22 deletions

View File

@ -29,6 +29,7 @@
#include <simgear/scene/model/model.hxx>
using namespace std;
using namespace simgear;
namespace {
/**
@ -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;
@ -576,3 +579,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;
}

View File

@ -26,6 +26,7 @@ public:
const osgDB::ReaderWriter::Options* options);
virtual osg::Group* createAnimationGroup(osg::Group& parent);
virtual void install(osg::Node& node);
static SGPropertyNode_ptr makeEffectProperties(const SGPropertyNode* animProp);
private:
osg::ref_ptr<osg::Material> defaultMaterial;
osg::Vec4 defaultAmbientDiffuse;

View File

@ -49,6 +49,7 @@
#include "particles.hxx"
#include "model.hxx"
#include "SGText.hxx"
#include "SGMaterialAnimation.hxx"
using namespace std;
using namespace simgear;
@ -145,31 +146,42 @@ void makeEffectAnimations(PropertyList& animation_nodes,
for (PropertyList::iterator itr = animation_nodes.begin();
itr != animation_nodes.end();
++itr) {
SGPropertyNode_ptr effectProp;
SGPropertyNode* animProp = itr->ptr();
SGPropertyNode* typeProp = animProp->getChild("type");
if (!typeProp || strcmp(typeProp->getStringValue(), "shader"))
if (!typeProp)
continue;
SGPropertyNode* shaderProp = animProp->getChild("shader");
if (!shaderProp || strcmp(shaderProp->getStringValue(), "chrome"))
continue;
*itr = 0;
SGPropertyNode* textureProp = animProp->getChild("texture");
if (!textureProp)
continue;
SGPropertyNode_ptr effectProp = new SGPropertyNode();
makeChild(effectProp.ptr(), "inherits-from")
->setValue("Effects/chrome");
SGPropertyNode* paramsProp = makeChild(effectProp.get(), "parameters");
makeChild(paramsProp, "chrome-texture")
->setValue(textureProp->getStringValue());
PropertyList objectNameNodes = animProp->getChildren("object-name");
for (PropertyList::iterator objItr = objectNameNodes.begin(),
end = objectNameNodes.end();
objItr != end;
++objItr)
effectProp->addChild("object-name")
->setStringValue((*objItr)->getStringValue());
effect_nodes.push_back(effectProp);
const char* typeString = typeProp->getStringValue();
if (!strcmp(typeString, "material")) {
effectProp
= SGMaterialAnimation::makeEffectProperties(animProp);
} else if (!strcmp(typeString, "shader")) {
SGPropertyNode* shaderProp = animProp->getChild("shader");
if (!shaderProp || strcmp(shaderProp->getStringValue(), "chrome"))
continue;
*itr = 0; // effect replaces animation
SGPropertyNode* textureProp = animProp->getChild("texture");
if (!textureProp)
continue;
effectProp = new SGPropertyNode();
makeChild(effectProp.ptr(), "inherits-from")
->setValue("Effects/chrome");
SGPropertyNode* paramsProp = makeChild(effectProp.get(), "parameters");
makeChild(paramsProp, "chrome-texture")
->setValue(textureProp->getStringValue());
}
if (effectProp.valid()) {
PropertyList objectNameNodes = animProp->getChildren("object-name");
for (PropertyList::iterator objItr = objectNameNodes.begin(),
end = objectNameNodes.end();
objItr != end;
++objItr)
effectProp->addChild("object-name")
->setStringValue((*objItr)->getStringValue());
effect_nodes.push_back(effectProp);
}
}
animation_nodes.erase(remove_if(animation_nodes.begin(),
animation_nodes.end(),