mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-27 12:35:46 +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:
parent
ac3fda0b3d
commit
147ed39900
@ -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…
x
Reference in New Issue
Block a user