Ogre::Animation相关类

Ogre实现动画的基本原理是:通过多个关键帧(KeyFrame)组成一个动画轨迹(AnimationTrack),多个动画轨迹组成一个动画。在各个关键帧之间通过插值算法(Spline插值或者线性插值)进行插值来生成最终的动画。一个动画不仅仅包含关键帧,还有其它的一些属性(动画名、动画长度、动画的权重、是否被启用等等)。一个动画轨迹可以指定其控制的节点。

OGRE中与基本动画相关的类

根据动画原理我们可以抽象出下面的几个类(动画状态\动画类\动画轨迹(由关键帧、简单插值和角度插值组成):

Ogre::Animation相关类_第1张图片


SimpleSpline与RotationSpline类:

实现了样条的插值算法。SimpleSpline用来对Translate和Scale进行插值,RotationSpline用来对Rotation进行插值。

关键帧(KeyFrame)类:

组成动画最基本的元素,一个动画轨迹里面有多个关键帧,每个关键帧具有自己的位置、缩放比例和旋转角,同时每个关键帧还保存有自己在整个动画轨迹里所处的时间点。在实际运行时,根据当前时间,通过对两个关键帧的插值可以得到当前帧(当前位置、缩放比例和旋转角)。随着时间的变化,插值得到的当前帧也是变化的,动画就产生了。由于关键帧包括位置信息、缩放比例信息和旋转信息,所以可以实现运动动画、缩放动画和旋转动画以及混合动画。

通过观察下面的代码明显可以看出,Ogre中大量使用工厂模式的痕迹,用KeyFrame为基类,继承产生了以下的不同用途的五个关键帧类:

 

1. 关键帧类(KeyFrame类,所有下面的关键帧类的基础类):

 

[html]  view plain copy print ?
  1. class_OgreExport KeyFrame : public AnimationAlloc  
  2.   
  3. { //关键帧类  
  4.   
  5. public:  
  6.   
  7. KeyFrame(const AnimationTrack* parent, Real time);  
  8. //构造函数,应该是被AnimationTrack类的createKeyFrame方法来调用而不是直接产生的virtual ~KeyFrame() {}  
  9.   
  10. Real getTime(void)const { return mTime; }  
  11.   
  12. virtual KeyFrame* _clone(AnimationTrack* newParent)const;  
  13.   
  14. protected: //--------------------------一个关键帧中有时间(在动作轨迹中)和其所属的动作序列的指针  
  15.   
  16. Real mTime;  
  17.   
  18. const AnimationTrack* mParentTrack;  
  19.   
  20. };   

 

2. 数值关键帧类(MunmericKeyFrame类,里面存储了数值)

 
[html]  view plain copy print ?
  1. class_OgreExport NumericKeyFrame :public KeyFrame  
  2.   
  3. {//------------------------数值关键帧类,里面存储了数值  
  4.   
  5. public:        
  6.   
  7. NumericKeyFrame(const AnimationTrack* parent, Real time);  
  8.   
  9. ~NumericKeyFrame() {}  
  10.   
  11. virtualconst AnyNumeric& getValue(void)const;  
  12.   
  13. virtualvoid setValue(const AnyNumeric& val);  
  14.   
  15. KeyFrame* _clone(AnimationTrack* newParent)const;  
  16.   
  17. protected:  
  18.   
  19. AnyNumeric mValue;  
  20.   
  21. };  

 

3. 变换关键帧类(TransformKeyFrame):其中存储了一个完整的该帧的数学变换

  

[html]  view plain copy print ?
  1. class _OgreExport TransformKeyFrame :public KeyFrame  
  2.   
  3. {//变换关键帧:其中存储了一个完整的帧变换  
  4.   
  5. public:  
  6.   
  7. TransformKeyFrame(const AnimationTrack* parent, Real time);  
  8.   
  9. ~TransformKeyFrame() {}  
  10.   
  11. virtualvoid setTranslate(const Vector3& trans);  
  12.   
  13. //-----------------设置这个帧中的平移变换(用一个三维向量表示  
  14.   
  15. const Vector3& getTranslate(void)const;  
  16.   
  17. virtualvoid setScale(const Vector3& scale);  
  18.   
  19. //----------------用三维向量表示的此帧的缩放  
  20.   
  21. virtualconst Vector3& getScale(void)const;  
  22.   
  23. virtualvoid setRotation(const Quaternion& rot);  
  24.   
  25. //-----------------用四元数表示的此帧的旋转  
  26.   
  27. virtualconst Quaternion& getRotation(void)const;  
  28.   
  29. KeyFrame* _clone(AnimationTrack* newParent)const;  
  30.   
  31. protected:  
  32.   
  33. Vector3 mTranslate;  
  34.   
  35. Vector3 mScale;  
  36.   
  37. Quaternion mRotate;  
  38.   
  39. };  

4. 点Morph关键帧类:存储了在一个完整缓存中点的绝对位置

[html]  view plain copy print ?
  1. class _OgreExport VertexMorphKeyFrame :public KeyFrame  
  2.   
  3. { //点morph关键帧:存储了在一个完整缓存中点的绝对位置,用来在相同的动作轨迹中进行插值。  
  4.   
  5. public:  
  6.   
  7. VertexMorphKeyFrame(const AnimationTrack* parent, Real time);  
  8.   
  9. ~VertexMorphKeyFrame() {}  
  10.   
  11. void setVertexBuffer(const HardwareVertexBufferSharedPtr& buf);  
  12.   
  13. //为当前帧设置点缓存,我们假设在位置来源中的前3个位置是这帧的位置  
  14.   
  15. const HardwareVertexBufferSharedPtr& getVertexBuffer(void)const;  
  16.   
  17. KeyFrame* _clone(AnimationTrack* newParent)const;   
  18.   
  19. protected:  
  20.   
  21. HardwareVertexBufferSharedPtr mBuffer;  
  22.   
  23. };  


5. 动作点关键帧类:在使用Mesh的情况下存储vertex偏移量

[html]  view plain copy print ?
  1. class _OgreExport VertexPoseKeyFrame :public KeyFrame  
  2.   
  3. {//点位置帧:因为使用mesh产生的动作,其内部存储了指定的影响级别(大概是mesh受点位置变化的影响程度)下该帧的偏移  
  4.   
  5. public:  
  6.   
  7. VertexPoseKeyFrame(const AnimationTrack* parent, Real time);  
  8.   
  9. ~VertexPoseKeyFrame() {}  
  10.   
  11. struct PoseRef//----------------参考的动作  
  12.   
  13. {  
  14.   
  15. ushort poseIndex;  
  16.   
  17. //------------------------动作索引(短整型)  
  18.   
  19. Real influence;  
  20.   
  21. PoseRef(ushort p, Real i) : poseIndex(p), influence(i) {}  
  22.   
  23. };  
  24.   
  25. typedef vector<PoseRef>::type PoseRefList;  
  26.   
  27. void addPoseReference(ushort poseIndex, Real influence);  
  28.   
  29. void updatePoseReference(ushort poseIndex, Real influence);  
  30.   
  31. void removePoseReference(ushort poseIndex);  
  32.   
  33. void removeAllPoseReferences(void);  
  34.   
  35. const PoseRefList& getPoseReferences(void)const;  
  36.   
  37. typedef VectorIterator<PoseRefList> PoseRefIterator;  
  38.   
  39. typedef ConstVectorIterator<PoseRefList> ConstPoseRefIterator;  
  40.   
  41. PoseRefIterator getPoseReferenceIterator(void);  
  42.   
  43. ConstPoseRefIterator getPoseReferenceIterator(void)const;  
  44.   
  45. KeyFrame* _clone(AnimationTrack* newParent) const;  
  46.   
  47. protected:  
  48.   
  49. PoseRefList mPoseRefs;  
  50.   
  51. };  


PS:以上关键帧的创建均通过AnimationTrack::createKeyFrame()来完成,由此看继承机制真是个好东西

 

动画轨迹(AnimationTrack)类

 

动画轨迹由多个关键帧组成,负责对响铃的两个关键帧之间插值。

每个动画轨迹保存关键帧列表、本动画轨迹所属的动画(Animation)、本动画轨迹所控制的Node,又由于动画轨迹负责关键帧的插值,所以它保存SimpleSpline的(简单样条插值计算器)和RotationSpline(旋转样条插值计算器)对象以实现其插值功能。

一个动画轨迹可以对一个物体产生作用,使物体按照动画轨迹运动。这个物体可以是一个Node(一块骨头或者场景中的一个接点)。如有骨头受动画轨迹控制,可以实现骨骼动画.如果场景节点受到动画轨迹控制,可以直接实现场景节点的动画运动。

重要函数:

1) 创建一个关键帧,传入这一帧所在的时间点:

KeyFrame *createKeyFrame(Real timePos);

2) 根据当前时间,得到插值计算出来的当前帧

KeyFrame getInterpolatedKeyFrame(Real timeIndex)const

3) 使用当前动画轨迹对其控制的节点产生作用,参数是当前时间点、权重和是否累计权重

Void apply(Real timePos,Real weight=1.0,bool accumulate=false)

主要构成类:

构成方式和KeyFrame类如出一辙,即使用了动画轨迹(AnimationTrack)类作为基类,构造了如下的几个类:

 

A.动作轨迹(AnimationTrack)类:一个“轨迹“是指一个动作序列,因为最普通的可动作物体是节点Node,所以当”apply“方法被使用的时候会自动的实现帧的更新

 
[html]  view plain copy print ?
  1. class_OgreExport AnimationTrack :public AnimationAlloc  
  2.   
  3. {//-----------------一个“轨迹”是指一个动作序列,因为最普遍的可动作物体是节点Node,所以当“apply”方法被使用的时候会自动的实现帧的更新  
  4.   
  5. public:  
  6.   
  7. class _OgreExport Listener  
  8.   
  9. { //----------------------------监听类,使用这个类可以允许你重写一个确定的运动轨迹  
  10.   
  11. public:  
  12.   
  13. virtual ~Listener() {}  
  14.   
  15. virtualbool getInterpolatedKeyFrame(const AnimationTrack* t,const TimeIndex& timeIndex, KeyFrame* kf) = 0;  
  16.   
  17. };  
  18.   
  19. /// Constructor  
  20.   
  21. AnimationTrack(Animation* parent,unsigned short handle);  
  22.   
  23. virtual ~AnimationTrack();  
  24.   
  25. unsignedshort getHandle(void)const { return mHandle; }  
  26.   
  27. //得到轨迹相关的句柄  
  28.   
  29. virtualunsigned short getNumKeyFrames(void)const;  
  30.   
  31. //得到这个动作轨迹中的帧数  
  32.   
  33. virtual KeyFrame* getKeyFrame(unsignedshort index) const;  
  34.   
  35. //通过特定索引来得到动画中的帧  
  36.   
  37. virtual Real getKeyFramesAtTime(const TimeIndex& timeIndex, KeyFrame** keyFrame1, KeyFrame** keyFrame2,  
  38.   
  39. unsignedshort* firstKeyIndex = 0) const;  
  40.   
  41. //-------------------------------返回介于KeyFrame1和KeyFrame2之间的帧,timeIndex是用于两帧之间时间标记,keyFrame1和KeyFrame2分别是用来构造新帧的帧模板,最后一个参数指向了形成的帧  
  42.   
  43. virtual KeyFrame* createKeyFrame(Real timePos);  
  44.   
  45. virtualvoid removeKeyFrame(unsignedshort index);  
  46.   
  47. virtual void removeAllKeyFrames(void);  
  48.   
  49. virtualvoid getInterpolatedKeyFrame(const TimeIndex& timeIndex, KeyFrame* kf)const = 0;  
  50.   
  51. //得到在timeIndex上的插值帧  
  52.   
  53. virtualvoid apply(const TimeIndex& timeIndex, Real weight = 1.0, Real scale = 1.0f) = 0;  
  54.   
  55. //-----------------在特定的目标上面使用该动作轨迹        
  56.   
  57. virtual void _keyFrameDataChanged(void) const {}  
  58.   
  59.   //-------------------告知关键帧已经改变  
  60.   
  61. virtualbool hasNonZeroKeyFrames(void)const { return true; }  
  62.   
  63. //-------------------使用这个函数来说明是否这个序列中有可用帧  
  64.   
  65. virtualvoid optimise(void) {}  
  66.   
  67. virtualvoid _collectKeyFrameTimes(vector<Real>::type& keyFrameTimes);  
  68.   
  69. //----------------使用一个关键帧时间序列来定义特殊的帧轨迹  
  70.   
  71. virtualvoid _buildKeyFrameIndexMap(const vector<Real>::type& keyFrameTimes);  
  72.   
  73. //----------------通过定义一个关键帧时间序列来完成关键帧映射动画的建立  
  74.   
  75. virtualvoid setListener(Listener* l) { mListener = l; }  
  76.   
  77. Animation *getParent() const { return mParent; }  
  78.   
  79.    
  80.   
  81. protected:  
  82.   
  83. typedef vector<KeyFrame*>::type KeyFrameList;  
  84.   
  85. KeyFrameList mKeyFrames;  
  86.   
  87. Animation* mParent;  
  88.   
  89. unsignedshort mHandle;  
  90.   
  91. Listener* mListener;  
  92.   
  93. /// Map used to translate global keyframe time lower bound index to local lower bound index  
  94.   
  95. typedef vector<ushort>::type KeyFrameIndexMap;  
  96.   
  97. KeyFrameIndexMap mKeyFrameIndexMap;  
  98.   
  99. /// Create a keyframe implementation - must be overridden  
  100.   
  101. virtual KeyFrame* createKeyFrameImpl(Real time) = 0;  
  102.   
  103. /// Internal method for clone implementation  
  104.   
  105. virtualvoid populateClone(AnimationTrack* clone) const;  
  106.   
  107. };  

 

B. 数值动作轨迹(NumericAnimationTrack)类:通过处理一般的动作数值来完成动作轨迹的建立(由上面提到的数值关键帧(NumeraicKeyFrame)来构成)

 

[html]  view plain copy print ?
  1. class_OgreExport NumericAnimationTrack :public AnimationTrack  
  2.   
  3. { //数值动作轨迹:通过处理一般的动作数值来完成动作轨迹的建立  
  4.   
  5. public:  
  6.   
  7. /// Constructor  
  8.   
  9. NumericAnimationTrack(Animation* parent,unsigned short handle);  
  10.   
  11. /// Constructor, associates with an AnimableValue  
  12.   
  13. NumericAnimationTrack(Animation* parent,unsigned short handle,  
  14.   
  15. AnimableValuePtr& target);  
  16.   
  17. virtual NumericKeyFrame* createNumericKeyFrame(Real timePos);  
  18.   
  19. //由数值关键帧构成  
  20.   
  21. /// @copydoc AnimationTrack::getInterpolatedKeyFrame  
  22.   
  23. virtualvoid getInterpolatedKeyFrame(const TimeIndex& timeIndex, KeyFrame* kf)const;  
  24.   
  25. /// @copydoc AnimationTrack::apply  
  26.   
  27. virtualvoid apply(const TimeIndex& timeIndex, Real weight = 1.0, Real scale = 1.0f);  
  28.   
  29. void applyToAnimable(const AnimableValuePtr& anim,const TimeIndex& timeIndex,Real weight = 1.0, Real scale = 1.0f);        
  30.   
  31. virtual const AnimableValuePtr& getAssociatedAnimable(void)const;  
  32.   
  33. virtualvoid setAssociatedAnimable(const AnimableValuePtr& val);  
  34.   
  35. NumericKeyFrame* getNumericKeyFrame(unsignedshort index) const;  
  36.   
  37. NumericAnimationTrack* _clone(Animation* newParent)const;  
  38.   
  39.    
  40.   
  41. protected:  
  42.   
  43. /// Target to animate  
  44.   
  45. AnimableValuePtr mTargetAnim;  
  46.   
  47. /// @copydoc AnimationTrack::createKeyFrameImpl  
  48.   
  49. KeyFrame* createKeyFrameImpl(Real time);  
  50.   
  51. };  

C. 节点动作轨迹(NodeAnimationTrack)类:主要是处理以节点为目标帧变换

 

[html]  view plain copy print ?
  1. class_OgreExport NodeAnimationTrack :public AnimationTrack  
  2.   
  3. { //---------------------结点动作轨迹  
  4.   
  5. public:  
  6.   
  7. /// Constructor  
  8.   
  9. NodeAnimationTrack(Animation* parent,unsigned short handle);  
  10.   
  11. /// Constructor, associates with a Node  
  12.   
  13. NodeAnimationTrack(Animation* parent,unsigned short handle,  
  14.   
  15. Node* targetNode);  
  16.   
  17. /// Destructor  
  18.   
  19. virtual ~NodeAnimationTrack();  
  20.   
  21. virtual TransformKeyFrame* createNodeKeyFrame(Real timePos);  
  22.   
  23. virtual Node* getAssociatedNode(void)const;  
  24.   
  25. virtualvoid setAssociatedNode(Node* node);  
  26.   
  27. virtualvoid applyToNode(Node* node, const TimeIndex& timeIndex, Real weight = 1.0,Real scale = 1.0f);  
  28.   
  29. virtualvoid setUseShortestRotationPath(bool useShortestPath);  
  30.   
  31. virtualbool getUseShortestRotationPath() const;  
  32.   
  33. /// @copydoc AnimationTrack::getInterpolatedKeyFrame  
  34.   
  35. virtualvoid getInterpolatedKeyFrame(const TimeIndex& timeIndex, KeyFrame* kf)const;  
  36.   
  37. /// @copydoc AnimationTrack::apply  
  38.   
  39. virtualvoid apply(const TimeIndex& timeIndex, Real weight = 1.0, Real scale = 1.0f);  
  40.   
  41. /// @copydoc AnimationTrack::_keyFrameDataChanged  
  42.   
  43. void _keyFrameDataChanged(void)const;  
  44.   
  45. virtual TransformKeyFrame* getNodeKeyFrame(unsignedshort index) const;  
  46.   
  47. virtualbool hasNonZeroKeyFrames(void)const;  
  48.   
  49. virtualvoid optimise(void);  
  50.   
  51. NodeAnimationTrack* _clone(Animation* newParent)const;  
  52.   
  53. protected:  
  54.   
  55. /// Specialised keyframe creation  
  56.   
  57. KeyFrame* createKeyFrameImpl(Real time);  
  58.   
  59. // Flag indicating we need to rebuild the splines next time  
  60.   
  61. virtualvoid buildInterpolationSplines(void)const;  
  62.   
  63. // Struct for store splines, allocate on demand for better memory footprint  
  64.   
  65. struct Splines//里面保存了修改器  
  66.   
  67. {  
  68.   
  69.   SimpleSpline positionSpline;  
  70.   
  71.   SimpleSpline scaleSpline;  
  72.   
  73.   RotationalSpline rotationSpline;  
  74.   
  75. };  
  76.   
  77.   
  78.   
  79. Node* mTargetNode;  
  80.   
  81. // Prebuilt splines, must be mutable since lazy-update in const method  
  82.   
  83. mutable Splines* mSplines;  
  84.   
  85. mutablebool mSplineBuildNeeded;  
  86.   
  87. /// Defines if rotation is done using shortest path  
  88.   
  89. mutablebool mUseShortestRotationPath ;  
  90.   
  91. };  

D. 顶点动作轨迹(VertexAnimationTrack)类:用来处理变化顶点信息的类

 
[html]  view plain copy print ?
  1. class_OgreExport VertexAnimationTrack :public AnimationTrack  
  2.   
  3. {//----------------------------顶点动作轨迹  
  4.   
  5. public:  
  6.   
  7. enum TargetMode  
  8.   
  9. {  
  10.   
  11. /// Interpolate vertex positions in software  
  12.   
  13. TM_SOFTWARE,  
  14.   
  15. TM_HARDWARE  
  16.   
  17. };  
  18.   
  19. /// Constructor  
  20.   
  21. VertexAnimationTrack(Animation* parent,unsigned short handle, VertexAnimationType animType);  
  22.   
  23. /// Constructor, associates with target VertexData and temp buffer (for software)  
  24.   
  25. VertexAnimationTrack(Animation* parent,unsigned short handle, VertexAnimationType animType,  
  26.   
  27. VertexData* targetData, TargetMode target = TM_SOFTWARE);  
  28.   
  29. VertexAnimationType getAnimationType(void)const { return mAnimationType; }  
  30.   
  31. virtual VertexMorphKeyFrame* createVertexMorphKeyFrame(Real timePos);  
  32.   
  33. virtual VertexPoseKeyFrame* createVertexPoseKeyFrame(Real timePos);  
  34.   
  35. virtualvoid getInterpolatedKeyFrame(const TimeIndex& timeIndex, KeyFrame* kf)const  
  36.   
  37. { (void)timeIndex; (void)kf; }  
  38.   
  39.   
  40.   
  41. /// @copydoc AnimationTrack::apply  
  42.   
  43. virtualvoid apply(const TimeIndex& timeIndex, Real weight = 1.0, Real scale = 1.0f);  
  44.   
  45. virtualvoid applyToVertexData(VertexData* data,  
  46.   
  47. const TimeIndex& timeIndex, Real weight = 1.0,  
  48.   
  49. const PoseList* poseList = 0);  
  50.   
  51.   
  52.   
  53. VertexMorphKeyFrame* getVertexMorphKeyFrame(unsignedshort index) const;  
  54.   
  55. VertexPoseKeyFrame* getVertexPoseKeyFrame(unsignedshort index) const;  
  56.   
  57. void setAssociatedVertexData(VertexData* data) { mTargetVertexData = data; }  
  58.   
  59. VertexData* getAssociatedVertexData(void)const { return mTargetVertexData; }  
  60.   
  61.   
  62.   
  63. /// Set the target mode  
  64.   
  65. void setTargetMode(TargetMode m) { mTargetMode = m; }  
  66.   
  67. /// Get the target mode  
  68.   
  69. TargetMode getTargetMode(void)const { return mTargetMode; }  
  70.   
  71. virtualbool hasNonZeroKeyFrames(void)const;  
  72.   
  73. virtualvoid optimise(void);  
  74.   
  75. VertexAnimationTrack* _clone(Animation* newParent)const;  
  76.   
  77.   
  78.   
  79. protected:  
  80.   
  81. /// Animation type  
  82.   
  83. VertexAnimationType mAnimationType;  
  84.   
  85.   /// Target to animate  
  86.   
  87. VertexData* mTargetVertexData;  
  88.   
  89. /// Mode to apply  
  90.   
  91. TargetMode mTargetMode;  
  92.   
  93.   
  94.   
  95. /// @copydoc AnimationTrack::createKeyFrameImpl  
  96.   
  97. KeyFrame* createKeyFrameImpl(Real time);  
  98.   
  99. /// Utility method for applying pose animation  
  100.   
  101. void applyPoseToVertexData(const Pose* pose, VertexData* data, Real influence);  
  102.   
  103. };  

 

 

动画类(Animation)

 

一个动画由多个动画轨迹(AnimationTrack)组成,而一个动画轨迹可以控制一个节点,这样一个动画可以使得多个节点沿着自己的轨迹运动。

设想一下一个人的行走动画,人身上的关节点都沿着自己的轨迹运动,如果把两个关节点连接起来,就形成骨头,再让表面的网格受骨头影响而运动,骨骼动画的基础就有了!

每个动画保存子阿吉的AnimationTrack列表,保存动画名称和长度(时间)。

重要函数

1) 设置关键帧间的插值方式。参数IM_LNEAR代表线性插值、IM_SPLINE代表样条插值;

Void setInterpolationMode(InterpolationMode im)

2) 创建一个动画轨迹,第一个参数是这个动画轨迹的唯一标识,第二个参数指定应用这个动画轨迹的节点

AnimationTrack *createTrack(unsigned shor handle,Node *node);

3) 使得当前动画对其控制的节点产生作用(委托AnimationTrack进行),参数是当前时间点、权重和是否累计权重。

Void apply(Real timePos,Real weight=1.0,bool accumulate=false)

(具体的各种函数可以在OgreAnimation.h中看到)

动画状态类(AnimationState)

一个动画状态类的对象对应一个动画类的对象,看上面的类图,AnimationState的数据成员mAnimationNameAnimation类的数据成员没Name是相对应的,它保存相应动画的状态。

动画状态包括动画名、当前时间点,动画长度(总时间)、动画权重和动画的Enable开关

重要函数

1) 设置动画是否可用

Void setEnabled(bool enabled);

2) 移动当前时间点,让动画状态在动画时间线上向前移动,参数为移动量。

Void addTime(Real offset) 

场景管理器(SceneManager)类: 

场景管理器负责动画和动画状态的创建于维护,在场景管理器中保存有没AnimationList(动画列表)和没Animation(动画状态列表),其中每个动画和动画状态通过名字一一对应。

场景管理器中有一个很重要的方法_applySceneAnimations.在每次渲染时(_renderScene函数里)都会被调用(自动调用不需要程序员控制),它的任务是在每一帧渲染之前根据动画状态更新动画,完成动作。_applySceneAnimation方法遍历全部的动画状态,并根据这些状态找出与之一一对应的动画。再找出每个动画中的全部动画轨迹,在每个轨迹里都保存有该轨迹控制的节点。_applySceneAnimations方法首先将这些被动画控制额节点都还原为初始状态,而后载调用动画的apply方法将全部节点更新到新的位置、大小或者方向,从而使得动画向前进行。

重要函数

1) 创建动画Animation,参数为动画名和长度(时间)

Virtual Animation *createAnimation(const string &name,Real length)

2) 创建动画状态AnimationState,参数是与动画对应的名称

Virtual AnimationState *createAnimationState(const String&animationName)

Ogre的骨骼动画: 

骨骼动画用骨架(由一系列骨头构成的继承体系)来单独保存动作信息,这样就将动作信息与网络、皮肤信息分割成两种数据结构分别进行处理,从而比以往的动画技术效率更高。每块骨头都有自己的位置和旋转方向,这些骨头以树的形式组织起来构成骨骼。例如:腕关节是肘关节的子节点,肘关节又是肩关节的子节点。肩关节旋转会自动带动肘关节运动,腕关节同样也会运动。

怎样使得一个网格产生动作效果?我们可以使网格上的每个顶点都对应于一块或多块骨头,当这些骨头移动时便会影响网格的位置。如果一个点与多块骨头关联,则必须通过指定权重类决定每块骨头对此顶点的影响程度(一个顶点对应一块骨头的时候,该点的权重为1.0)。

与关键帧动画相比,使用骨骼动画有很多优点。首先,骨骼动画需要保存的动作数据量非常小。其次,通过指定不同的权重,可以很容易的将多个动作绑定在一起形成新的动作。还可以实现动作键的平滑过渡等等。

当然骨骼动画的实现中,骨骼本身的运动还是需要关键帧来完成,但是信息量已经很小了。

        Ogre骨骼信息和动画信息保存到后缀名为.skeleton的文件中,你可以通过OGRE提供的导出插件工具(Milkshape和3Dmax的exporter)来导出该类型的文件。当你创建基于Mesh文件的Entity的时候,.skeleton文件将会自动被系统加载进来。为了操作方便,Entity自动给每一个动作指定一个AnimationState类对象,可以通过Entity::getAnimationState函数来得到具体的动作。


上文来自:http://blog.csdn.net/kuangfengwu/article/details/7896841

你可能感兴趣的:(C++,c,动画,OGRE)