Speed up finding of attachment node by using the cached nodeMap

coverity_scan^2
scrawl 8 years ago
parent a76d693627
commit 767eba941f

@ -1,5 +1,9 @@
#include "creatureanimation.hpp" #include "creatureanimation.hpp"
#include <iostream>
#include <osg/MatrixTransform>
#include <components/esm/loadcrea.hpp> #include <components/esm/loadcrea.hpp>
#include <components/resource/resourcesystem.hpp> #include <components/resource/resourcesystem.hpp>
@ -9,6 +13,8 @@
#include <components/sceneutil/positionattitudetransform.hpp> #include <components/sceneutil/positionattitudetransform.hpp>
#include <components/sceneutil/skeleton.hpp> #include <components/sceneutil/skeleton.hpp>
#include <components/misc/stringops.hpp>
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
@ -107,39 +113,51 @@ void CreatureWeaponAnimation::updatePart(PartHolderPtr& scene, int slot)
else else
bonename = "Shield Bone"; bonename = "Shield Bone";
osg::ref_ptr<osg::Node> node = mResourceSystem->getSceneManager()->getInstance(item.getClass().getModel(item)); try
osg::ref_ptr<osg::Node> attached = SceneUtil::attach(node, mObjectRoot, bonename, bonename);
mResourceSystem->getSceneManager()->notifyAttached(attached);
scene.reset(new PartHolder(attached));
if (!item.getClass().getEnchantment(item).empty())
addGlow(attached, getEnchantmentColor(item));
// Crossbows start out with a bolt attached
// FIXME: code duplicated from NpcAnimation
if (slot == MWWorld::InventoryStore::Slot_CarriedRight &&
item.getTypeName() == typeid(ESM::Weapon).name() &&
item.get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanCrossbow)
{ {
MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); osg::ref_ptr<osg::Node> node = mResourceSystem->getSceneManager()->getInstance(item.getClass().getModel(item));
if (ammo != inv.end() && ammo->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::Bolt)
attachArrow(); const NodeMap& nodeMap = getNodeMap();
NodeMap::const_iterator found = getNodeMap().find(Misc::StringUtils::lowerCase(bonename));
if (found == nodeMap.end())
throw std::runtime_error("Can't find attachment node " + bonename);
osg::ref_ptr<osg::Node> attached = SceneUtil::attach(node, mObjectRoot, bonename, found->second.get());
mResourceSystem->getSceneManager()->notifyAttached(attached);
scene.reset(new PartHolder(attached));
if (!item.getClass().getEnchantment(item).empty())
addGlow(attached, getEnchantmentColor(item));
// Crossbows start out with a bolt attached
// FIXME: code duplicated from NpcAnimation
if (slot == MWWorld::InventoryStore::Slot_CarriedRight &&
item.getTypeName() == typeid(ESM::Weapon).name() &&
item.get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanCrossbow)
{
MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition);
if (ammo != inv.end() && ammo->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::Bolt)
attachArrow();
else
mAmmunition.reset();
}
else else
mAmmunition.reset(); mAmmunition.reset();
}
else
mAmmunition.reset();
boost::shared_ptr<SceneUtil::ControllerSource> source; boost::shared_ptr<SceneUtil::ControllerSource> source;
if (slot == MWWorld::InventoryStore::Slot_CarriedRight) if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
source = mWeaponAnimationTime; source = mWeaponAnimationTime;
else else
source.reset(new NullAnimationTime); source.reset(new NullAnimationTime);
SceneUtil::AssignControllerSourcesVisitor assignVisitor(source); SceneUtil::AssignControllerSourcesVisitor assignVisitor(source);
attached->accept(assignVisitor); attached->accept(assignVisitor);
}
catch (std::exception& e)
{
std::cerr << "Error adding creature part: " << e.what() << std::endl;
}
} }
void CreatureWeaponAnimation::attachArrow() void CreatureWeaponAnimation::attachArrow()

@ -667,10 +667,18 @@ void NpcAnimation::updateParts()
attachArrow(); attachArrow();
} }
PartHolderPtr NpcAnimation::insertBoundedPart(const std::string& model, const std::string& bonename, const std::string& bonefilter, bool enchantedGlow, osg::Vec4f* glowColor) PartHolderPtr NpcAnimation::insertBoundedPart(const std::string& model, const std::string& bonename, const std::string& bonefilter, bool enchantedGlow, osg::Vec4f* glowColor)
{ {
osg::ref_ptr<osg::Node> instance = mResourceSystem->getSceneManager()->getInstance(model); osg::ref_ptr<osg::Node> instance = mResourceSystem->getSceneManager()->getInstance(model);
osg::ref_ptr<osg::Node> attached = SceneUtil::attach(instance, mObjectRoot, bonefilter, bonename);
const NodeMap& nodeMap = getNodeMap();
NodeMap::const_iterator found = nodeMap.find(Misc::StringUtils::lowerCase(bonename));
if (found == nodeMap.end())
throw std::runtime_error("Can't find attachment node " + bonename);
osg::ref_ptr<osg::Node> attached = SceneUtil::attach(instance, mObjectRoot, bonefilter, found->second);
mResourceSystem->getSceneManager()->notifyAttached(attached); mResourceSystem->getSceneManager()->notifyAttached(attached);
if (enchantedGlow) if (enchantedGlow)
addGlow(attached, *glowColor); addGlow(attached, *glowColor);

@ -63,7 +63,7 @@ namespace SceneUtil
std::string mFilter2; std::string mFilter2;
}; };
osg::ref_ptr<osg::Node> attach(osg::ref_ptr<osg::Node> toAttach, osg::Node *master, const std::string &filter, const std::string &attachNode) osg::ref_ptr<osg::Node> attach(osg::ref_ptr<osg::Node> toAttach, osg::Node *master, const std::string &filter, osg::Group* attachNode)
{ {
if (dynamic_cast<SceneUtil::Skeleton*>(toAttach.get())) if (dynamic_cast<SceneUtil::Skeleton*>(toAttach.get()))
{ {
@ -88,11 +88,6 @@ namespace SceneUtil
} }
else else
{ {
FindByNameVisitor find(attachNode);
master->accept(find);
if (!find.mFoundNode)
throw std::runtime_error(std::string("Can't find attachment node ") + attachNode);
FindByNameVisitor findBoneOffset("BoneOffset"); FindByNameVisitor findBoneOffset("BoneOffset");
toAttach->accept(findBoneOffset); toAttach->accept(findBoneOffset);
@ -110,7 +105,7 @@ namespace SceneUtil
trans->setAttitude(osg::Quat(osg::DegreesToRadians(-90.f), osg::Vec3f(1,0,0))); trans->setAttitude(osg::Quat(osg::DegreesToRadians(-90.f), osg::Vec3f(1,0,0)));
} }
if (attachNode.find("Left") != std::string::npos) if (attachNode->getName().find("Left") != std::string::npos)
{ {
if (!trans) if (!trans)
trans = new osg::PositionAttitudeTransform; trans = new osg::PositionAttitudeTransform;
@ -132,13 +127,13 @@ namespace SceneUtil
if (trans) if (trans)
{ {
find.mFoundNode->addChild(trans); attachNode->addChild(trans);
trans->addChild(toAttach); trans->addChild(toAttach);
return trans; return trans;
} }
else else
{ {
find.mFoundNode->addChild(toAttach); attachNode->addChild(toAttach);
return toAttach; return toAttach;
} }
} }

@ -8,6 +8,7 @@
namespace osg namespace osg
{ {
class Node; class Node;
class Group;
} }
namespace SceneUtil namespace SceneUtil
@ -18,7 +19,7 @@ namespace SceneUtil
/// Otherwise, just attach all of the toAttach scenegraph to the attachment node on the master scenegraph, with no filtering. /// Otherwise, just attach all of the toAttach scenegraph to the attachment node on the master scenegraph, with no filtering.
/// @note The master scene graph is expected to include a skeleton. /// @note The master scene graph is expected to include a skeleton.
/// @return A newly created node that is directly attached to the master scene graph /// @return A newly created node that is directly attached to the master scene graph
osg::ref_ptr<osg::Node> attach(osg::ref_ptr<osg::Node> toAttach, osg::Node* master, const std::string& filter, const std::string& attachNode); osg::ref_ptr<osg::Node> attach(osg::ref_ptr<osg::Node> toAttach, osg::Node* master, const std::string& filter, osg::Group* attachNode);
} }

Loading…
Cancel
Save