1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-03 16:49:54 +00:00

Animation: don't create the NodeMap if we don't need it

This commit is contained in:
scrawl 2016-02-09 16:18:19 +01:00
parent ae031b23d4
commit 8ece1885cd
2 changed files with 39 additions and 27 deletions

View file

@ -95,7 +95,12 @@ namespace
class NodeMapVisitor : public osg::NodeVisitor class NodeMapVisitor : public osg::NodeVisitor
{ {
public: public:
NodeMapVisitor() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} typedef std::map<std::string, osg::ref_ptr<osg::MatrixTransform> > NodeMap;
NodeMapVisitor(NodeMap& map)
: osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
, mMap(map)
{}
void apply(osg::MatrixTransform& trans) void apply(osg::MatrixTransform& trans)
{ {
@ -103,15 +108,8 @@ namespace
traverse(trans); traverse(trans);
} }
typedef std::map<std::string, osg::ref_ptr<osg::MatrixTransform> > NodeMap;
const NodeMap& getNodeMap() const
{
return mMap;
}
private: private:
NodeMap mMap; NodeMap& mMap;
}; };
NifOsg::TextKeyMap::const_iterator findGroupStart(const NifOsg::TextKeyMap &keys, const std::string &groupname) NifOsg::TextKeyMap::const_iterator findGroupStart(const NifOsg::TextKeyMap &keys, const std::string &groupname)
@ -312,6 +310,7 @@ namespace MWRender
Animation::Animation(const MWWorld::Ptr &ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem) Animation::Animation(const MWWorld::Ptr &ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem)
: mInsert(parentNode) : mInsert(parentNode)
, mSkeleton(NULL) , mSkeleton(NULL)
, mNodeMapCreated(false)
, mPtr(ptr) , mPtr(ptr)
, mResourceSystem(resourceSystem) , mResourceSystem(resourceSystem)
, mAccumulate(1.f, 1.f, 0.f) , mAccumulate(1.f, 1.f, 0.f)
@ -407,12 +406,14 @@ namespace MWRender
if (!animsrc->mKeyframes || animsrc->mKeyframes->mTextKeys.empty() || animsrc->mKeyframes->mKeyframeControllers.empty()) if (!animsrc->mKeyframes || animsrc->mKeyframes->mTextKeys.empty() || animsrc->mKeyframes->mKeyframeControllers.empty())
return; return;
const NodeMap& nodeMap = getNodeMap();
for (NifOsg::KeyframeHolder::KeyframeControllerMap::const_iterator it = animsrc->mKeyframes->mKeyframeControllers.begin(); for (NifOsg::KeyframeHolder::KeyframeControllerMap::const_iterator it = animsrc->mKeyframes->mKeyframeControllers.begin();
it != animsrc->mKeyframes->mKeyframeControllers.end(); ++it) it != animsrc->mKeyframes->mKeyframeControllers.end(); ++it)
{ {
std::string bonename = Misc::StringUtils::lowerCase(it->first); std::string bonename = Misc::StringUtils::lowerCase(it->first);
NodeMap::const_iterator found = mNodeMap.find(bonename); NodeMap::const_iterator found = nodeMap.find(bonename);
if (found == mNodeMap.end()) if (found == nodeMap.end())
{ {
std::cerr << "addAnimSource: can't find bone '" + bonename << "' in " << model << " (referenced by " << kfname << ")" << std::endl; std::cerr << "addAnimSource: can't find bone '" + bonename << "' in " << model << " (referenced by " << kfname << ")" << std::endl;
continue; continue;
@ -436,11 +437,11 @@ namespace MWRender
if (!mAccumRoot) if (!mAccumRoot)
{ {
NodeMap::const_iterator found = mNodeMap.find("root bone"); NodeMap::const_iterator found = nodeMap.find("root bone");
if (found == mNodeMap.end()) if (found == nodeMap.end())
found = mNodeMap.find("bip01"); found = nodeMap.find("bip01");
if (found != mNodeMap.end()) if (found != nodeMap.end())
mAccumRoot = found->second; mAccumRoot = found->second;
} }
} }
@ -690,6 +691,17 @@ namespace MWRender
mTextKeyListener = listener; mTextKeyListener = listener;
} }
const Animation::NodeMap &Animation::getNodeMap() const
{
if (!mNodeMapCreated && mObjectRoot)
{
NodeMapVisitor visitor(mNodeMap);
mObjectRoot->accept(visitor);
mNodeMapCreated = true;
}
return mNodeMap;
}
void Animation::resetActiveGroups() void Animation::resetActiveGroups()
{ {
// remove all previous external controllers from the scene graph // remove all previous external controllers from the scene graph
@ -729,7 +741,7 @@ namespace MWRender
for (AnimSource::ControllerMap::iterator it = animsrc->mControllerMap[blendMask].begin(); it != animsrc->mControllerMap[blendMask].end(); ++it) for (AnimSource::ControllerMap::iterator it = animsrc->mControllerMap[blendMask].begin(); it != animsrc->mControllerMap[blendMask].end(); ++it)
{ {
osg::ref_ptr<osg::Node> node = mNodeMap.at(it->first); // this should not throw, we already checked for the node existing in addAnimSource osg::ref_ptr<osg::Node> node = getNodeMap().at(it->first); // this should not throw, we already checked for the node existing in addAnimSource
node->addUpdateCallback(it->second); node->addUpdateCallback(it->second);
mActiveControllers.insert(std::make_pair(node, it->second)); mActiveControllers.insert(std::make_pair(node, it->second));
@ -978,6 +990,7 @@ namespace MWRender
mSkeleton = NULL; mSkeleton = NULL;
mNodeMap.clear(); mNodeMap.clear();
mNodeMapCreated = false;
mActiveControllers.clear(); mActiveControllers.clear();
mAccumRoot = NULL; mAccumRoot = NULL;
mAccumCtrl = NULL; mAccumCtrl = NULL;
@ -1025,10 +1038,6 @@ namespace MWRender
removeTriBipVisitor.remove(); removeTriBipVisitor.remove();
} }
NodeMapVisitor visitor;
mObjectRoot->accept(visitor);
mNodeMap = visitor.getNodeMap();
mObjectRoot->addCullCallback(new SceneUtil::LightListCallback); mObjectRoot->addCullCallback(new SceneUtil::LightListCallback);
} }
@ -1121,8 +1130,8 @@ namespace MWRender
parentNode = mInsert; parentNode = mInsert;
else else
{ {
NodeMap::iterator found = mNodeMap.find(Misc::StringUtils::lowerCase(bonename)); NodeMap::const_iterator found = getNodeMap().find(Misc::StringUtils::lowerCase(bonename));
if (found == mNodeMap.end()) if (found == getNodeMap().end())
throw std::runtime_error("Can't find bone " + bonename); throw std::runtime_error("Can't find bone " + bonename);
parentNode = found->second; parentNode = found->second;
@ -1222,8 +1231,8 @@ namespace MWRender
const osg::Node* Animation::getNode(const std::string &name) const const osg::Node* Animation::getNode(const std::string &name) const
{ {
std::string lowerName = Misc::StringUtils::lowerCase(name); std::string lowerName = Misc::StringUtils::lowerCase(name);
NodeMap::const_iterator found = mNodeMap.find(lowerName); NodeMap::const_iterator found = getNodeMap().find(lowerName);
if (found == mNodeMap.end()) if (found == getNodeMap().end())
return NULL; return NULL;
else else
return found->second; return found->second;
@ -1317,8 +1326,8 @@ namespace MWRender
if (mPtr.getClass().isBipedal(mPtr)) if (mPtr.getClass().isBipedal(mPtr))
{ {
NodeMap::iterator found = mNodeMap.find("bip01 head"); NodeMap::const_iterator found = getNodeMap().find("bip01 head");
if (found != mNodeMap.end() && dynamic_cast<osg::MatrixTransform*>(found->second.get())) if (found != getNodeMap().end() && dynamic_cast<osg::MatrixTransform*>(found->second.get()))
{ {
osg::Node* node = found->second; osg::Node* node = found->second;
mHeadController = new RotateController(mObjectRoot.get()); mHeadController = new RotateController(mObjectRoot.get());

View file

@ -232,7 +232,8 @@ protected:
// Stored in all lowercase for a case-insensitive lookup // Stored in all lowercase for a case-insensitive lookup
typedef std::map<std::string, osg::ref_ptr<osg::MatrixTransform> > NodeMap; typedef std::map<std::string, osg::ref_ptr<osg::MatrixTransform> > NodeMap;
NodeMap mNodeMap; mutable NodeMap mNodeMap;
mutable bool mNodeMapCreated;
MWWorld::Ptr mPtr; MWWorld::Ptr mPtr;
@ -263,6 +264,8 @@ protected:
float mAlpha; float mAlpha;
const NodeMap& getNodeMap() const;
/* Sets the appropriate animations on the bone groups based on priority. /* Sets the appropriate animations on the bone groups based on priority.
*/ */
void resetActiveGroups(); void resetActiveGroups();