From 31c33247054cfacb65e0904feccfe291f1c872a2 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 17 Dec 2015 03:04:36 +0100 Subject: [PATCH] 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. --- apps/openmw/mwphysics/physicssystem.cpp | 2 +- components/nifosg/nifloader.cpp | 2 +- components/nifosg/particle.cpp | 12 ++++++++---- components/nifosg/particle.hpp | 7 ++++--- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index eebfddaab..7b4b93678 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -580,7 +580,7 @@ namespace MWPhysics int recIndex = it->first; int shapeIndex = it->second; - NifOsg::FindRecIndexVisitor visitor(recIndex); + NifOsg::FindGroupByRecIndex visitor(recIndex); mPtr.getRefData().getBaseNode()->accept(visitor); if (!visitor.mFound) { diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 0489e07e6..9a017a497 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -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. // 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); if (!find.mFound) { diff --git a/components/nifosg/particle.cpp b/components/nifosg/particle.cpp index e3162bcd9..500339722 100644 --- a/components/nifosg/particle.cpp +++ b/components/nifosg/particle.cpp @@ -276,7 +276,7 @@ void Emitter::emitParticles(double dt) int randomRecIndex = mTargets[(std::rand() / (static_cast(RAND_MAX)+1.0)) * mTargets.size()]; // we could use a map here for faster lookup - FindRecIndexVisitor visitor(randomRecIndex); + FindGroupByRecIndex visitor(randomRecIndex); getParent(0)->accept(visitor); 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) , mFound(NULL) , mRecIndex(recIndex) { } -void FindRecIndexVisitor::apply(osg::Node &searchNode) +void FindGroupByRecIndex::apply(osg::Node &searchNode) { if (searchNode.getUserDataContainer() && searchNode.getUserDataContainer()->getNumUserObjects()) { NodeUserData* holder = dynamic_cast(searchNode.getUserDataContainer()->getUserObject(0)); if (holder && holder->mIndex == mRecIndex) { - mFound = static_cast(&searchNode); + osg::Group* group = searchNode.asGroup(); + if (!group) + group = searchNode.getParent(0); + + mFound = group; mFoundPath = getNodePath(); return; } diff --git a/components/nifosg/particle.hpp b/components/nifosg/particle.hpp index d86408254..a1ed3f3d0 100644 --- a/components/nifosg/particle.hpp +++ b/components/nifosg/particle.hpp @@ -172,11 +172,12 @@ namespace NifOsg osg::Vec3f mCachedWorldDirection; }; - // NodeVisitor to find a child node with the given record index, stored in the node's user data container. - class FindRecIndexVisitor : public osg::NodeVisitor + // NodeVisitor to find a Group node with the given record index, stored in the node's user data container. + // 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: - FindRecIndexVisitor(int recIndex); + FindGroupByRecIndex(int recIndex); virtual void apply(osg::Node &searchNode);