From a9439d58c718c264edad865c378e3ea0729bc021 Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Tue, 13 Jan 2009 12:50:47 +0100 Subject: [PATCH] SGMaterialAnimation: factor out update of osg::Material --- simgear/scene/model/SGMaterialAnimation.cxx | 117 ++++++++++++-------- 1 file changed, 71 insertions(+), 46 deletions(-) diff --git a/simgear/scene/model/SGMaterialAnimation.cxx b/simgear/scene/model/SGMaterialAnimation.cxx index 47397fdb..cce40c62 100644 --- a/simgear/scene/model/SGMaterialAnimation.cxx +++ b/simgear/scene/model/SGMaterialAnimation.cxx @@ -245,20 +245,78 @@ public: osg::Vec4 ambientDiffuse; }; +class MaterialPropertyAdapter +{ +public: + MaterialPropertyAdapter(const SGPropertyNode* configNode, + SGPropertyNode* modelRoot) : + _ambient(configNode->getChild("ambient"), modelRoot), + _diffuse(configNode->getChild("diffuse"), modelRoot), + _specular(configNode->getChild("specular"), modelRoot), + _emission(configNode->getChild("emission"), modelRoot), + _shininess("shininess", "shininess-prop", + configNode/*->getChild("shininess")*/, modelRoot), + _transparency("alpha", "alpha-prop", + configNode->getChild("transparency"), modelRoot) + { + _shininess.max = 128; + _isAnimated = (_ambient.live() || _diffuse.live() || _specular.live() + || _emission.live() || _shininess.live() + || _transparency.live()); + } + bool isAnimated() { return _isAnimated; } + // This takes a StateSet argument because the rendering bin will + // be changed if there is transparency. + void setMaterialValues(osg::StateSet* stateSet) + { + osg::StateAttribute* stateAttribute + = stateSet->getAttribute(osg::StateAttribute::MATERIAL); + osg::Material* material = dynamic_cast(stateAttribute); + if (material) { + if (_ambient.live() || _ambient.dirty()) + material->setAmbient(osg::Material::FRONT_AND_BACK, + _ambient.rgbaVec4()); + if (_diffuse.live() || _diffuse.dirty()) + material->setDiffuse(osg::Material::FRONT_AND_BACK, + _diffuse.rgbaVec4()); + if (_specular.live() || _specular.dirty()) + material->setSpecular(osg::Material::FRONT_AND_BACK, + _specular.rgbaVec4()); + if (_emission.live() || _emission.dirty()) + material->setEmission(osg::Material::FRONT_AND_BACK, + _emission.rgbaVec4()); + if (_shininess.live() || _shininess.dirty()) + material->setShininess(osg::Material::FRONT_AND_BACK, + _shininess.getValue()); + if (_transparency.live() || _transparency.dirty()) { + float alpha = _transparency.getValue(); + material->setAlpha(osg::Material::FRONT_AND_BACK, alpha); + if (alpha < 1.0f) { + stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + stateSet->setMode(GL_BLEND, osg::StateAttribute::ON); + } else { + stateSet->setRenderingHint(osg::StateSet::DEFAULT_BIN); + } + } + } + } + ColorSpec _ambient; + ColorSpec _diffuse; + ColorSpec _specular; + ColorSpec _emission; + PropSpec _shininess; + PropSpec _transparency; + bool _isAnimated; + +}; + class UpdateCallback : public osg::NodeCallback { public: UpdateCallback(const osgDB::FilePathList& texturePathList, const SGCondition* condition, const SGPropertyNode* configNode, SGPropertyNode* modelRoot) : _condition(condition), - _ambient(configNode->getChild("ambient"), modelRoot), - _diffuse(configNode->getChild("diffuse"), modelRoot), - _specular(configNode->getChild("specular"), modelRoot), - _emission(configNode->getChild("emission"), modelRoot), - _shininess("shininess", "shininess-prop", - configNode/*->getChild("shininess")*/, modelRoot), - _transparency("alpha", "alpha-prop", - configNode->getChild("transparency"), modelRoot), + _materialProps(configNode, modelRoot), _texturePathList(texturePathList), _prevState(false) { @@ -270,7 +328,6 @@ public: node = configNode->getChild("texture-prop"); if (node) _textureProp = modelRoot->getNode(node->getStringValue(), true); - _shininess.max = 128; } virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) @@ -302,40 +359,13 @@ public: osg::StateSet* stateSet = node->getOrCreateStateSet(); osg::StateAttribute* stateAttribute; stateAttribute = stateSet->getAttribute(osg::StateAttribute::ALPHAFUNC); - osg::AlphaFunc* alphaFunc = dynamic_cast(stateAttribute); + osg::AlphaFunc* alphaFunc + = dynamic_cast(stateAttribute); assert(alphaFunc); alphaFunc->setReferenceValue(_thresholdProp->getFloatValue()); } - osg::StateAttribute* stateAttribute - = stateSet->getAttribute(osg::StateAttribute::MATERIAL); - osg::Material* material = dynamic_cast(stateAttribute); - if (material) { - if (_ambient.live() || (!_prevState && _ambient.dirty())) - material->setAmbient(osg::Material::FRONT_AND_BACK, - _ambient.rgbaVec4()); - if (_diffuse.live() || (!_prevState && _diffuse.dirty())) - material->setDiffuse(osg::Material::FRONT_AND_BACK, - _diffuse.rgbaVec4()); - if (_specular.live() || (!_prevState && _specular.dirty())) - material->setSpecular(osg::Material::FRONT_AND_BACK, - _specular.rgbaVec4()); - if (_emission.live() || (!_prevState && _emission.dirty())) - material->setEmission(osg::Material::FRONT_AND_BACK, - _emission.rgbaVec4()); - if (_shininess.live() || (!_prevState && _shininess.dirty())) - material->setShininess(osg::Material::FRONT_AND_BACK, - _shininess.getValue()); - if (_transparency.live() || (!_prevState && _transparency.dirty())) { - float alpha = _transparency.getValue(); - material->setAlpha(osg::Material::FRONT_AND_BACK, alpha); - if (alpha < 1.0f) { - stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); - stateSet->setMode(GL_BLEND, osg::StateAttribute::ON); - } else { - stateSet->setRenderingHint(osg::StateSet::DEFAULT_BIN); - } - } - } + if (_materialProps.isAnimated() || !_prevState) + _materialProps.setMaterialValues(stateSet); _prevState = true; } else { _prevState = false; @@ -347,12 +377,7 @@ private: SGSharedPtr _textureProp; SGSharedPtr _thresholdProp; std::string _textureName; - ColorSpec _ambient; - ColorSpec _diffuse; - ColorSpec _specular; - ColorSpec _emission; - PropSpec _shininess; - PropSpec _transparency; + MaterialPropertyAdapter _materialProps; osgDB::FilePathList _texturePathList; bool _prevState; }; -- 2.39.5