ImageVerifierCode 换一换
格式:DOCX , 页数:7 ,大小:124.46KB ,
资源ID:14848639      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/14848639.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(骨骼蒙皮动画SkinnedMesh的原理解析二Word下载.docx)为本站会员(b****2)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

骨骼蒙皮动画SkinnedMesh的原理解析二Word下载.docx

1、BoneOffsetMatrix-Bone space-World从这个过程中可看出,需要首先将模型顶点从模型空间变换到某块骨骼自身的骨骼空间,然后才能利用骨骼的世界变换计算顶点的世界坐标。BoneOffset Matrix的作用正是将模型从顶点空间变换到骨骼空间。那么Bone Offset Matrix如何得到呢?下面具体分析:Mesh space是建模时使用的空间,mesh中顶点的位置相对于这个空间的原点定义。比如在3d max中建模时(视xy平面为地面,+z朝上),可将模型两脚之间的中点作为Mesh空间的原点,并将其放置在世界原点,这样左脚上某一顶点坐标是(10,10,2),右脚上对称的

2、一点坐标是(-10,10,2),头顶上某一顶点的坐标是(0,0,170)。由于此时Mesh空间和世界空间重合,上述坐标既在Mesh空间也在世界空间,换句话说,此时实际是以世界空间作为Mesh空间了。在骨骼动画中,在世界中放置的是骨骼而不是Mesh,所以这个区别并不重要。在3d max中添加骨骼的时候,也是将骨骼放入世界空间中,并调整骨骼的相对位置使得和mesh相吻合(即设置骨骼的TransformMatrix),得到骨架的初始姿势以及相应的Transform Matrix(按惯例模型做成两臂侧平举直立,骨骼也要适合这个姿态)。由于骨骼的TransformMatrix(作用是将顶点从骨骼空间变换

3、到上层空间)是基于其父骨骼空间的,只有根骨骼的Transform是基于世界空间的,所以要通过自下而上一层层Transform变换(如果使用行向量右乘矩阵,这个Transform的累积过程就是C=Mbone*Mfather*Mgrandpar*.*Mroot),得到该骨骼在世界空间上的变换矩阵 - Combined TransformMatrix,即通过这个矩阵可将顶点从骨骼空间变换到世界空间。那么这个矩阵的逆矩阵就可以将世界空间中的顶点变换到某块骨骼的骨骼空间。由于Mesh实际上就是定义在世界空间了,所以这个逆矩阵就是OffsetMatrix。即Offset Matrix就是骨骼在初始位置(没

4、有经过任何动画改变)时将bone变换到世界空间的矩阵(CombinedTransformMatrix)的逆矩阵,有一些资料称之为Inverse Matrix。在几何流水线中,是通过变换矩阵将顶点变换到上层空间,最终得到世界坐标,逆矩阵则做相反的事,所以Inverse这种提法也符合惯例。那么Offset这种提法从字面上怎么理解呢?Offset即骨骼相对于世界原点的偏移,世界原点加上这个偏移就变成骨骼空间的原点,同样定义在世界空间中的点经过这个偏移矩阵的作用也被变换到骨骼空间了。从另一角度理解,在动画中模型中顶点的位置是根据骨骼位置动态计算的,也就是说顶点跟着骨骼动,但首先必须确定顶点和骨骼之间的

5、相对位置(即顶点在该骨骼坐标系中的位置),一个骨骼可能对应很多顶点,如果要保存这个相对位置每个顶点对于每块受控制的骨骼都要保存,这样就要保存太多的矩阵了。所以只保存mesh空间到骨骼空间的变换(即OffsetMatrix),然后通过这个变换计算每个顶点在该骨骼空间中的坐标,所以OffsetMatrix也反应了mesh和每块骨骼的相对位置,只是这个位置是间接的通过和世界坐标空间的关系表达的,在初始位置将骨骼按照模型的形状摆好是关键之处。以上的分析是通过将mesh space和world space重合得到OffsetMatrix的计算方法。那么如果他们不重合呢?那就要先计算顶点从mesh spa

6、ce变换到world space的变换矩阵,并乘上(还是右乘为例)Combined Matrix的InverseMatrix从而得到OffsetMatrix。但是这不是找麻烦吗?因为Mesh的原点在哪儿并不重要,为啥不让他们重合呢?还有一个问题是,既然OffsetMatrix可以计算出来,为啥还要在骨骼动画文件中同时提供TransformMatrix和OffsetMatrix呢?实际上文件中确实可以不提供OffsetMatrix,而只在载入时计算。但TransformMatrix不可缺少,动画关键帧数据一般只存储骨骼的旋转和根骨骼的位置,骨骼间的相对位置还是要靠TransformMatrix提

7、供。在微软的X文件结构中提供了OffsetMatrix,原因是什么呢?我不知道。我猜想一个可能的原因是为了兼容性和灵活性,比如mesh并没有定义在世界坐标系,而是作为一个object放置在3d max中,在导出骨骼动画时不能简单的认为mesh的顶点坐标是相对于世界原点的,还要把这个object的位置考虑进去,于是导出插件要计算出OffsetMatrix并保存在x文件中以避免兼容性问题。关于OffsetMatrix和TransformMatrix含有平移,旋转和缩放的讨论:首先,OffsetMatrix取决于骨骼的初始位置(即TransformMatrix),由于骨骼动画中我们使用的是动画中的位

8、置,初始位置是什么样并不重要,所以可以在初始位置中只包含平移,而旋转和缩放在动画中设置(一般也仅仅使用旋转,这也是为啥动画通常中可以用一个四元数表示骨骼的关键帧)。在这种情况下,OffsetMatrix只包含平移即可。因此一些引擎的Bone中不存放Transform矩阵,而只存放骨骼在父骨骼空间中的坐标,然后旋转只在动画帧中设置,最基本的骨骼动画即可实现。但也可在Transform和Offset Matrix中包括旋转和缩放,这样可以提高创建动画时的容错性。在本文DEMO中,我们也没有使用矩阵保存Bone Offset,而只用了一个坐标保存偏移位置。classBoneOffsetpublic:

9、floatm_offx, m_offy, m_offz;在Bone class中,有一个方法用来计算Bone OffsetclassBoneBoneOffsetm_boneOffset;/called after ComputeWorldPos() when boneloaded but not animatedvoidComputeBoneOffset()m_boneOffset.m_offx= -m_wx;m_boneOffset.m_offy= -m_wy;m_boneOffset.m_offz= -m_wz;if(m_pSibling!=NULL)m_pSibling-ComputeB

10、oneOffset();if(m_pFirstChild!m_pFirstChild-在ComputeBoneOffset()中,使用计算好的骨骼的世界坐标来计算bone offset,这儿的计算只是取一个负数,在实际引擎中,如果bone offset是一个矩阵,这儿就应该是求逆矩阵,本文不做讨论了。注意由于我们计算Bone offset时是使用计算好的世界坐标,所以在这之前必须在初始位置时对根骨骼调用ComputeWorldPos()以计算出各个骨骼在初始位置时的世界坐标。2-3)最终:顶点混合(vertexblending)现在我们有了Skin info,有了Bone offset,可谓万

11、事具备,只欠东风了。现在就可以做顶点混合了,这是骨骼动画的精髓所在,正是这个技术消除了关节处的裂缝。顶点混合后得到了顶点新的世界坐标,对所有的顶点执行vertexblending后,从Mesh的角度看,Mesh deform(变形)了,变成动画需要的形状了。首先,让我们看看使用单块骨骼对顶点进行作用的过程,以下是DEMO中的相关代码:classVertexvoidComputeWorldPosByBone(Bone* pBone, float& outX, float& outY, float&outZ)/step1:transform vertex from mesh space to bo

12、ne spaceoutX= m_x+pBone-m_boneOffset.m_offx;outY= m_y+pBone-m_boneOffset.m_offy;outZ= m_z+pBone-m_boneOffset.m_offz;/step2:transform vertex from bone space to world sapceoutX+= pBone-m_wx;outY+= pBone-m_wy;outZ+= pBone-m_wz;这个函数使用一块骨骼对顶点进行变换,将顶点从Mesh坐标系变换到世界坐标系,这儿使用了骨骼的Bone Offset Matrix和 Combined T

13、ransform Matrix (嗯,我知道这儿没用矩阵,但意思是一样的对吗)对于多块骨骼,对每块骨骼执行这个过程并将结果根据权重混合(即vertex blending)就得到顶点最终的世界坐标。进行vertex blending的代码如下:voidBlendVertex()/dothe vertex blending, get the vertexs pos in world spacem_wX= 0;m_wY= 0;m_wZ= 0;for(inti=0; im_boneNum; +i)floattx, ty, tz;ComputeWorldPosByBone(m_bonesi,tx, ty

14、, tz);tx*=m_boneWeightsi;ty*=m_boneWeightsi;tz*=m_boneWeightsi;m_wX+= tx;m_wY+= ty;m_wZ+= tz;这些函数我都放在Vertex类中了,因为只是一个简单DEMO所以没有特别考虑引擎结构问题,在BlendVertex()中,遍历影响该顶点的所有骨骼,用每块骨骼计算出顶点的世界坐标,然后使用Skin Weight对这些坐标进行加权平均。tx,ty,tz是某块骨骼作用后顶点的世界坐标乘以权重后的值,这些值相加后就是最终的世界坐标了。现在让我们用一个公式回顾一下Vertexblending的整个过程(使用矩阵变换)Vworld = Vmesh * BoneOffsetMatrix1

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1