diff --git a/OgreMain/include/OgreAnimationTrack.h b/OgreMain/include/OgreAnimationTrack.h index dfae92fa677..0424b091fb7 100644 --- a/OgreMain/include/OgreAnimationTrack.h +++ b/OgreMain/include/OgreAnimationTrack.h @@ -34,6 +34,7 @@ THE SOFTWARE. #include "OgreSimpleSpline.h" #include "OgreRotationalSpline.h" #include "OgrePose.h" +#include "OgreNode.h" namespace Ogre { @@ -339,6 +340,16 @@ namespace Ogre /** Gets the method of rotation calculation */ virtual bool getUseShortestRotationPath() const; + /** Sets the space that this track's transformations are relative to. + Default is TS_PARENT. + NB with TS_LOCAL only one animation at a time can transform + the same Node and the translations and rotations will be done in + the Node's local space established by the call to setInitialState(). */ + virtual void setTransformSpace(Node::TransformSpace space); + + /** Gets the space that this track's transformations are relative to. */ + virtual Node::TransformSpace getTransformSpace() const; + /// @copydoc AnimationTrack::getInterpolatedKeyFrame void getInterpolatedKeyFrame(const TimeIndex& timeIndex, KeyFrame* kf) const override; @@ -383,6 +394,8 @@ namespace Ogre mutable bool mSplineBuildNeeded; /// Defines if rotation is done using shortest path mutable bool mUseShortestRotationPath; + /// Which space our transformations are relative to. + Node::TransformSpace mTransformSpace; Node* mTargetNode; // Prebuilt splines, must be mutable since lazy-update in const method mutable Splines* mSplines; diff --git a/OgreMain/src/OgreAnimationTrack.cpp b/OgreMain/src/OgreAnimationTrack.cpp index 1affd11d193..3c984d646f8 100644 --- a/OgreMain/src/OgreAnimationTrack.cpp +++ b/OgreMain/src/OgreAnimationTrack.cpp @@ -363,8 +363,8 @@ namespace Ogre { } //--------------------------------------------------------------------- NodeAnimationTrack::NodeAnimationTrack(Animation* parent, unsigned short handle, Node* targetNode) - : AnimationTrack(parent, handle), mSplineBuildNeeded(false), mUseShortestRotationPath(true), - mTargetNode(targetNode), mSplines(0) + : AnimationTrack(parent, handle), mSplineBuildNeeded(false), mUseShortestRotationPath(true) + , mTransformSpace(Node::TS_PARENT), mTargetNode(targetNode), mSplines(0) { } @@ -486,7 +486,7 @@ namespace Ogre { // add to existing. Weights are not relative, but treated as absolute multipliers for the animation Vector3 translate = kf.getTranslate() * weight * scl; - node->translate(translate); + node->translate(translate, mTransformSpace); // interpolate between no-rotation and full rotation, to point 'weight', so 0 = no rotate, 1 = full Quaternion rotate; @@ -500,7 +500,7 @@ namespace Ogre { { rotate = Quaternion::Slerp(weight, Quaternion::IDENTITY, kf.getRotation(), mUseShortestRotationPath); } - node->rotate(rotate); + node->rotate(rotate, mTransformSpace); Vector3 scale = kf.getScale(); // Not sure how to modify scale for cumulative anims... leave it alone @@ -566,6 +566,16 @@ namespace Ogre { return mUseShortestRotationPath ; } //--------------------------------------------------------------------- + void NodeAnimationTrack::setTransformSpace(Node::TransformSpace space) + { + mTransformSpace = space; + } + //--------------------------------------------------------------------- + Node::TransformSpace NodeAnimationTrack::getTransformSpace() const + { + return mTransformSpace; + } + //--------------------------------------------------------------------- void NodeAnimationTrack::_keyFrameDataChanged(void) const { mSplineBuildNeeded = true; @@ -670,6 +680,7 @@ namespace Ogre { NodeAnimationTrack* newTrack = newParent->createNodeTrack(mHandle, mTargetNode); newTrack->mUseShortestRotationPath = mUseShortestRotationPath; + newTrack->mTransformSpace = mTransformSpace; populateClone(newTrack); return newTrack; }