Ogre引擎源码——资源之Skeleton
2013-11-23 00:32
239 查看
/article/7856323.html
Ogre中Resouce资源有以下几种类型:Texture、Compositor、Font、GpuProgram、Material、Mesh、Skeleton、BspLevel。
本文聚焦于资源Skeleton,这部分资源是Ogre处理动画的环节。Ogre支持三种动画方式:骨骼动画(Skeletal)、变形动画(Morph)以及姿态动画(Pose)。
相关的头文件如下:
OgreNode.h
OgreBone.h
OgreKeyFrame.h
OgreAnimation.h
OgreAnimationTrack.h
OgreSkeleton.h
OgreSkeletonFileFormat.h
1、OgreNode与OgreBone
Ogre中的骨骼动画,Bone就是相应的骨骼类。在关注这个Bone类之前,我们需要来看下它的父类——Node类。在Ogre场景组织中,Node是一个重要的基类,一个Node对应了场景中的一个组成部分。场景中的所有节点都被组织成一颗结构树,父节点的变换可以影响它相应的子节点。这些基础的变换实现正好符合Bone的需求。
先来看下Node类中重要的数据成员:
[cpp]
view plaincopyprint?
/// Pointer to parent node
Node* mParent;
/// Collection of pointers to direct children; hashmap for efficiency
typedef HashMap<String, Node*> ChildNodeMap;
ChildNodeMap mChildren;
String mName;
/// Stores the orientation of the node relative to it's parent.
Quaternion mOrientation;
/// Stores the position/translation of the node relative to its parent.
Vector3 mPosition;
/// Stores the scaling factor applied to this node
Vector3 mScale;
[cpp]
view plaincopyprint?
/// Pointer to parent node
Node* mParent;
/// Collection of pointers to direct children; hashmap for efficiency
typedef HashMap<String, Node*> ChildNodeMap;
ChildNodeMap mChildren;
String mName;
/// Stores the orientation of the node relative to it's parent.
Quaternion mOrientation;
/// Stores the position/translation of the node relative to its parent.
Vector3 mPosition;
/// Stores the scaling factor applied to this node
Vector3 mScale;
其中儿子节点可以以名字或者索引两种Key形式。
(b)进行变换
[cpp]
view plaincopyprint?
virtual void scale(const Vector3& scale);
virtual void translate(const Vector3& d, TransformSpace relativeTo);
virtual void roll(const Radian& angle, TransformSpace relativeTo);
virtual void pitch(const Radian& angle, TransformSpace relativeTo);
virtual void yaw(const Radian& angle, TransformSpace relativeTo);
virtual void rotate(const Vector3& axis, const Radian& angle, TransformSpace relativeTo);
virtual Matrix3 getLocalAxes(void) const;
[cpp]
view plaincopyprint?
virtual void scale(const Vector3& scale);
virtual void translate(const Vector3& d, TransformSpace relativeTo);
virtual void roll(const Radian& angle, TransformSpace relativeTo);
virtual void pitch(const Radian& angle, TransformSpace relativeTo);
virtual void yaw(const Radian& angle, TransformSpace relativeTo);
virtual void rotate(const Vector3& axis, const Radian& angle, TransformSpace relativeTo);
virtual Matrix3 getLocalAxes(void) const;
这个函数从父类获取(如果有父类的话)变换信息,对自身和子类施加变换操作。
主要的代码片段如下:
[cpp]
view plaincopyprint?
ChildNodeMap::iterator it, itend;
itend = mChildren.end();
for (it = mChildren.begin(); it != itend; ++it)
{
Node* child = it->second;
child->_update(true, true);
}
mChildrenToUpdate.clear();
[cpp]
view plaincopyprint?
ChildNodeMap::iterator it, itend;
itend = mChildren.end();
for (it = mChildren.begin(); it != itend; ++it)
{
Node* child = it->second;
child->_update(true, true);
}
mChildrenToUpdate.clear();
Handle是一个用来标示Bone的值。
Skeleton(后面会介绍)是集中管理Bone的类。所以在Bone中保存了一个指向创建自己的Skeleton指针。
最后的3个变量值是子节点反变换回父节点位置的变换信息。
这些信息是在函数void _getOffsetTransform(Matrix4& m)中用来生成变换矩阵:
[cpp]
view plaincopyprint?
Vector3 scale = _getDerivedScale() * mBindDerivedInverseScale;
Quaternion rotate = _getDerivedOrientation() * mBindDerivedInverseOrientation;
Vector3 translate = _getDerivedPosition() + rotate * (scale * mBindDerivedInversePosition);
m.makeTransform(translate, scale, rotate);
[cpp]
view plaincopyprint?
Vector3 scale = _getDerivedScale() * mBindDerivedInverseScale;
Quaternion rotate = _getDerivedOrientation() * mBindDerivedInverseOrientation;
Vector3 translate = _getDerivedPosition() + rotate * (scale * mBindDerivedInversePosition);
m.makeTransform(translate, scale, rotate);
KeyFrame类的定义就这样简单的几行。它的成员变量只有两个。一个是表示该帧在整个动画轨迹中的时间位置;还有一个就是创建该帧的AnimationTrack类。
KeyFrame类并没有保存每帧需保存的空间变换信息,因为Ogre只是四种不同的关键帧,它们各自有自己需要保存的变换信息,所以在KeyFrame的派生类中可以找到相应的内容。
KeyFrame的四个派生类:
数字关键帧(NumericKeyFrame)
变换关键帧(TransformKeyFrame)
顶点变形关键帧(VertexMorphKeyFrame)
顶点姿态关键帧(VertexPoseKeyFrame)
比如:数字关键帧(NumericKeyFrame)中就保存了相应的数字数据;变换关键帧(TransformKeyFrame)中则保存了变换、缩放和旋转信息等。(这些关键帧会在相应Track里再提到)
在UML图的中央,我们可以看到,KeyFrame类是由AnimationTrack的类负责创建和管理的。KeyFrame的四个子类对应了三种动画轨迹类型(最后两种KeyFrame子类对应同一种AnimationTrack),也就定义了Ogre所支持的三种动画轨迹方式。
先来看下这些动画轨迹的父类AnimationTrack
AnimationTrack的主要成员变量如下:
typedef vector<KeyFrame*>::type KeyFrameList;
KeyFrameList mKeyFrames;
Animation* mParent;
unsigned short mHandle;
[cpp]
view plaincopyprint?
typedef vector<KeyFrame*>::type KeyFrameList;
KeyFrameList mKeyFrames;
Animation* mParent;
unsigned short mHandle;
顶点动画轨迹(VertexAnimationTrack):对应顶点变形关键帧(VertexMorphKeyFrame)和顶点姿态关键帧(VertexPoseKeyFrame),每个关键帧保存了特定时间的顶点位置数据,在姿态动画(Pose)中还保存了顶点混合权重。
两种不同的顶点动画:
变形动画:记录每个关键帧时刻所有顶点的快照集合。
姿态动画:记录所有顶点的偏移,根据不同的权重来融合不同的姿态,来产生最后的结果。在面部动画中,姿态动画应用比较广泛。
现在再来看Animation类就简单很多了:
[cpp]
view plaincopyprint?
/// Node tracks, indexed by handle
NodeTrackList mNodeTrackList;
/// Numeric tracks, indexed by handle
NumericTrackList mNumericTrackList;
/// Vertex tracks, indexed by handle
VertexTrackList mVertexTrackList;
String mName;
Real mLength;
InterpolationMode mInterpolationMode;
RotationInterpolationMode mRotationInterpolationMode;
[cpp]
view plaincopyprint?
/// Node tracks, indexed by handle
NodeTrackList mNodeTrackList;
/// Numeric tracks, indexed by handle
NumericTrackList mNumericTrackList;
/// Vertex tracks, indexed by handle
VertexTrackList mVertexTrackList;
String mName;
Real mLength;
InterpolationMode mInterpolationMode;
RotationInterpolationMode mRotationInterpolationMode;
Skeleton类中较多的成员函数是对这两个列表成员的具体操作,如创建、添加、删除一个Bone或者AnimationList等。
_getAnimation成员函数获取相应的Animation类,然后在setAnimationState函数中将该动画变换附加所有骨骼上。_updateTransforms成员函数的作用是遍历所有Bone,调用每个Bone的update函数进行变换更新。
还有值得一提的是LinkedSkeletonAnimationSource结构,它允许Skeleton类使用其他的Animation类来实现动画。
本文完。
参考内容
网站:
http://www.ogre3d.cn/wiki/index.php?title=%E9%A6%96%E9%A1%B5
http://blog.csdn.net/pizi0475/archive/2010/03/11/5370338.aspx
http://hi.baidu.com/bdruiruili/blog/item/e2024135d351861f90ef399f.html
书籍:PRO OGRE 3D PROGRAMMING
Ogre中Resouce资源有以下几种类型:Texture、Compositor、Font、GpuProgram、Material、Mesh、Skeleton、BspLevel。
本文聚焦于资源Skeleton,这部分资源是Ogre处理动画的环节。Ogre支持三种动画方式:骨骼动画(Skeletal)、变形动画(Morph)以及姿态动画(Pose)。
相关的头文件如下:
OgreNode.h
OgreBone.h
OgreKeyFrame.h
OgreAnimation.h
OgreAnimationTrack.h
OgreSkeleton.h
OgreSkeletonFileFormat.h
1、OgreNode与OgreBone
Ogre中的骨骼动画,Bone就是相应的骨骼类。在关注这个Bone类之前,我们需要来看下它的父类——Node类。在Ogre场景组织中,Node是一个重要的基类,一个Node对应了场景中的一个组成部分。场景中的所有节点都被组织成一颗结构树,父节点的变换可以影响它相应的子节点。这些基础的变换实现正好符合Bone的需求。
先来看下Node类中重要的数据成员:
[cpp]
view plaincopyprint?
/// Pointer to parent node
Node* mParent;
/// Collection of pointers to direct children; hashmap for efficiency
typedef HashMap<String, Node*> ChildNodeMap;
ChildNodeMap mChildren;
String mName;
/// Stores the orientation of the node relative to it's parent.
Quaternion mOrientation;
/// Stores the position/translation of the node relative to its parent.
Vector3 mPosition;
/// Stores the scaling factor applied to this node
Vector3 mScale;
[cpp]
view plaincopyprint?
/// Pointer to parent node
Node* mParent;
/// Collection of pointers to direct children; hashmap for efficiency
typedef HashMap<String, Node*> ChildNodeMap;
ChildNodeMap mChildren;
String mName;
/// Stores the orientation of the node relative to it's parent.
Quaternion mOrientation;
/// Stores the position/translation of the node relative to its parent.
Vector3 mPosition;
/// Stores the scaling factor applied to this node
Vector3 mScale;
[cpp] view plaincopyprint? virtual Node* createChildconst Vector3& translate, const Quaternion& rotate ); virtual void addChild(Node* child); virtual unsigned short numChildren(void) const; virtual Node* removeChild(unsigned short index); virtual Node* removeChild(Node* child); [cpp] view plaincopyprint? virtual Node* createChildconst Vector3& translate, const Quaternion& rotate ); virtual void addChild(Node* child); virtual unsigned short numChildren(void) const; virtual Node* removeChild(unsigned short index); virtual Node* removeChild(Node* child); virtual Node* createChildconst Vector3& translate, const Quaternion& rotate ); virtual void addChild(Node* child); virtual unsigned short numChildren(void) const; virtual Node* removeChild(unsigned short index); virtual Node* removeChild(Node* child);
其中儿子节点可以以名字或者索引两种Key形式。
(b)进行变换
[cpp]
view plaincopyprint?
virtual void scale(const Vector3& scale);
virtual void translate(const Vector3& d, TransformSpace relativeTo);
virtual void roll(const Radian& angle, TransformSpace relativeTo);
virtual void pitch(const Radian& angle, TransformSpace relativeTo);
virtual void yaw(const Radian& angle, TransformSpace relativeTo);
virtual void rotate(const Vector3& axis, const Radian& angle, TransformSpace relativeTo);
virtual Matrix3 getLocalAxes(void) const;
[cpp]
view plaincopyprint?
virtual void scale(const Vector3& scale);
virtual void translate(const Vector3& d, TransformSpace relativeTo);
virtual void roll(const Radian& angle, TransformSpace relativeTo);
virtual void pitch(const Radian& angle, TransformSpace relativeTo);
virtual void yaw(const Radian& angle, TransformSpace relativeTo);
virtual void rotate(const Vector3& axis, const Radian& angle, TransformSpace relativeTo);
virtual Matrix3 getLocalAxes(void) const;
[cpp] view plaincopyprint? virtual void _update(bool updateChildren, bool parentHasChanged); [cpp] view plaincopyprint? virtual void _update(bool updateChildren, bool parentHasChanged); virtual void _update(bool updateChildren, bool parentHasChanged);
这个函数从父类获取(如果有父类的话)变换信息,对自身和子类施加变换操作。
主要的代码片段如下:
[cpp]
view plaincopyprint?
ChildNodeMap::iterator it, itend;
itend = mChildren.end();
for (it = mChildren.begin(); it != itend; ++it)
{
Node* child = it->second;
child->_update(true, true);
}
mChildrenToUpdate.clear();
[cpp]
view plaincopyprint?
ChildNodeMap::iterator it, itend;
itend = mChildren.end();
for (it = mChildren.begin(); it != itend; ++it)
{
Node* child = it->second;
child->_update(true, true);
}
mChildrenToUpdate.clear();
[cpp] view plaincopyprint? /// The numeric handle of this bone unsigned short mHandle; Skeleton* mCreator; /// The inversed derived scale of the bone in the binding pose Vector3 mBindDerivedInverseScale; /// The inversed derived orientation of the bone in the binding pose Quaternion mBindDerivedInverseOrientation; /// The inversed derived position of the bone in the binding pose Vector3 mBindDerivedInversePosition; [cpp] view plaincopyprint? /// The numeric handle of this bone unsigned short mHandle; Skeleton* mCreator; /// The inversed derived scale of the bone in the binding pose Vector3 mBindDerivedInverseScale; /// The inversed derived orientation of the bone in the binding pose Quaternion mBindDerivedInverseOrientation; /// The inversed derived position of the bone in the binding pose Vector3 mBindDerivedInversePosition; /// The numeric handle of this bone unsigned short mHandle; Skeleton* mCreator; /// The inversed derived scale of the bone in the binding pose Vector3 mBindDerivedInverseScale; /// The inversed derived orientation of the bone in the binding pose Quaternion mBindDerivedInverseOrientation; /// The inversed derived position of the bone in the binding pose Vector3 mBindDerivedInversePosition;
Handle是一个用来标示Bone的值。
Skeleton(后面会介绍)是集中管理Bone的类。所以在Bone中保存了一个指向创建自己的Skeleton指针。
最后的3个变量值是子节点反变换回父节点位置的变换信息。
这些信息是在函数void _getOffsetTransform(Matrix4& m)中用来生成变换矩阵:
[cpp]
view plaincopyprint?
Vector3 scale = _getDerivedScale() * mBindDerivedInverseScale;
Quaternion rotate = _getDerivedOrientation() * mBindDerivedInverseOrientation;
Vector3 translate = _getDerivedPosition() + rotate * (scale * mBindDerivedInversePosition);
m.makeTransform(translate, scale, rotate);
[cpp]
view plaincopyprint?
Vector3 scale = _getDerivedScale() * mBindDerivedInverseScale;
Quaternion rotate = _getDerivedOrientation() * mBindDerivedInverseOrientation;
Vector3 translate = _getDerivedPosition() + rotate * (scale * mBindDerivedInversePosition);
m.makeTransform(translate, scale, rotate);
[cpp] view plaincopyprint? class _OgreExport KeyFrame : public AnimationAlloc { public: KeyFrame(const AnimationTrack* parent, Real time); virtual ~KeyFrame() {} Real getTime(void) const { return mTime; } virtual KeyFrame* _clone(AnimationTrack* newParent) const; protected: Real mTime; const AnimationTrack* mParentTrack; }; [cpp] view plaincopyprint? class _OgreExport KeyFrame : public AnimationAlloc { public: KeyFrame(const AnimationTrack* parent, Real time); virtual ~KeyFrame() {} Real getTime(void) const { return mTime; } virtual KeyFrame* _clone(AnimationTrack* newParent) const; protected: Real mTime; const AnimationTrack* mParentTrack; }; class _OgreExport KeyFrame : public AnimationAlloc { public: KeyFrame(const AnimationTrack* parent, Real time); virtual ~KeyFrame() {} Real getTime(void) const { return mTime; } virtual KeyFrame* _clone(AnimationTrack* newParent) const; protected: Real mTime; const AnimationTrack* mParentTrack; };
KeyFrame类的定义就这样简单的几行。它的成员变量只有两个。一个是表示该帧在整个动画轨迹中的时间位置;还有一个就是创建该帧的AnimationTrack类。
KeyFrame类并没有保存每帧需保存的空间变换信息,因为Ogre只是四种不同的关键帧,它们各自有自己需要保存的变换信息,所以在KeyFrame的派生类中可以找到相应的内容。
KeyFrame的四个派生类:
数字关键帧(NumericKeyFrame)
变换关键帧(TransformKeyFrame)
顶点变形关键帧(VertexMorphKeyFrame)
顶点姿态关键帧(VertexPoseKeyFrame)
比如:数字关键帧(NumericKeyFrame)中就保存了相应的数字数据;变换关键帧(TransformKeyFrame)中则保存了变换、缩放和旋转信息等。(这些关键帧会在相应Track里再提到)
在UML图的中央,我们可以看到,KeyFrame类是由AnimationTrack的类负责创建和管理的。KeyFrame的四个子类对应了三种动画轨迹类型(最后两种KeyFrame子类对应同一种AnimationTrack),也就定义了Ogre所支持的三种动画轨迹方式。
先来看下这些动画轨迹的父类AnimationTrack
AnimationTrack的主要成员变量如下:
typedef vector<KeyFrame*>::type KeyFrameList;
KeyFrameList mKeyFrames;
Animation* mParent;
unsigned short mHandle;
[cpp]
view plaincopyprint?
typedef vector<KeyFrame*>::type KeyFrameList;
KeyFrameList mKeyFrames;
Animation* mParent;
unsigned short mHandle;
[cpp] view plaincopyprint? struct Splines { SimpleSpline positionSpline; SimpleSpline scaleSpline; RotationalSpline rotationSpline; }; [cpp] view plaincopyprint? struct Splines { SimpleSpline positionSpline; SimpleSpline scaleSpline; RotationalSpline rotationSpline; }; struct Splines { SimpleSpline positionSpline; SimpleSpline scaleSpline; RotationalSpline rotationSpline; };
顶点动画轨迹(VertexAnimationTrack):对应顶点变形关键帧(VertexMorphKeyFrame)和顶点姿态关键帧(VertexPoseKeyFrame),每个关键帧保存了特定时间的顶点位置数据,在姿态动画(Pose)中还保存了顶点混合权重。
两种不同的顶点动画:
变形动画:记录每个关键帧时刻所有顶点的快照集合。
姿态动画:记录所有顶点的偏移,根据不同的权重来融合不同的姿态,来产生最后的结果。在面部动画中,姿态动画应用比较广泛。
现在再来看Animation类就简单很多了:
[cpp]
view plaincopyprint?
/// Node tracks, indexed by handle
NodeTrackList mNodeTrackList;
/// Numeric tracks, indexed by handle
NumericTrackList mNumericTrackList;
/// Vertex tracks, indexed by handle
VertexTrackList mVertexTrackList;
String mName;
Real mLength;
InterpolationMode mInterpolationMode;
RotationInterpolationMode mRotationInterpolationMode;
[cpp]
view plaincopyprint?
/// Node tracks, indexed by handle
NodeTrackList mNodeTrackList;
/// Numeric tracks, indexed by handle
NumericTrackList mNumericTrackList;
/// Vertex tracks, indexed by handle
VertexTrackList mVertexTrackList;
String mName;
Real mLength;
InterpolationMode mInterpolationMode;
RotationInterpolationMode mRotationInterpolationMode;
[cpp] view plaincopyprint? /// Storage of bones, indexed by bone handle BoneList mBoneList; /// Storage of animations, lookup by name AnimationList mAnimationsList; [cpp] view plaincopyprint? /// Storage of bones, indexed by bone handle BoneList mBoneList; /// Storage of animations, lookup by name AnimationList mAnimationsList; /// Storage of bones, indexed by bone handle BoneList mBoneList; /// Storage of animations, lookup by name AnimationList mAnimationsList;
Skeleton类中较多的成员函数是对这两个列表成员的具体操作,如创建、添加、删除一个Bone或者AnimationList等。
_getAnimation成员函数获取相应的Animation类,然后在setAnimationState函数中将该动画变换附加所有骨骼上。_updateTransforms成员函数的作用是遍历所有Bone,调用每个Bone的update函数进行变换更新。
还有值得一提的是LinkedSkeletonAnimationSource结构,它允许Skeleton类使用其他的Animation类来实现动画。
本文完。
参考内容
网站:
http://www.ogre3d.cn/wiki/index.php?title=%E9%A6%96%E9%A1%B5
http://blog.csdn.net/pizi0475/archive/2010/03/11/5370338.aspx
http://hi.baidu.com/bdruiruili/blog/item/e2024135d351861f90ef399f.html
书籍:PRO OGRE 3D PROGRAMMING
相关文章推荐
- Ogre引擎源码——资源之Skeleton
- Ogre引擎源码——资源之Skeleton
- Ogre引擎源码——资源之Skeleton
- Ogre引擎源码——资源之Material
- Ogre引擎源码——资源之GpuProgram
- Ogre引擎源码——资源之GpuProgram
- Ogre引擎源码——资源之Font
- Ogre引擎源码——资源之Font
- Ogre引擎源码——资源之GpuProgram
- Ogre引擎源码——资源之Font
- ogre 引擎 框架追踪 第五章 资源加载之实加载
- Ogre引擎源码——String
- ogre 引擎 框架追踪 第四章 资源加载之资源组初始化
- 转: 在Ogre中使用Havok物理引擎(源码)
- Ogre引擎源码——场景查询
- Ogre引擎源码——Timer
- Ogre引擎源码——文件管理
- Ogre引擎源码——内存管理 .
- Ogre引擎源码——内存管理
- Ogre引擎源码——文件管理