骨骼蒙皮动画(Skinned-Mesh)的原理解析(二)_第1页
骨骼蒙皮动画(Skinned-Mesh)的原理解析(二)_第2页
骨骼蒙皮动画(Skinned-Mesh)的原理解析(二)_第3页
骨骼蒙皮动画(Skinned-Mesh)的原理解析(二)_第4页
骨骼蒙皮动画(Skinned-Mesh)的原理解析(二)_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

骨骼蒙皮动画(SkinnedMesh)的原理解析(二)2)蒙皮信息和蒙皮过程2-1)Skininfo的定义上文曾讨论过,SkinnedMesh中Mesh是作为皮肤使用,蒙在骨骼之上的。为了让普通的Mesh具有蒙皮的功能,必须添加蒙皮信息,即Skininfo。我们知道Mesh是由顶点构成的,建模时顶点是定义在模型自身坐标系的,即相对于Mesh原点的,而骨骼动画中决定模型顶点最终世界坐标的是骨骼,所以要让骨骼决定顶点的世界坐标,这就要将顶点和骨骼联系起来,Skininfo正是起了这个作用。下面是DEMO中顶点类的定义的代码片段:#defineMAX_BONE_PER_VERTEX4

//用来设置可同时影响该顶点的最大骨骼数classVertex{floatm_x,m_y,m_z;//localposinmeshspacefloatm_wX,m_wY,m_wZ;//blendedvertexpos,inworldspace//skininfointm_boneNum;

//影响该顶点的骨骼数目Bone*m_bones[MAX_BONE_PER_VERTEX];

//指向这些骨骼的指针floatm_boneWeights[MAX_BONE_PER_VERTEX];

//这些骨骼作用于该点的权重};顶点的Skininfo包含影响该顶点的骨骼数目,指向这些骨骼的指针,这些骨骼作用于该顶点的权重(Skinweight)。由于只是一个简单的例子,这儿没有考虑优化,所以用静态数组存放骨骼指针和权重,且实际引擎中Skininfo的定义方式不一定是这样的,但基本原理一致。MAX_BONE_PER_VERTEX在这儿用来设置可同时影响顶点的最大骨骼数,实际上由于这个DEMO是手工进行VertexBlending并且也没用硬件加速,可影响顶点的骨骼数量并没有限制,只是恰好需要一个常量来定义数组,所以定义了一下。在实际引擎中由于要使用硬件加速,以及为了确保速度,一般会定义最大骨骼数。另外在本DEMO中,Skininfo是手工设定的,而在实际项目中,一般是在建模软件中生成这些信息并导出。Skininfo的作用是使用各个骨骼的变换矩阵对顶点进行变换并乘以权重,这样某块骨骼只能对该顶点产生部分影响。各骨骼权重之和应该为1。Skininfo是针对顶点的,然而在使用Skininfo前我们必须要使用BoneOffsetMatrix对顶点进行变换,下面具体讨论BoneoffsetMatrix。(写下这句话的时候我感觉有些不妥,因为实际是先将所有的矩阵相乘最后再作用于顶点,这儿是按照理论上的顺序进行讲述吧,请不要与实际情况混淆,其实他们也并不矛盾。而且在我们的DEMO中由于没有使用矩阵,所以变换的顺序和理论顺序是一致的)2-2)BoneOffsetMatrix的含义和计算方法上文已经说过:“骨骼动画中决定模型顶点最终世界坐标的是骨骼,所以要让骨骼决定顶点的世界坐标”,现在让我们看下顶点受一块骨骼的作用时的坐标变换过程:meshvertex(definedinmeshspace)---<BoneOffsetMatrix>--->Bonespace---<BoneCombinedTransformMatrix>--->World从这个过程中可看出,需要首先将模型顶点从模型空间变换到某块骨骼自身的骨骼空间,然后才能利用骨骼的世界变换计算顶点的世界坐标。BoneOffsetMatrix的作用正是将模型从顶点空间变换到骨骼空间。那么BoneOffsetMatrix如何得到呢?下面具体分析:Meshspace是建模时使用的空间,mesh中顶点的位置相对于这个空间的原点定义。比如在3dmax中建模时(视xy平面为地面,+z朝上),可将模型两脚之间的中点作为Mesh空间的原点,并将其放置在世界原点,这样左脚上某一顶点坐标是(10,10,2),右脚上对称的一点坐标是(-10,10,2),头顶上某一顶点的坐标是(0,0,170)。由于此时Mesh空间和世界空间重合,上述坐标既在Mesh空间也在世界空间,换句话说,此时实际是以世界空间作为Mesh空间了。在骨骼动画中,在世界中放置的是骨骼而不是Mesh,所以这个区别并不重要。在3dmax中添加骨骼的时候,也是将骨骼放入世界空间中,并调整骨骼的相对位置使得和mesh相吻合(即设置骨骼的TransformMatrix),得到骨架的初始姿势以及相应的TransformMatrix(按惯例模型做成两臂侧平举直立,骨骼也要适合这个姿态)。由于骨骼的TransformMatrix(作用是将顶点从骨骼空间变换到上层空间)是基于其父骨骼空间的,只有根骨骼的Transform是基于世界空间的,所以要通过自下而上一层层Transform变换(如果使用行向量右乘矩阵,这个Transform的累积过程就是C=Mbone*Mfather*Mgrandpar*...*Mroot),得到该骨骼在世界空间上的变换矩阵-CombinedTransformMatrix,即通过这个矩阵可将顶点从骨骼空间变换到世界空间。那么这个矩阵的逆矩阵就可以将世界空间中的顶点变换到某块骨骼的骨骼空间。由于Mesh实际上就是定义在世界空间了,所以这个逆矩阵就是OffsetMatrix。即OffsetMatrix就是骨骼在初始位置(没有经过任何动画改变)时将bone变换到世界空间的矩阵(CombinedTransformMatrix)的逆矩阵,有一些资料称之为InverseMatrix。在几何流水线中,是通过变换矩阵将顶点变换到上层空间,最终得到世界坐标,逆矩阵则做相反的事,所以Inverse这种提法也符合惯例。那么Offset这种提法从字面上怎么理解呢?Offset即骨骼相对于世界原点的偏移,世界原点加上这个偏移就变成骨骼空间的原点,同样定义在世界空间中的点经过这个偏移矩阵的作用也被变换到骨骼空间了。从另一角度理解,在动画中模型中顶点的位置是根据骨骼位置动态计算的,也就是说顶点跟着骨骼动,但首先必须确定顶点和骨骼之间的相对位置(即顶点在该骨骼坐标系中的位置),一个骨骼可能对应很多顶点,如果要保存这个相对位置每个顶点对于每块受控制的骨骼都要保存,这样就要保存太多的矩阵了。。。所以只保存mesh空间到骨骼空间的变换(即OffsetMatrix),然后通过这个变换计算每个顶点在该骨骼空间中的坐标,所以OffsetMatrix也反应了mesh和每块骨骼的相};这个函数使用一块骨骼对顶点进行变换,将顶点从Mesh坐标系变换到世界坐标系,这儿使用了骨骼的BoneOffsetMatrix和CombinedTransformMatrix(嗯,我知道这儿没用矩阵,但意思是一样的对吗)对于多块骨骼,对每块骨骼执行这个过程并将结果根据权重混合(即vertexblending)就得到顶点最终的世界坐标。进行vertexblending的代码如下:classVertex{voidBlendVertex(){//dothevertexblending,getthevertex'sposinworldspacem_wX=0;m_wY=0;m_wZ=0;for(inti=0;i<m_boneNum;++i){floattx,ty,tz;ComputeWorldPosByBone(m_bones[i],tx,ty,tz);tx*=m_boneWeights[i];ty*=m_boneWeights[i];tz*=m_boneWeights[i];m_wX+=tx;m_wY+=ty;m_wZ+=tz;}}};这些函数我都放在Vertex类中了,因为只是一个简单DEMO所以没有特别考虑引擎结构问题,在BlendVertex()中,遍历影响该顶点的所有骨骼,用每块骨骼计算出顶点的世界坐标,然后使用SkinWeight对这些坐标进行加权平均。tx,ty,tz是某块骨骼作用后顶点的世界坐标乘以权重后的值,这些值相加后就是最终的世界坐标了。现在让我们用一个公式回顾一下Vertexblending的整个过程(使用矩阵变换)Vworld=Vmesh*BoneOffsetMatrix1*CombindMatrix1*Weight1+Vmesh*BoneOffsetMatrix2*CombinedMatrix2*Weight2+…+Vmesh*BoneOffsetMatrixN*CombindMatrixN*WeightN(这个公式使用的是行向量左乘矩阵)由于BoneOffsetMatrix和CombinedMatrix都是矩阵,可以先相乘这样就减少很多计算了,在实际PC游戏中可以使用VS进行硬件加速计算。3)动画数据和播放动画正如前面所说,本例子中并没有使用动画数据,但动画数据在骨骼动画中确实最重要的,因为我们的最终目的就是播放动画。所以作为DEMO的补充,这儿简要讨论一下动画数据相关问题。其实我觉得动画的处理在骨骼动画中是很灵活的,需要专门的一篇文章讨论。本文的最开始说,3D模型动画的基本原理是让模型中各顶点的位置随时间变化。骨骼动画的情况是,骨骼的位置随时间变化,顶点位置随骨骼变化。所以动画数据中必然包含的是骨骼的运动信息。可以在动画帧中包含某时刻骨骼的TransformMatrix,但骨骼一般只是做旋转,所以也可以用一个四元数表示。但有时候骨骼层次整体会在动画中进行平移,所以可能需要在动画帧中包含根骨骼的位置信息。播放动画时,给出当前播放的时间值,对于每块需要动画的骨骼,根据这个值找出该骨骼前后两个关键帧,根据时间差进行插值,对于四元数要使用四元数球面插值。然后将插值得到的四元数转换成TransformMatrix,再调用UpdateBoneMatrix(其含义上文已介绍)更新计算整个骨骼层次的CombinedMatrix。4)总结从结构上看,SkinnedMesh包括:动画数据,骨骼数据,包含Skininfo的Mesh数据,以及BoneOffsetMatrix。从过程上看,载入阶段:载入并建立骨骼层次

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论