diff --git a/OgreMain/include/OgreAnimationTrack.h b/OgreMain/include/OgreAnimationTrack.h index 65e92a24dfb..644e197fab0 100644 --- a/OgreMain/include/OgreAnimationTrack.h +++ b/OgreMain/include/OgreAnimationTrack.h @@ -365,7 +365,18 @@ namespace Ogre NodeAnimationTrack* _clone(Animation* newParent) const; void _applyBaseKeyFrame(const KeyFrame* base) override; - + + /** Sets the transform of the current node to be the 'initial state' ie that + position / orientation / scale to be used as a basis for delta values used + in keyframe animation. + + If you never call this method, the initial state is the identity transform, ie do nothing. + */ + void setInitialState(void); + + /** Resets the position / orientation / scale of the node to it's initial state, see setInitialState for more info. */ + void resetToInitialState(void) const; + private: /// Specialised keyframe creation KeyFrame* createKeyFrameImpl(Real time) override; @@ -386,6 +397,13 @@ namespace Ogre Node* mTargetNode; // Prebuilt splines, must be mutable since lazy-update in const method mutable Splines* mSplines; + + /// The position to use as a base for keyframe animation + Vector3 mInitialPosition; + /// The orientation to use as a base for keyframe animation + Quaternion mInitialOrientation; + /// The scale to use as a base for keyframe animation + Vector3 mInitialScale; }; /** Type of vertex animation. diff --git a/OgreMain/include/OgreBone.h b/OgreMain/include/OgreBone.h index 8a38ef559de..920c767e6f2 100644 --- a/OgreMain/include/OgreBone.h +++ b/OgreMain/include/OgreBone.h @@ -92,6 +92,26 @@ namespace Ogre */ void reset(void); + /** Sets the current transform of this Bone to be the 'initial state' ie that + position / orientation / scale to be used as a basis for delta values used + in keyframe animation. + + If you never call this method, the initial state is the identity transform, ie do nothing. + */ + void setInitialState(void); + + /** Gets the initial position of this Bone, see setInitialState for more info. + + Also resets the cumulative animation weight used for blending. + */ + const Vector3& getInitialPosition(void) const { return mInitialPosition; } + + /** Gets the initial orientation of this Bone, see setInitialState for more info. */ + const Quaternion& getInitialOrientation(void) const { return mInitialOrientation; } + + /** Gets the initial position of this Bone, see setInitialState for more info. */ + const Vector3& getInitialScale(void) const { return mInitialScale; } + /** Sets whether or not this bone is manually controlled. Manually controlled bones can be altered by the application at runtime, @@ -136,6 +156,13 @@ namespace Ogre /// Pointer back to creator, for child creation (not smart ptr so child does not preserve parent) Skeleton* mCreator; + /// The position to use as a base for keyframe animation + Vector3 mInitialPosition; + /// The orientation to use as a base for keyframe animation + Quaternion mInitialOrientation; + /// The scale to use as a base for keyframe animation + Vector3 mInitialScale; + /// The inversed derived scale of the bone in the binding pose Vector3 mBindDerivedInverseScale; /// The inversed derived orientation of the bone in the binding pose diff --git a/OgreMain/include/OgreNode.h b/OgreMain/include/OgreNode.h index 683d7303f94..7bbc38efa41 100644 --- a/OgreMain/include/OgreNode.h +++ b/OgreMain/include/OgreNode.h @@ -177,13 +177,6 @@ namespace Ogre { */ virtual void updateFromParentImpl(void) const; private: - /// The position to use as a base for keyframe animation - Vector3 mInitialPosition; - /// The orientation to use as a base for keyframe animation - Quaternion mInitialOrientation; - /// The scale to use as a base for keyframe animation - Vector3 mInitialScale; - /** Node listener - only one allowed (no list) for size & performance reasons. */ Listener* mListener; @@ -560,28 +553,6 @@ namespace Ogre { */ Listener* getListener(void) const { return mListener; } - - /** Sets the current transform of this node to be the 'initial state' ie that - position / orientation / scale to be used as a basis for delta values used - in keyframe animation. - - You never need to call this method unless you plan to animate this node. If you do - plan to animate it, call this method once you've loaded the node with it's base state, - ie the state on which all keyframes are based. - @par - If you never call this method, the initial state is the identity transform, ie do nothing. - */ - void setInitialState(void); - - /** Resets the position / orientation / scale of this node to it's initial state, see setInitialState for more info. */ - void resetToInitialState(void); - - /** Gets the initial position of this node, see setInitialState for more info. - - Also resets the cumulative animation weight used for blending. - */ - const Vector3& getInitialPosition(void) const { return mInitialPosition; } - /** Gets the local position, relative to this node, of the given world-space position */ Vector3 convertWorldToLocalPosition( const Vector3 &worldPos ); @@ -603,12 +574,6 @@ namespace Ogre { useful for simple transforms that don't require a child node.*/ Quaternion convertLocalToWorldOrientation( const Quaternion &localOrientation ); - /** Gets the initial orientation of this node, see setInitialState for more info. */ - const Quaternion& getInitialOrientation(void) const { return mInitialOrientation; } - - /** Gets the initial position of this node, see setInitialState for more info. */ - const Vector3& getInitialScale(void) const { return mInitialScale; } - /** Helper function, get the squared view depth. */ Real getSquaredViewDepth(const Camera* cam) const; diff --git a/OgreMain/include/OgreSceneManager.h b/OgreMain/include/OgreSceneManager.h index 634ddf61534..840ead49ad2 100644 --- a/OgreMain/include/OgreSceneManager.h +++ b/OgreMain/include/OgreSceneManager.h @@ -2248,7 +2248,7 @@ namespace Ogre { You can create Animation objects for animating SceneNode obejcts using the createAnimation method. However, in order to actually apply those animations you have to call methods on Node and Animation in a particular order (namely - Node::resetToInitialState and Animation::apply). To make this easier and to + @ref NodeAnimationTrack::resetToInitialState and @ref Animation::apply). To make this easier and to help track the current time position of animations, the AnimationState object is provided. So if you don't want to control animation application manually, call this method, @@ -2260,14 +2260,14 @@ namespace Ogre { @par Note that any SceneNode affected by this automatic animation will have it's state reset to it's initial position before application of the animation. Unless specifically - modified using Node::setInitialState the Node assumes it's initial state is at the + modified using @ref NodeAnimationTrack::setInitialState the Node assumes it's initial state is at the origin. If you want the base state of the SceneNode to be elsewhere, make your changes to the node using the standard transform methods, then call setInitialState to - 'bake' this reference position into the node. + 'bake' this reference position into the NodeAnimationTrack. @par If the target of your animation is to be a generic AnimableValue, you should ensure that it has a base value set (unlike nodes this has no - default). @see AnimableValue::setAsBaseValue. + default). @ref AnimableValue::setCurrentStateAsBaseValue @param animName The name of an animation created already with createAnimation. */ AnimationState* createAnimationState(const String& animName); diff --git a/OgreMain/src/OgreAnimationTrack.cpp b/OgreMain/src/OgreAnimationTrack.cpp index 44fce4ab6f4..2a1aa2bad9f 100644 --- a/OgreMain/src/OgreAnimationTrack.cpp +++ b/OgreMain/src/OgreAnimationTrack.cpp @@ -360,8 +360,8 @@ namespace Ogre { //--------------------------------------------------------------------- NodeAnimationTrack::NodeAnimationTrack(Animation* parent, unsigned short handle, Node* targetNode) : AnimationTrack(parent, handle), mSplineBuildNeeded(false), mUseShortestRotationPath(true), - mTargetNode(targetNode), mSplines(0) - + mTargetNode(targetNode), mSplines(0), mInitialPosition(Vector3::ZERO), + mInitialOrientation(Quaternion::IDENTITY), mInitialScale(Vector3::UNIT_SCALE) { } //--------------------------------------------------------------------- @@ -681,6 +681,23 @@ namespace Ogre { } } + void NodeAnimationTrack::setInitialState(void) + { + OgreAssert(mTargetNode, "Target node must be set before calling setInitialState"); + mInitialPosition = mTargetNode->getPosition(); + mInitialOrientation = mTargetNode->getOrientation(); + mInitialScale = mTargetNode->getScale(); + } + //----------------------------------------------------------------------- + void NodeAnimationTrack::resetToInitialState(void) const + { + if (!mTargetNode) + return; + + mTargetNode->setPosition(mInitialPosition); + mTargetNode->setOrientation(mInitialOrientation); + mTargetNode->setScale(mInitialScale); + } //-------------------------------------------------------------------------- VertexAnimationTrack::VertexAnimationTrack(Animation* parent, unsigned short handle, VertexAnimationType animType) diff --git a/OgreMain/src/OgreBone.cpp b/OgreMain/src/OgreBone.cpp index d9b0f83a2c5..27ee395b309 100644 --- a/OgreMain/src/OgreBone.cpp +++ b/OgreMain/src/OgreBone.cpp @@ -33,11 +33,13 @@ namespace Ogre { Bone::Bone(unsigned short handle, Skeleton* creator) : Node(), mCreator(creator), mHandle(handle), mManuallyControlled(false) { + setInitialState(); } //--------------------------------------------------------------------- Bone::Bone(const String& name, unsigned short handle, Skeleton* creator) : Node(name), mCreator(creator), mHandle(handle), mManuallyControlled(false) { + setInitialState(); } //--------------------------------------------------------------------- Bone::~Bone() @@ -73,10 +75,21 @@ namespace Ogre { mBindDerivedInverseScale = Vector3::UNIT_SCALE / _getDerivedScale(); mBindDerivedInverseOrientation = _getDerivedOrientation().Inverse(); } - //--------------------------------------------------------------------- + //----------------------------------------------------------------------- + void Bone::setInitialState(void) + { + mInitialPosition = mPosition; + mInitialOrientation = mOrientation; + mInitialScale = mScale; + } + //----------------------------------------------------------------------- void Bone::reset(void) { - resetToInitialState(); + mPosition = mInitialPosition; + mOrientation = mInitialOrientation; + mScale = mInitialScale; + + needUpdate(); } //--------------------------------------------------------------------- void Bone::setManuallyControlled(bool manuallyControlled) diff --git a/OgreMain/src/OgreNode.cpp b/OgreMain/src/OgreNode.cpp index 0bc8974361a..03f7d7d0bdd 100644 --- a/OgreMain/src/OgreNode.cpp +++ b/OgreMain/src/OgreNode.cpp @@ -47,9 +47,6 @@ namespace Ogre { mDerivedOrientation(Quaternion::IDENTITY), mDerivedPosition(Vector3::ZERO), mDerivedScale(Vector3::UNIT_SCALE), - mInitialPosition(Vector3::ZERO), - mInitialOrientation(Quaternion::IDENTITY), - mInitialScale(Vector3::UNIT_SCALE), mListener(0) { needUpdate(); @@ -591,22 +588,6 @@ namespace Ogre { } //----------------------------------------------------------------------- - void Node::setInitialState(void) - { - mInitialPosition = mPosition; - mInitialOrientation = mOrientation; - mInitialScale = mScale; - } - //----------------------------------------------------------------------- - void Node::resetToInitialState(void) - { - mPosition = mInitialPosition; - mOrientation = mInitialOrientation; - mScale = mInitialScale; - - needUpdate(); - } - //----------------------------------------------------------------------- struct NodeNameExists { const String& name; bool operator()(const Node* mo) { diff --git a/OgreMain/src/OgreSceneManager.cpp b/OgreMain/src/OgreSceneManager.cpp index 335849d7f8e..05a1e96a849 100644 --- a/OgreMain/src/OgreSceneManager.cpp +++ b/OgreMain/src/OgreSceneManager.cpp @@ -2198,8 +2198,7 @@ void SceneManager::_applySceneAnimations(void) // Reset any nodes involved for (const auto& it : anim->_getNodeTrackList()) { - if (Node* nd = it.second->getAssociatedNode()) - nd->resetToInitialState(); + it.second->resetToInitialState(); } for (const auto& it : anim->_getNumericTrackList()) diff --git a/PlugIns/DotScene/src/DotSceneLoader.cpp b/PlugIns/DotScene/src/DotSceneLoader.cpp index 2faabac1e79..f18015f13ee 100644 --- a/PlugIns/DotScene/src/DotSceneLoader.cpp +++ b/PlugIns/DotScene/src/DotSceneLoader.cpp @@ -928,7 +928,7 @@ void DotSceneLoader::processNodeAnimation(pugi::xml_node& XMLNode, SceneNode* pP // create a track to animate the camera's node NodeAnimationTrack* track = anim->createNodeTrack(0, pParent); - pParent->setInitialState(); + track->setInitialState(); // Process keyframes (*) for (auto pElement : XMLNode.children("keyframe"))