骨骼动画貌似很简单的原理的理解.docxVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
骨骼动画貌似很简单的原理的理解

先说一下我对骨骼动画貌似很简单的原理的理解。下面的阐述也能看得出我对这些概念的把握其实很混乱,都是模模糊糊的。 骨骼像一棵树形结构那样,有父骨骼、子骨骼。每个骨骼保存的都是相对于父骨骼的转换矩阵,因此他们的世界矩阵都需要把自己的矩阵乘上父骨骼的世界矩阵才能得到(这是在d3d的情况。opengl的程序往往是反过来的,父骨骼的世界矩阵乘上本骨骼的矩阵,好像跟opengl使用矩阵的方式有关(压入堆栈))。 Mesh的每一个顶点都可以受多根骨骼的影响,使用权重值来决定影响的程度。 在程序里面,可以先对一个顶点使用骨骼转换到正确的动作姿态(这时仍然只是在模型空间),再用该游戏物体的世界矩阵转换到游戏世界的正确位置上 现在先不考虑游戏物体的世界矩阵,只考虑模型空间。 这就有了一个问题:对顶点应当使用什么矩阵才能把它转换到正确的动作姿态上?想象一个简单的人物模型,裸模,身体各部位都是连贯的一个mesh。那么这些顶点都是在模型空间里定义的,而每个骨骼的那些缩放、旋转和位置信息都是在父骨骼的空间里定义的,这就不能拿骨骼的世界矩阵直接转换顶点。我认为,只有顶点是在骨骼的本地空间里定义的才可以使用骨骼的世界矩阵转换它。确实,有一个bind pose的概念,它其实就是矩阵,是骨骼初始的世界矩阵。矩阵是把坐标从空间A转换到空间B,那么这个矩阵的逆矩阵就能把坐标从空间B转换回空间A。所以bind pose矩阵的逆矩阵就应当能把模型空间的顶点转换到骨骼的本地空间去,然后在某一时刻,使用骨骼的世界矩阵转换这些在骨骼空间中的顶点,应该就能把它们转换到正确的动作姿态了。 在3DSMAX导出插件,使用IGame。如何得到各骨骼的bind pose呢?由于在游戏里,骨骼的空间信息仍然是相对于父骨骼定义的,所以这里求Bind pose,也是一样。而且一般bind pose取第0帧时即可。 使用IGameNode::GetWorldTM()函数(参数应该传0,也就相当于第0帧了),得到一个GMatrix结构,在调用GMatrix的ExtractMatrix3()函数就能得到一个Matrix3结构(它是以列为主的,跟d3d不一样)tm,这就是该IGameNode在第0帧时的世界矩阵了。本来tm应该就是该骨骼的bind pose矩阵的,但因为要保存相对于父骨骼的值,所以还要先使用同样方法得到父骨骼在第0帧时的世界矩阵ptm,让tm乘上ptm的逆矩阵。 接下来,实际保存的时候,由于我的Bone结构实际存储的是缩放、旋转、位置,所以要把这个tm矩阵拆开来。那么在游戏里要得到一个Bone的Bind pose矩阵,就是从这3个值构造一个矩阵,再乘上父骨骼的bind pose矩阵。这里,我发现我和Ogre引擎的一个非常显著的分歧。 我的做法,如上所述 Matrix IBone::GetBindPoseMatrix() { ? Matrix mtxScale = MtxScale(m_BindPoseScale); // m_BindPoseScale是一个三维向量,代表了bind pose的xyz方向上的缩放 ? Matrix mtxRot = MtxRotFromQuaternion(m_BindPoseRot); // m_BindPoseRot是一个Quaternion,MtxRotFromQuaternion函数可以根据一个Quaternion创建一个旋转矩阵 ? Matrix mtxTrans = MtxTranslation(m_BindPoseTrans); ? m_BindPoseMatrix = mtxScale * mtxRot * mtxTrans; // 保存一下计算出的bind pose矩阵,如果愿意,使用一点技巧,可以使此函数不必每次都计算,这里省掉了 ? if(m_pParent) ? { ? m_BindPoseMatrix *= m_pParent-GetBindPoseMatrix(); ? } ? return m_BindPoseMatrix; } 可以看到,我先把本骨骼相对于父骨骼的bindpose缩放、旋转、平移合并为一个矩阵,再乘上父骨骼的bind pose矩阵,得到本骨骼的在世界空间的bind pose矩阵。 可是ogre,是先把本骨骼的bindpose缩放乘上父骨骼的bindpose缩放,本骨骼的bindpose旋转乘上父骨骼的bindpose旋转,本骨骼的bindpose位置加上父骨骼的bindpose位置,得出三个新的缩放、旋转、位置,再合并为一个矩阵。 这两种方法得出来的结果是不一样的。 这就是我的困惑。ogre的运行效果是没错的,我的运行效果是错误的,不过我之前用过ogre的方式,也不对。我想不对的原因不仅仅

文档评论(0)

baoyue + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档