ogre的动画系统写在OgreMain中。
骨骼资源导入
SkeletonManager是骨骼的创建管理,创建有两种方式,第一种是直接new出Skeleton,第二种是通过资源导入。
资源导入时执行到OgreResource的Resource::prepare,然后执行prepareImpl,这个是OgreResource.h的prepareImpl。
然后Skeleton继承Resource,所以导入时执行Skeleton::prepareImpl。
先获取资源ResourceGroupManager::getSingleton().openResource。获取到文件的指针,是DataStream类型。
然后用SkeletonSerializer的importSkeleton导入资源内容。SkeletonSerializer是继承Serializer的,Serializer是对资源读取后的序列化内容。
对导入的骨骼能有几个类型的识别
OgreSkeletonInstance实例化骨骼
OgreSkeletonInstance是对实例化后的对象的骨骼文件识别,在OgreEntity中初始化时回执行_initialise,如果有骨骼则执行创建SkeletonInstance,并则行load。SkeletonInstance是继承Skeleton的,所以也回执行Skeleton的prepareImpl执行内容加载。deriveRootBone是设置根节点,
对每根骨骼都执行createBone,设置骨骼的父子级,
在场景管理SceneManager中,执行_renderScene后会更新动画执行 _applySceneAnimations();在里面会拿到所有的AnimationStates,并拿到animation然后apply。执行到OgreAnimation的apply函数。
_applyBaseKeyFrame
然后先执行Animation::_applyBaseKeyFrame()对mNodeTrackList和mVertexTrackList。
里面对Node和Vertex做初始化
然后分别对Node,Numeric,Vertex分别执行apply。
执行到NodeAnimationTrack::applyToNode,
mNodeTrackList
NodeAnimationTrack是专门用于处理节点变换的AnimationTrack。
如果是Node的就执行到NodeAnimationTrack::getInterpolatedKeyFrame
判断是否第一帧,如果第一帧直接赋值旋转缩放平移。
不然的话就执行前后两帧的混合,混合有两种,线性的和样条曲线的。
getInterpolatedKeyFrame拿到帧的矩阵数据后设置到node里面
NumericAnimation:
NumericAnimationTrack是专门用于处理通用动画值的AnimationTrack。
NumericAnimationTrack::applyToAnimable,通过getInterpolatedKeyFrame获取影响权重,通过VertexPoseKeyFrame::addPoseReference设置进某帧,然后anim->applyDeltaValue(val);设置进AnimableValue里,他又几个类型可以设置
mVertexTrackList
VertexAnimationTrack专门用于处理变化的顶点位置信息的AnimationTrack。
如果类型是VAT_POSE类型也就是动画由单个三角形姿势关键帧组成,则执行VertexAnimationTrack::getInterpolatedKeyFrame,这里面主要是获取帧之间的影响放到KeyFrame中。
然后根据是形变,姿势的animation执行矩阵变化。
骨骼播放权重:
AnimationState中的BoneBlendMask是用于骨骼的遮罩的,这里的mask最终影响的是某个node的播放动作的权重。
当OgreEntity_updateRenderQueue的时候他会去执行渲染队列处理,然后通过cacheBoneMatrices来执行setAnimationState。
然后从animSet中拿出所有激活的动作状态机getEnabledAnimationStates,通过状态机获取动作,然后通过两种方式做,第一种是有blendMask的,则执行带blendMask的动作的apply,如果不是则不带。
blendMask
如果是带blendMask的方式则会执行node的动作系统,
相当于带了blendMask的话就只会有blendMask的可以做动作。
不带blendMask
如果不带blendMask的则执行applyToNode不带blendMask的,相当于不带mask的影响。
骨骼动画的优化(只有node的优化)
Skeleton::optimiseAllAnimations中有对骨骼动画的优化,他会拿出缩放,平移,旋转都为0的值给移除掉,执行到Animation::optimise,主要对Node和Vertex模式做优化,但是现在只做了node的。
然后到NodeAnimationTrack::optimise中。这里主要仅从5+个相同关键帧的序列中消除中间关键帧,因为我们需要在适当的位置保留边界关键帧,并且我们需要在每一端保留2个关键帧,以便为样条线插值保留切线。
再OgreMesh中又对Animation的处理