OGRE 1.8 Animation ,动画部分

本系列文章认为你懂得C++ stl的设计概念和设计模式,当然c++你要是压根不会就直接闪人吧。懂点boost最好,Ogre也用了这个。计算机图形学怎么说也得懂点吧?要不然四元数都够你郁闷的了。mesh,material,light,camera,bone,skeleton等这些3d玩意默认你是懂了啊。不懂的话,可以啃图形学,Opengl红宝书,或者是Ogre的tutorial都行。

本文的组织方法,上半部分为功能性头文件,下半部分为基础头文件(与具体功能无关,例如数据结构)。由于每个头文件都包含一些其他的头文件,而这部分头文件在上半部分和下半部分都可能出现,没办法严格区分。所以本文遵守一个原则:上半部分出现的基础头文件只进行第一层解释(即不具体解释包含中的包含),下半部分将针对每个基础头文件进行详细解释(由于一层基础头文件已经在上半部分进行了解释,下半部分主要解释往下层的深入探讨,对于已经解释了的只做简单的引用。没有特殊需求,读者不需要读下半部分)。上下部分的关联通过头文件名之后的序号来联系。例如【1】对应下半部分的【1】,也是第1个。

本文在介绍一个子模块的时候,尽量不交叉到另外一个模块的知识,尽量独立的介绍,实在是用到就形容一下,讲明白本部分的道理才是王道,另外的部分让另外的部分讲明白去。

另外,Ogre的设计模式用的很严重,这对于开源程序和增量开发是Very好的,设计模式的核心在于接口编程,在讨论设计问题时就可以忽略具体的实现。本文的原理介绍就是这样做的。只拿一般的Abstract接口来说事。例如关键帧(KeyFrame),有好多种关键帧(Numeric,Transform,Vertex),但是宏观原理上只需要知道那玩意是个KeyFrame就行了,管那么多干嘛。管得越多越不明白。按照敏捷开发的思路,咱该从宏观到具体,从粗到细嘛~~~~

OgreMain.h

Ogre.h  这个文件包含了所有创建应用程序会使用到的头文件。也就是说懒人可以直接包含这一个头文件就可以开发了。这个文件也显示了整个Ogre系统的对外接口。由于只包含了部分头文件,每个头文件都是某个子系统的入口,可以从这里切入对每个子系统进行分析。以下的排序也是根据此文件的顺序。

以下,每个红色头文件都是OgreMain.h中包含的主要头文件。注意红头文件之间也有包含关系,被包含的字体会稍微小一些。

OgrePrerequisites.h【1】

1.定义基本数据类型:Real,uchar,ushort,uint,ulong,和高级数据string,stl container。别奇怪人家干嘛把这些玩意重新定义,用原本的不行?行是行,人家自己房子,肯定要用自己的转头搭,但是这个转头可以和别人的砖头一样,但是我给它个我自己起的名字,用着方便,想着舒心。也就方便在别人的砖头的基础上稍加修改了。

2.包含了OgreStdHeaders.h,该头文件包含所有的标准头文件(cstdlib,vector等std头文件)

3。包含了OgreMemoryAllocatorConfig.h,此文件配置内存分配器(Allocator),您知道C++ stl也有个Allocator概念,这是接口编程和设计模式的特色,内存分配独立实现。总之,这玩意负责Ogre各个对象的内存分配和释放。


OgreAnimation.h

1.定义了Animation类和。动画种类万万千(砍人,跑步,做俯卧撑。。),一个Animation类就是一个动画。

2.定义了AnimationContainer,用来放一系列动画。例如一个机器人不但可以跑步,还可以砍人,还可以做俯卧撑。

3.包含了OgreString.h ,该头文件定义了作用于String上的操作,类似于C++的cstring头文件里定义的操作。【2】

4.包含了OgreInteratorWrappers.h,封装了Vector,map,range这三个container【3】

5.包含了OgreAnimable.h

这个文件要从Ogre动画的种类说起了,包含4种:Skeletal Animation, Vertex Animation, SceneNode Animation, Numeric Animatio。 前三种有点3D基础的都容易理解:骨骼动画(把顶点绑定到骨骼),顶点动画(移动顶点实现动画),场景动画(移动摄像头实现动画),第四种呢?前三种,动必须要有能动的东西,它们分别是骨骼,顶点,和摄像头。第四种是用来开发动画插件的,表示能动的其他东西组成的动画,这个能动的其它东西必须满足的条件就是Animable,看,多形象。也就是说,你不开发Animation插件的话,让Animable见鬼去吧。

这个文件包含了OgrePrerequisites.h【1】,OgreVector2.h,OgreVector3.h, OgreVector4.h【4】, OgreQuaternion.h【6】, OgreColorValue.h【7】, OgreSharedPtr.h【8】, OgreStringVector.h【9】, OgreException.h【10】,OgreAny.h【11】

6.包含了OgreAnimationTrack.h

这个头文件包含了OgrePrerequisites.h【1】,OgreSimpleSpline.h【13】,OgreRotationalSpline.h【14】,OgreKeyFrame.h【15】,OgreAnimable.h,OgrePose.h

这个可是动画的核心组成部分了,一个track由一个关键帧序列组成。例如胳膊的前移动作就是一个track,由一系列的关键帧组成(这里不区别考虑四种动画模式),那么很容易理解,一个砍人动作需要挥动胳膊,迈腿(另一个track),也就是说一个Animation需要多个AnimationTrack来描述。

7.包含了OgreAnimationState.h

这个头文件包含了OgrePrerequisites.h【1】, OgreString.h【2】, OgreController.h【12】, OgreIteratorWrapper.h【3】。这个文件定义的主要类是AnimationState类。读过Intermediate Tutorial 1的都知道调用mesh里的动画就是通过AnimationState类来调用。的确,这个类不表示动画这个本身的实体,但是它表示动画的状态,而驱动一个动画动的和表示一个动画现在的帧的都是状态,所以用户可以直接通过控制动画的状态来驱动动画。这就是这个类的逻辑。

主要存储和控制以下几个状态:

BoneBlendMask(一个float的vector,是骨头的weight,玩建模的人知道这个,其他的不管也罢),

mAnimationName(这个AnimationState类控制的动画的名称),

mTimePos(动画的时间轴,都知道动画由一个个随时间变化的帧组成,不同时间点对应不同的帧,所以通过不断的增加时间就可以驱动帧的不断刷新,动画就动起来了,这个时间轴就是mTimePos),

mLength(整个动画的时间长度),

mWeight(动画的weight,这个词我也不知道怎么形容,程度吧。我再琢磨琢磨),

mEnabled(使能,你得把这个Animation给设成enable状态这个动画才能动),

mLoop(设置这个动画成循环模式,也就是在时间轴上复制展开)

另外这个文件还定义了一个AnimationStateSet类,顾名思义,就是一群AnimationState,其实每个AnimationState都会保存一个指向自己所在的AnimationStateSet的指针,要知道Ogre中,东西都要有组织有纪律的存在。这里的逻辑在于每个mesh物体(比如一个机器人),会有很多个动作(例如摔倒、摆手。。),所以对应的是一个AnimationStateSet,如果只有一个动作,那对应一个单元素的AnimationStateSet不就得了。接口统一是王道嘛。


Ogre的Animation(skeleton)只支持Animation Blending和Partial-skeleton Blending。而不支持流行的Additive Blending。(关于Animation Blending、Partial-skeleton Blending和Additive Blending的定义见Game Engine Architecture一书)



基本头文件(这部分头文件不完成特定的功能,是对基础数据结构和算法的定义和声明,被以上的头文件所使用。只是要了解OGRE的功能,这部分可以忽略)

【1】、OgrePrerequisites.h,解释在上文【1】,由于为基础头文件,也是底层头文件,所以分类时同时放在上下部分。

【2】、OgreString.h,该头文件定义了作用于String上的操作,类似于C++的cstring头文件里定义的操作。

【3】、OgreInteratorWrappers.h、OgreInteratorWrapper.h、OgreInteratorRange.h。是个空头文件,只负责包含仨头文件:OgrePrerequistes.h(前面说过),OgreInteratorWrapper.h(把vector和map这俩stl的container  的Interator重新封装了下,方便本程序内使用),OgreInteratorRange.h(Range是boost的一个container,这个头文件也是把range这个container的Interator重新封装了下下)

【4】、OgreVector2.h,OgreVector3.h,OgreVector4.h:分别定义了2维、3维和4维向量以及操作(4维不是咱说的那个四维空间,这叫齐次坐标,用四维向量,具体百度去)。这三头文件还包含了OgreMath.h【5】

【5】、OgreMath.h,定义了角度的两种表示方法:弧度和度数,并且定义了两种表示方法之间的转换函数和数学运算函数。

【6】、OgreQuaternion.h,定了了大名鼎鼎的四元数。这个东西你要是不懂你只能先学学数学了。三维中的数学重点理论。opengl中利用4*4的矩阵进行各种变换,Ogre利用的是四元数,两者肯定有数学关系,但是原理不一样的,

【7】、OgreColourValue.h,定义了Ogre中颜色的表示形式。r,g,b,a。这个要是也不懂的话,赶紧学下数学基础先吧。。。3d你真没法做了。

【8】、OgreSharedPtr.h,这个是智能指针。比如你的多个对象中指向同一个实体,那么智能指针通过维护一个引用计数来表示有多少指针指向这个对象,当为0时就删除,增加一个指针就加1.这种实现实际上是对C++机制的补充,避免了两个指针同时指向一个对象,一个free掉了,调用另一个出问题的这种事。

【9】、OgreStringVector.h,其实就是一个String的Vector。。。。typedef而已

【10】、OgreExceptin.h,用过C++的exception都知道这玩意是干嘛的。只是Ogre在std的exception的基础上做了些针对性的扩展,我看到的大部分系统都会干这个活。Ogre从来不根据返回值确定操作是否成功,它就用这个exception,不过大部分初级使用者不用在意。能看懂教程的不会出错,出错了的是看不懂教程的,你就更看不懂exception了。

【11】、OgreAny.h,这是boost库里面any这个container的Ogre版本。

【12】、OgreController.h,这个类可不得了,可以用来控制其他的对象,根据输入来变对象的值,是设计上的一个类,暂时不清楚这种设计模式叫啥。后期会补上。

【13】、OgreSimpleSpline.h,亲,应该知道啥是样条函数吧?这个文件就实现了Catmull-Rom样条曲线,给它起了个名字就叫SimpleSpline

【14】、OgreRotationalSpline.h,和SimpleSpline类似。都知道Hermite样条是点和切线来确定,SimpleSpline实现的Catmull-Rom是完全通过点来表示的曲线,这个类RotationalSpline则是通过方向来确定曲线(很容易理解,自己想想让你表示曲线你会怎么做,无非就是点、切线、向量这几种方法),这个类还会对点进行差值,使线条更圆滑,这已经是功能上的了。

【15】、OgreKeyFrame.h,学过flash木有?这就是传说中的关键帧。一个动画序列是用关键帧序列组成的,给序列中的每个帧一个时间坐标就成了动画,动画的其他空余的时间点通过插值(这概念要是不懂,改进补数学。。。)来计算出来。

【16】、OgreHardwareBuffer.h,这个定义了所有hardware buffer的公共操作接口。hardware buffer有很多,例如显存、声卡的外存、板上的主存之外的其它存储体。HardwareBuffer这个类把所有的buffer抽象了,是个纯虚类。

【16】、OgrePose.h,这个pose比较难理解。Ogre把顶点动画分成两种,一种叫morph,一种叫pose。morph最简单,就是两关键帧之间差值;pose也是定点动画,但是它的原理是定义一个mesh不同区域的顶点的偏移,通过组合不同的偏移形成最终的关键帧,也就是说 每个关键帧只可以存储一个morph(很容易理解,多个关键帧差值就有动画了),但对于pose动画,每个关键帧可以有多个pose。例如面部动画,假设一张脸是一个mesh,里面有很多个顶点。让它笑,一种方法是在笑的过程拍照片,然后差值,另一种就是让腮部、唇部、下巴、嘴形分别移动,因为很多面部顶点被这些部位共享,这就需要一个权值,最终得出所有顶点的偏移,然后与原位置的顶点相加就得到最新的位置,也就是最新的关键帧。(需要看Ogre manual)










你可能感兴趣的:(设计模式,数据结构,exception,vector,String,animation)