1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-10-16 10:46:33 +00:00

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]
This commit is contained in:
Bo Svensson 2021-09-09 20:56:57 +00:00 committed by GitHub
parent ac3fda0b3d
commit 147ed39900
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 26 additions and 29 deletions

View file

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

View file

@ -7,6 +7,7 @@
Bug #3846: Strings starting with "-" fail to compile if not enclosed in quotes Bug #3846: Strings starting with "-" fail to compile if not enclosed in quotes
Bug #3905: Great House Dagoth issues Bug #3905: Great House Dagoth issues
Bug #4203: Resurrecting an actor should close the loot GUI 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 #4700: Editor: Incorrect command implementation
Bug #4744: Invisible particles must still be processed Bug #4744: Invisible particles must still be processed
Bug #4752: UpdateCellCommand doesn't undo properly Bug #4752: UpdateCellCommand doesn't undo properly

View file

@ -158,7 +158,7 @@ void CreatureWeaponAnimation::updatePart(PartHolderPtr& scene, int slot)
try 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(); const NodeMap& nodeMap = getNodeMap();
NodeMap::const_iterator found = nodeMap.find(Misc::StringUtils::lowerCase(bonename)); NodeMap::const_iterator found = nodeMap.find(Misc::StringUtils::lowerCase(bonename));

View file

@ -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) 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(); const NodeMap& nodeMap = getNodeMap();
NodeMap::const_iterator found = nodeMap.find(Misc::StringUtils::lowerCase(bonename)); NodeMap::const_iterator found = nodeMap.find(Misc::StringUtils::lowerCase(bonename));
if (found == nodeMap.end()) if (found == nodeMap.end())
throw std::runtime_error("Can't find attachment node " + bonename); 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) if (enchantedGlow)
mGlowUpdater = SceneUtil::addEnchantedGlow(attached, mResourceSystem, *glowColor); mGlowUpdater = SceneUtil::addEnchantedGlow(attached, mResourceSystem, *glowColor);

View file

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

View file

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

View file

@ -14,12 +14,12 @@ namespace osg
namespace SceneUtil 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). /// 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. /// 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, 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);
} }