From b582cd230eb54293b5537ada0f550fdf83ceaaf4 Mon Sep 17 00:00:00 2001 From: Frederic Bouvier Date: Wed, 4 Jan 2012 19:42:46 +0100 Subject: [PATCH] Implement a cache of light effects --- simgear/scene/model/SGLightAnimation.cxx | 51 ++++++++++++++--------- simgear/scene/model/SGReaderWriterXML.cxx | 2 +- simgear/scene/model/animation.cxx | 5 ++- simgear/scene/model/animation.hxx | 7 +++- 4 files changed, 41 insertions(+), 24 deletions(-) diff --git a/simgear/scene/model/SGLightAnimation.cxx b/simgear/scene/model/SGLightAnimation.cxx index 6d6257b4..4e7c2a16 100644 --- a/simgear/scene/model/SGLightAnimation.cxx +++ b/simgear/scene/model/SGLightAnimation.cxx @@ -19,6 +19,8 @@ # include #endif +#include + #include "animation.hxx" #include "ConditionNode.hxx" @@ -28,6 +30,9 @@ #include #include +typedef std::map > EffectMap; +static EffectMap lightEffectMap; + #define GET_COLOR_VALUE(n) \ SGVec4d( getConfig()->getDoubleValue(n "/r"), \ getConfig()->getDoubleValue(n "/g"), \ @@ -35,7 +40,8 @@ getConfig()->getDoubleValue(n "/a") ) SGLightAnimation::SGLightAnimation(const SGPropertyNode* configNode, - SGPropertyNode* modelRoot) : + SGPropertyNode* modelRoot, + const string &path, int i) : SGAnimation(configNode, modelRoot) { _position = SGVec3d( getConfig()->getDoubleValue("position/x"), getConfig()->getDoubleValue("position/y"), getConfig()->getDoubleValue("position/z") ); @@ -50,6 +56,7 @@ SGLightAnimation::SGLightAnimation(const SGPropertyNode* configNode, _cutoff = getConfig()->getDoubleValue("cutoff"); _near = getConfig()->getDoubleValue("near-m"); _far = getConfig()->getDoubleValue("far-m"); + _key = path + ";" + boost::lexical_cast( i ); } osg::Group* @@ -91,7 +98,7 @@ cone->setUseDisplayList(false); } osg::Vec4Array* colours = new osg::Vec4Array(1); - (*colours)[0] = osg::Vec4d(toOsg(getConfig()->getValue("diffuse")), 1.0f); + (*colours)[0] = toOsg(_diffuse); cone->setColorArray(colours); cone->setColorBinding(osg::Geometry::BIND_OVERALL); @@ -109,23 +116,29 @@ cone->setUseDisplayList(false); node.asGroup()->addChild( geode ); - // TODO: build a cache - problem: what is the key ? - SGPropertyNode_ptr effectProp = new SGPropertyNode; - makeChild(effectProp, "inherits-from")->setStringValue("Effects/light-spot"); - SGPropertyNode* params = makeChild(effectProp, "parameters"); - params->getNode("light-spot/position",true)->setValue(SGVec4d(_position.x(),_position.y(),_position.z(),1.0)); - params->getNode("light-spot/direction",true)->setValue(SGVec4d(_direction.x(),_direction.y(),_direction.z(),0.0)); - params->getNode("light-spot/ambient",true)->setValue(_ambient); - params->getNode("light-spot/diffuse",true)->setValue(_diffuse); - params->getNode("light-spot/specular",true)->setValue(_specular); - params->getNode("light-spot/attenuation",true)->setValue(_attenuation); - params->getNode("light-spot/exponent",true)->setValue(_exponent); - params->getNode("light-spot/cutoff",true)->setValue(_cutoff); - params->getNode("light-spot/cosCutoff",true)->setValue( cos(_cutoff*SG_DEGREES_TO_RADIANS) ); - params->getNode("light-spot/near",true)->setValue(_near); - params->getNode("light-spot/far",true)->setValue(_far); - - simgear::Effect* effect = simgear::makeEffect(effectProp, true); + simgear::Effect* effect = 0; + EffectMap::iterator iter = lightEffectMap.find(_key); + if (iter == lightEffectMap.end()) { + SGPropertyNode_ptr effectProp = new SGPropertyNode; + makeChild(effectProp, "inherits-from")->setStringValue("Effects/light-spot"); + SGPropertyNode* params = makeChild(effectProp, "parameters"); + params->getNode("light-spot/position",true)->setValue(SGVec4d(_position.x(),_position.y(),_position.z(),1.0)); + params->getNode("light-spot/direction",true)->setValue(SGVec4d(_direction.x(),_direction.y(),_direction.z(),0.0)); + params->getNode("light-spot/ambient",true)->setValue(_ambient); + params->getNode("light-spot/diffuse",true)->setValue(_diffuse); + params->getNode("light-spot/specular",true)->setValue(_specular); + params->getNode("light-spot/attenuation",true)->setValue(_attenuation); + params->getNode("light-spot/exponent",true)->setValue(_exponent); + params->getNode("light-spot/cutoff",true)->setValue(_cutoff); + params->getNode("light-spot/cosCutoff",true)->setValue( cos(_cutoff*SG_DEGREES_TO_RADIANS) ); + params->getNode("light-spot/near",true)->setValue(_near); + params->getNode("light-spot/far",true)->setValue(_far); + + effect = simgear::makeEffect(effectProp, true); + lightEffectMap.insert(EffectMap::value_type(_key, effect)); + } else { + effect = iter->second.get(); + } geode->setEffect(effect); } } diff --git a/simgear/scene/model/SGReaderWriterXML.cxx b/simgear/scene/model/SGReaderWriterXML.cxx index 1a83f204..3a461328 100644 --- a/simgear/scene/model/SGReaderWriterXML.cxx +++ b/simgear/scene/model/SGReaderWriterXML.cxx @@ -438,7 +438,7 @@ sgLoad3DModel_internal(const SGPath& path, for (unsigned i = 0; i < animation_nodes.size(); ++i) /// OSGFIXME: duh, why not only model????? SGAnimation::animate(group.get(), animation_nodes[i], prop_root, - options.get()); + options.get(), path.str(), i); if (!needTransform && group->getNumChildren() < 2) { model = group->getChild(0); diff --git a/simgear/scene/model/animation.cxx b/simgear/scene/model/animation.cxx index b6748fe0..582046ea 100644 --- a/simgear/scene/model/animation.cxx +++ b/simgear/scene/model/animation.cxx @@ -410,7 +410,8 @@ SGAnimation::~SGAnimation() bool SGAnimation::animate(osg::Node* node, const SGPropertyNode* configNode, SGPropertyNode* modelRoot, - const osgDB::Options* options) + const osgDB::Options* options, + const string &path, int i) { std::string type = configNode->getStringValue("type", "none"); if (type == "alpha-test") { @@ -466,7 +467,7 @@ SGAnimation::animate(osg::Node* node, const SGPropertyNode* configNode, SGTranslateAnimation animInst(configNode, modelRoot); animInst.apply(node); } else if (type == "light") { - SGLightAnimation animInst(configNode, modelRoot); + SGLightAnimation animInst(configNode, modelRoot, path, i); animInst.apply(node); } else if (type == "null" || type == "none" || type.empty()) { SGGroupAnimation animInst(configNode, modelRoot); diff --git a/simgear/scene/model/animation.hxx b/simgear/scene/model/animation.hxx index fcd81a97..331ff3cf 100644 --- a/simgear/scene/model/animation.hxx +++ b/simgear/scene/model/animation.hxx @@ -46,7 +46,8 @@ public: static bool animate(osg::Node* node, const SGPropertyNode* configNode, SGPropertyNode* modelRoot, - const osgDB::Options* options); + const osgDB::Options* options, + const string &path, int i); protected: void apply(osg::Node* node); @@ -351,7 +352,8 @@ private: class SGLightAnimation : public SGAnimation { public: SGLightAnimation(const SGPropertyNode* configNode, - SGPropertyNode* modelRoot); + SGPropertyNode* modelRoot, + const string &path, int i); virtual osg::Group* createAnimationGroup(osg::Group& parent); virtual void install(osg::Node& node); private: @@ -365,6 +367,7 @@ private: double _cutoff; double _near; double _far; + string _key; }; #endif // _SG_ANIMATION_HXX -- 2.39.5