This PR solves a crash with Robert's bodies logged on your bugtracker. (#3095)

* attach.cpp [ci skip]

* attach.cpp [ci skip]

* attach.cpp [ci skip]

* npcanimation.cpp [ci skip]

* attach.hpp [ci skip]

* attach.cpp [ci skip]

* creatureanimation.cpp [ci skip]

* creatureanimation.cpp [ci skip]

* cellpreloader.cpp

* npcanimation.cpp

* attach.cpp

* make android adk happy

* make android adk happy

* changelog.md [ci skip]

* authors.md [ci skip]
pull/3100/head^2
Bo Svensson 3 years ago committed by GitHub
parent ac3fda0b3d
commit 147ed39900
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -44,6 +44,7 @@ Programmers
Austin Salgat (Salgat)
Ben Shealy (bentsherman)
Berulacks
Bo Svensson
Britt Mathis (galdor557)
Capostrophic
Carl Maxwell

@ -7,6 +7,7 @@
Bug #3846: Strings starting with "-" fail to compile if not enclosed in quotes
Bug #3905: Great House Dagoth issues
Bug #4203: Resurrecting an actor should close the loot GUI
Bug #4602: Robert's Bodies: crash inside createInstance()
Bug #4700: Editor: Incorrect command implementation
Bug #4744: Invisible particles must still be processed
Bug #4752: UpdateCellCommand doesn't undo properly

@ -158,7 +158,7 @@ void CreatureWeaponAnimation::updatePart(PartHolderPtr& scene, int slot)
try
{
osg::ref_ptr<osg::Node> node = mResourceSystem->getSceneManager()->getInstance(itemModel);
osg::ref_ptr<const osg::Node> node = mResourceSystem->getSceneManager()->getTemplate(itemModel);
const NodeMap& nodeMap = getNodeMap();
NodeMap::const_iterator found = nodeMap.find(Misc::StringUtils::lowerCase(bonename));

@ -714,14 +714,14 @@ void NpcAnimation::updateParts()
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<const osg::Node> templateNode = mResourceSystem->getSceneManager()->getTemplate(model);
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);
osg::ref_ptr<osg::Node> attached = SceneUtil::attach(templateNode, mObjectRoot, bonefilter, found->second);
if (enchantedGlow)
mGlowUpdater = SceneUtil::addEnchantedGlow(attached, mResourceSystem, *glowColor);

@ -114,10 +114,7 @@ namespace MWWorld
}
}
}
if (mPreloadInstances && animated)
mPreloadedObjects.insert(mSceneManager->cacheInstance(mesh));
else
mPreloadedObjects.insert(mSceneManager->getTemplate(mesh));
mPreloadedObjects.insert(mSceneManager->getTemplate(mesh));
if (mPreloadInstances)
mPreloadedObjects.insert(mBulletShapeManager->cacheInstance(mesh));
else

@ -15,6 +15,7 @@
#include <components/sceneutil/skeleton.hpp>
#include "visitor.hpp"
#include "clone.hpp"
namespace SceneUtil
{
@ -49,10 +50,10 @@ namespace SceneUtil
return;
osg::Node* node = &drawable;
while (node->getNumParents())
for (auto it = getNodePath().rbegin()+1; it != getNodePath().rend(); ++it)
{
osg::Group* parent = node->getParent(0);
if (!parent || !filterMatches(parent->getName()))
osg::Node* parent = *it;
if (!filterMatches(parent->getName()))
break;
node = parent;
}
@ -63,12 +64,7 @@ namespace SceneUtil
{
for (const osg::ref_ptr<osg::Node>& node : mToCopy)
{
if (node->getNumParents() > 1)
Log(Debug::Error) << "Error CopyRigVisitor: node has " << node->getNumParents() << " parents";
while (node->getNumParents())
node->getParent(0)->removeChild(node);
mParent->addChild(node);
mParent->addChild(static_cast<osg::Node*>(node->clone(SceneUtil::CopyOp())));
}
mToCopy.clear();
}
@ -90,25 +86,25 @@ namespace SceneUtil
std::string mFilter2;
};
void mergeUserData(osg::UserDataContainer* source, osg::Object* target)
void mergeUserData(const osg::UserDataContainer* source, osg::Object* target)
{
if (!target->getUserDataContainer())
target->setUserDataContainer(source);
target->setUserDataContainer(osg::clone(source, osg::CopyOp::SHALLOW_COPY));
else
{
for (unsigned int i=0; i<source->getNumUserObjects(); ++i)
target->getUserDataContainer()->addUserObject(source->getUserObject(i));
target->getUserDataContainer()->addUserObject(osg::clone(source->getUserObject(i), osg::CopyOp::SHALLOW_COPY));
}
}
osg::ref_ptr<osg::Node> attach(osg::ref_ptr<osg::Node> toAttach, osg::Node *master, const std::string &filter, osg::Group* attachNode)
osg::ref_ptr<osg::Node> attach(osg::ref_ptr<const osg::Node> toAttach, osg::Node *master, const std::string &filter, osg::Group* attachNode)
{
if (dynamic_cast<SceneUtil::Skeleton*>(toAttach.get()))
if (dynamic_cast<const SceneUtil::Skeleton*>(toAttach.get()))
{
osg::ref_ptr<osg::Group> handle = new osg::Group;
CopyRigVisitor copyVisitor(handle, filter);
toAttach->accept(copyVisitor);
const_cast<osg::Node*>(toAttach.get())->accept(copyVisitor);
copyVisitor.doCopy();
if (handle->getNumChildren() == 1)
@ -122,14 +118,16 @@ namespace SceneUtil
else
{
master->asGroup()->addChild(handle);
handle->setUserDataContainer(toAttach->getUserDataContainer());
mergeUserData(toAttach->getUserDataContainer(), handle);
return handle;
}
}
else
{
osg::ref_ptr<osg::Node> clonedToAttach = static_cast<osg::Node*>(toAttach->clone(SceneUtil::CopyOp()));
FindByNameVisitor findBoneOffset("BoneOffset");
toAttach->accept(findBoneOffset);
clonedToAttach->accept(findBoneOffset);
osg::ref_ptr<osg::PositionAttitudeTransform> trans;
@ -172,13 +170,13 @@ namespace SceneUtil
if (trans)
{
attachNode->addChild(trans);
trans->addChild(toAttach);
trans->addChild(clonedToAttach);
return trans;
}
else
{
attachNode->addChild(toAttach);
return toAttach;
attachNode->addChild(clonedToAttach);
return clonedToAttach;
}
}
}

@ -14,12 +14,12 @@ namespace osg
namespace SceneUtil
{
/// Attach parts of the \a toAttach scenegraph to the \a master scenegraph, using the specified filter and attachment node.
/// Clone and attach parts of the \a toAttach scenegraph to the \a master scenegraph, using the specified filter and attachment node.
/// If the \a toAttach scene graph contains skinned objects, we will attach only those (filtered by the \a filter).
/// 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.
/// @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, osg::Group* attachNode);
osg::ref_ptr<osg::Node> attach(osg::ref_ptr<const osg::Node> toAttach, osg::Node* master, const std::string& filter, osg::Group* attachNode);
}

Loading…
Cancel
Save