diff --git a/components/nifogre/ogrenifloader.cpp b/components/nifogre/ogrenifloader.cpp index aca27d82a..86d713aab 100644 --- a/components/nifogre/ogrenifloader.cpp +++ b/components/nifogre/ogrenifloader.cpp @@ -391,9 +391,10 @@ public: class Value : public NodeTargetValue, public ValueInterpolator { private: - Nif::QuaternionKeyList mRotations; - Nif::Vector3KeyList mTranslations; - Nif::FloatKeyList mScales; + const Nif::QuaternionKeyList* mRotations; + const Nif::Vector3KeyList* mTranslations; + const Nif::FloatKeyList* mScales; + Nif::NIFFilePtr mNif; // Hold a SharedPtr to make sure key lists stay valid using ValueInterpolator::interpKey; @@ -421,31 +422,33 @@ public: } public: - Value(Ogre::Node *target, const Nif::NiKeyframeData *data) + /// @note The NiKeyFrameData must be valid as long as this KeyframeController exists. + Value(Ogre::Node *target, const Nif::NIFFilePtr& nif, const Nif::NiKeyframeData *data) : NodeTargetValue(target) - , mRotations(data->mRotations) - , mTranslations(data->mTranslations) - , mScales(data->mScales) + , mRotations(&data->mRotations) + , mTranslations(&data->mTranslations) + , mScales(&data->mScales) + , mNif(nif) { } virtual Ogre::Quaternion getRotation(float time) const { - if(mRotations.mKeys.size() > 0) - return interpKey(mRotations.mKeys, time); + if(mRotations->mKeys.size() > 0) + return interpKey(mRotations->mKeys, time); return mNode->getOrientation(); } virtual Ogre::Vector3 getTranslation(float time) const { - if(mTranslations.mKeys.size() > 0) - return interpKey(mTranslations.mKeys, time); + if(mTranslations->mKeys.size() > 0) + return interpKey(mTranslations->mKeys, time); return mNode->getPosition(); } virtual Ogre::Vector3 getScale(float time) const { - if(mScales.mKeys.size() > 0) - return Ogre::Vector3(interpKey(mScales.mKeys, time)); + if(mScales->mKeys.size() > 0) + return Ogre::Vector3(interpKey(mScales->mKeys, time)); return mNode->getScale(); } @@ -457,12 +460,12 @@ public: virtual void setValue(Ogre::Real time) { - if(mRotations.mKeys.size() > 0) - mNode->setOrientation(interpKey(mRotations.mKeys, time)); - if(mTranslations.mKeys.size() > 0) - mNode->setPosition(interpKey(mTranslations.mKeys, time)); - if(mScales.mKeys.size() > 0) - mNode->setScale(Ogre::Vector3(interpKey(mScales.mKeys, time))); + if(mRotations->mKeys.size() > 0) + mNode->setOrientation(interpKey(mRotations->mKeys, time)); + if(mTranslations->mKeys.size() > 0) + mNode->setPosition(interpKey(mTranslations->mKeys, time)); + if(mScales->mKeys.size() > 0) + mNode->setScale(Ogre::Vector3(interpKey(mScales->mKeys, time))); } }; @@ -932,7 +935,7 @@ class NIFObjectLoader } - static void createNodeControllers(const std::string &name, Nif::ControllerPtr ctrl, ObjectScenePtr scene, int animflags) + static void createNodeControllers(const Nif::NIFFilePtr& nif, const std::string &name, Nif::ControllerPtr ctrl, ObjectScenePtr scene, int animflags) { do { if (ctrl->flags & Nif::NiNode::ControllerFlag_Active) @@ -966,7 +969,7 @@ class NIFObjectLoader Ogre::ControllerValueRealPtr srcval((animflags&Nif::NiNode::AnimFlag_AutoPlay) ? Ogre::ControllerManager::getSingleton().getFrameTimeSource() : Ogre::ControllerValueRealPtr()); - Ogre::ControllerValueRealPtr dstval(OGRE_NEW KeyframeController::Value(trgtbone, key->data.getPtr())); + Ogre::ControllerValueRealPtr dstval(OGRE_NEW KeyframeController::Value(trgtbone, nif, key->data.getPtr())); KeyframeController::Function* function = OGRE_NEW KeyframeController::Function(key, (animflags&Nif::NiNode::AnimFlag_AutoPlay)); scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength); Ogre::ControllerFunctionRealPtr func(function); @@ -1019,7 +1022,7 @@ class NIFObjectLoader } - static void createObjects(const std::string &name, const std::string &group, + static void createObjects(const Nif::NIFFilePtr& nif, const std::string &name, const std::string &group, Ogre::SceneNode *sceneNode, const Nif::Node *node, ObjectScenePtr scene, int flags, int animflags, int partflags) { @@ -1076,7 +1079,7 @@ class NIFObjectLoader } if(!node->controller.empty()) - createNodeControllers(name, node->controller, scene, animflags); + createNodeControllers(nif, name, node->controller, scene, animflags); if(node->recType == Nif::RC_NiCamera) { @@ -1101,7 +1104,7 @@ class NIFObjectLoader for(size_t i = 0;i < children.length();i++) { if(!children[i].empty()) - createObjects(name, group, sceneNode, children[i].getPtr(), scene, flags, animflags, partflags); + createObjects(nif, name, group, sceneNode, children[i].getPtr(), scene, flags, animflags, partflags); } } } @@ -1148,7 +1151,7 @@ public: // Create a base skeleton entity if this NIF needs one createSkelBase(name, group, sceneNode->getCreator(), node, scene); } - createObjects(name, group, sceneNode, node, scene, flags, 0, 0); + createObjects(nif, name, group, sceneNode, node, scene, flags, 0, 0); } static void loadKf(Ogre::Skeleton *skel, const std::string &name, @@ -1205,7 +1208,7 @@ public: Ogre::Bone *trgtbone = skel->getBone(strdata->string); Ogre::ControllerValueRealPtr srcval; - Ogre::ControllerValueRealPtr dstval(OGRE_NEW KeyframeController::Value(trgtbone, key->data.getPtr())); + Ogre::ControllerValueRealPtr dstval(OGRE_NEW KeyframeController::Value(trgtbone, nif, key->data.getPtr())); Ogre::ControllerFunctionRealPtr func(OGRE_NEW KeyframeController::Function(key, false)); ctrls.push_back(Ogre::Controller(srcval, dstval, func));