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