1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-30 10:36:42 +00:00

Don't assume the emitter node is a Group (Fixes #3082)

This would be a correct assumption by default, but is no longer true when the NifLoader::optimize() function optimizes the graph.
This commit is contained in:
scrawl 2015-12-17 03:04:36 +01:00
parent 8222c78cf2
commit 31c3324705
4 changed files with 14 additions and 9 deletions

View file

@ -580,7 +580,7 @@ namespace MWPhysics
int recIndex = it->first; int recIndex = it->first;
int shapeIndex = it->second; int shapeIndex = it->second;
NifOsg::FindRecIndexVisitor visitor(recIndex); NifOsg::FindGroupByRecIndex visitor(recIndex);
mPtr.getRefData().getBaseNode()->accept(visitor); mPtr.getRefData().getBaseNode()->accept(visitor);
if (!visitor.mFound) if (!visitor.mFound)
{ {

View file

@ -887,7 +887,7 @@ namespace NifOsg
// This seems to be true for all NIF files in the game that I've checked, suggesting that NIFs work similar to OSG with regards to update order. // This seems to be true for all NIF files in the game that I've checked, suggesting that NIFs work similar to OSG with regards to update order.
// If something ever violates this assumption, the worst that could happen is the culling being one frame late, which wouldn't be a disaster. // If something ever violates this assumption, the worst that could happen is the culling being one frame late, which wouldn't be a disaster.
FindRecIndexVisitor find (partctrl->emitter->recIndex); FindGroupByRecIndex find (partctrl->emitter->recIndex);
rootNode->accept(find); rootNode->accept(find);
if (!find.mFound) if (!find.mFound)
{ {

View file

@ -276,7 +276,7 @@ void Emitter::emitParticles(double dt)
int randomRecIndex = mTargets[(std::rand() / (static_cast<double>(RAND_MAX)+1.0)) * mTargets.size()]; int randomRecIndex = mTargets[(std::rand() / (static_cast<double>(RAND_MAX)+1.0)) * mTargets.size()];
// we could use a map here for faster lookup // we could use a map here for faster lookup
FindRecIndexVisitor visitor(randomRecIndex); FindGroupByRecIndex visitor(randomRecIndex);
getParent(0)->accept(visitor); getParent(0)->accept(visitor);
if (!visitor.mFound) if (!visitor.mFound)
@ -306,21 +306,25 @@ void Emitter::emitParticles(double dt)
} }
} }
FindRecIndexVisitor::FindRecIndexVisitor(int recIndex) FindGroupByRecIndex::FindGroupByRecIndex(int recIndex)
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
, mFound(NULL) , mFound(NULL)
, mRecIndex(recIndex) , mRecIndex(recIndex)
{ {
} }
void FindRecIndexVisitor::apply(osg::Node &searchNode) void FindGroupByRecIndex::apply(osg::Node &searchNode)
{ {
if (searchNode.getUserDataContainer() && searchNode.getUserDataContainer()->getNumUserObjects()) if (searchNode.getUserDataContainer() && searchNode.getUserDataContainer()->getNumUserObjects())
{ {
NodeUserData* holder = dynamic_cast<NodeUserData*>(searchNode.getUserDataContainer()->getUserObject(0)); NodeUserData* holder = dynamic_cast<NodeUserData*>(searchNode.getUserDataContainer()->getUserObject(0));
if (holder && holder->mIndex == mRecIndex) if (holder && holder->mIndex == mRecIndex)
{ {
mFound = static_cast<osg::Group*>(&searchNode); osg::Group* group = searchNode.asGroup();
if (!group)
group = searchNode.getParent(0);
mFound = group;
mFoundPath = getNodePath(); mFoundPath = getNodePath();
return; return;
} }

View file

@ -172,11 +172,12 @@ namespace NifOsg
osg::Vec3f mCachedWorldDirection; osg::Vec3f mCachedWorldDirection;
}; };
// NodeVisitor to find a child node with the given record index, stored in the node's user data container. // NodeVisitor to find a Group node with the given record index, stored in the node's user data container.
class FindRecIndexVisitor : public osg::NodeVisitor // Alternatively, returns the node's parent Group if that node is not a Group (i.e. a leaf node).
class FindGroupByRecIndex : public osg::NodeVisitor
{ {
public: public:
FindRecIndexVisitor(int recIndex); FindGroupByRecIndex(int recIndex);
virtual void apply(osg::Node &searchNode); virtual void apply(osg::Node &searchNode);