mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 17:29:55 +00:00
Speed up finding of attachment node by using the cached nodeMap
This commit is contained in:
parent
a76d693627
commit
767eba941f
4 changed files with 62 additions and 40 deletions
|
@ -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();
|
||||||
|
|
||||||
|
boost::shared_ptr<SceneUtil::ControllerSource> source;
|
||||||
|
|
||||||
|
if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
|
||||||
|
source = mWeaponAnimationTime;
|
||||||
|
else
|
||||||
|
source.reset(new NullAnimationTime);
|
||||||
|
|
||||||
|
SceneUtil::AssignControllerSourcesVisitor assignVisitor(source);
|
||||||
|
attached->accept(assignVisitor);
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
std::cerr << "Error adding creature part: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
mAmmunition.reset();
|
|
||||||
|
|
||||||
boost::shared_ptr<SceneUtil::ControllerSource> source;
|
|
||||||
|
|
||||||
if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
|
|
||||||
source = mWeaponAnimationTime;
|
|
||||||
else
|
|
||||||
source.reset(new NullAnimationTime);
|
|
||||||
|
|
||||||
SceneUtil::AssignControllerSourcesVisitor assignVisitor(source);
|
|
||||||
attached->accept(assignVisitor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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…
Reference in a new issue