diff --git a/components/nifosg/matrixtransform.cpp b/components/nifosg/matrixtransform.cpp index 12144b62a6..72e12ecf8e 100644 --- a/components/nifosg/matrixtransform.cpp +++ b/components/nifosg/matrixtransform.cpp @@ -7,9 +7,8 @@ namespace NifOsg { } - MatrixTransform::MatrixTransform(int recordIndex, const Nif::Transformation &trafo) + MatrixTransform::MatrixTransform(const Nif::Transformation &trafo) : osg::MatrixTransform(trafo.toMatrix()) - , mIndex(recordIndex) , mScale(trafo.scale) , mRotationScale(trafo.rotation) { @@ -17,7 +16,6 @@ namespace NifOsg MatrixTransform::MatrixTransform(const MatrixTransform ©, const osg::CopyOp ©op) : osg::MatrixTransform(copy, copyop) - , mIndex(copy.mIndex) , mScale(copy.mScale) , mRotationScale(copy.mRotationScale) { diff --git a/components/nifosg/matrixtransform.hpp b/components/nifosg/matrixtransform.hpp index b633efaad6..ac2fbb57a6 100644 --- a/components/nifosg/matrixtransform.hpp +++ b/components/nifosg/matrixtransform.hpp @@ -12,7 +12,7 @@ namespace NifOsg { public: MatrixTransform(); - MatrixTransform(int recordIndex, const Nif::Transformation &trafo); + MatrixTransform(const Nif::Transformation &trafo); MatrixTransform(const MatrixTransform ©, const osg::CopyOp ©op); META_Node(NifOsg, MatrixTransform) @@ -29,9 +29,6 @@ namespace NifOsg // Apply the given translation to OSG matrix. void setTranslation(const osg::Vec3f& translation); - // NIF record index - int mIndex{0}; - private: // Hack: account for Transform differences between OSG and NIFs. // OSG uses a 4x4 matrix, NIF's use a 3x3 rotationScale, float scale, and vec3 position. diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 68e3f9a9ce..f88800e364 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -43,6 +43,7 @@ #include #include "matrixtransform.hpp" +#include "nodeindexholder.hpp" #include "particle.hpp" namespace @@ -487,7 +488,7 @@ namespace NifOsg break; } if (!node) - node = new NifOsg::MatrixTransform(nifNode->recIndex, nifNode->trafo); + node = new NifOsg::MatrixTransform(nifNode->trafo); if (nifNode->recType == Nif::RC_NiCollisionSwitch && !(nifNode->flags & Nif::NiNode::Flag_ActiveCollision)) { @@ -522,6 +523,12 @@ namespace NifOsg if (!rootNode) rootNode = node; + // The original NIF record index is used for a variety of features: + // - finding the correct emitter node for a particle system + // - establishing connections to the animated collision shapes, which are handled in a separate loader + // - finding a random child NiNode in NiBspArrayController + node->getOrCreateUserDataContainer()->addUserObject(new NodeIndexHolder(nifNode->recIndex)); + for (Nif::ExtraPtr e = nifNode->extra; !e.empty(); e = e->next) { if(e->recType == Nif::RC_NiTextKeyExtraData && textKeys) diff --git a/components/nifosg/nodeindexholder.hpp b/components/nifosg/nodeindexholder.hpp new file mode 100644 index 0000000000..e7d4f0db31 --- /dev/null +++ b/components/nifosg/nodeindexholder.hpp @@ -0,0 +1,35 @@ +#ifndef OPENMW_COMPONENTS_NIFOSG_NODEINDEXHOLDER_H +#define OPENMW_COMPONENTS_NIFOSG_NODEINDEXHOLDER_H + +#include + +namespace NifOsg +{ + + class NodeIndexHolder : public osg::Object + { + public: + NodeIndexHolder() = default; + NodeIndexHolder(int index) + : mIndex(index) + { + } + NodeIndexHolder(const NodeIndexHolder& copy, const osg::CopyOp& copyop) + : Object(copy, copyop) + , mIndex(copy.mIndex) + { + } + + META_Object(NifOsg, NodeIndexHolder) + + int getIndex() const { return mIndex; } + + private: + + // NIF record index + int mIndex{0}; + }; + +} + +#endif diff --git a/components/nifosg/particle.cpp b/components/nifosg/particle.cpp index 7c72771186..0cbc3f22b5 100644 --- a/components/nifosg/particle.cpp +++ b/components/nifosg/particle.cpp @@ -11,7 +11,7 @@ #include #include -#include "matrixtransform.hpp" +#include "nodeindexholder.hpp" namespace NifOsg { @@ -381,11 +381,16 @@ void FindGroupByRecIndex::apply(osg::Geometry &node) void FindGroupByRecIndex::applyNode(osg::Node &searchNode) { - if (NifOsg::MatrixTransform* trans = dynamic_cast(&searchNode)) + if (searchNode.getUserDataContainer() && searchNode.getUserDataContainer()->getNumUserObjects()) { - if (trans->mIndex == mRecIndex) + NodeIndexHolder* holder = dynamic_cast(searchNode.getUserDataContainer()->getUserObject(0)); + if (holder && holder->getIndex() == mRecIndex) { - mFound = trans; + osg::Group* group = searchNode.asGroup(); + if (!group) + group = searchNode.getParent(0); + + mFound = group; mFoundPath = getNodePath(); return; } diff --git a/components/sceneutil/serialize.cpp b/components/sceneutil/serialize.cpp index 1577f080f3..62325186c0 100644 --- a/components/sceneutil/serialize.cpp +++ b/components/sceneutil/serialize.cpp @@ -143,6 +143,7 @@ void registerSerializers() "NifOsg::GeomMorpherController", "NifOsg::UpdateMorphGeometry", "NifOsg::UVController", + "NifOsg::NodeIndexHolder", "osgMyGUI::Drawable", "osg::DrawCallback", "osgOQ::ClearQueriesCallback",