由于要做第一视角的动画,所以测试了一下ogre的四元数,大致通过代码来理解其过程。
按下列代码,发现实验结果是物体位置不变。可以这样理解:物体在旋转的时候自身的X,Y,Z坐标系统跟随物体一起转动,但是还是保留了一个局部坐标系,而这个局部坐标系统不随物体转动而转动,即step2中的testvector2是定义在这个不变的局部坐标系统的,否则的话物体从Y转到(0.0,1.0,0.1)没有任何意义。
//test Quaternion //step 1,x----->y Ogre::Quaternion test = mWomanNode->getOrientation(); Ogre::Vector3 testvector = test*Ogre::Vector3::UNIT_X; Ogre::Vector3 testvector2(0,1,0); Ogre::Quaternion quat = testvector.getRotationTo(testvector2); mWomanNode->rotate(quat); //step x----->y测试物体是否绑定在局部坐标系上 test = mWomanNode->getOrientation(); testvector = test*Ogre::Vector3::UNIT_Y; testvector2 = Ogre::Vector3(0.0,1.0,0.0); quat = testvector.getRotationTo(testvector2); mWomanNode->rotate(quat);
再比较一下下面两段代码:
code1: test = mWomanNode->getOrientation(); testvector = Ogre::Vector3(-20.0,0.0,0.0); testvector2 = test*testvector; mWomanNode->translate(testvector2); code2: testvector = Ogre::Vector3(-20.0,0.0,0.0); mWomanNode->translate(testvector);
你能比较出两个的差别吗?两个的执行结果是不同的,code1执行的结果是在旋转以后的局部坐标中进行了平移,也就是说与我们在进行step1之前进行translate(0.0,-20.0,0.0)一样的效果,这与OPENGL很相似,就是旋转的时候整个坐标系也跟着旋转了,而第二部进行的平移是在原坐标系进行了平移,跟step1进行的旋转没有任何关系。
总结:1:平移:如果带getOrientation(),我们进行的平移操作是在旋转后的坐标系中进行的,不带getOriention(),我们进行的平移操作时在原坐标系中进行的;
2:旋转:如果带getOrientation(),我们进行的旋转操作时在旋转后的坐标中进行的,但是向量还是原来坐标中的向量。不带getOriention(),我们进行的旋转操作时在旋转后的坐标中实现的。这里有个好处,当我们调用getOrientation()时,旋转时转向某个向量可以不是自己转动过后内的局部坐标内的坐标,即我们可以及时计算两个向量的转动(一直在一个坐标系中)。而不带getOriention()的话,我们必须知道这个向量在转动后的局部坐标系中如何表示,这会带来很大的麻烦,要乘以很多旋转矩阵以后才能满足吧。。。所以如果你一直在一个坐标系中计算向量之间的转动的话,采用四元数是一种很奇妙的方法。
PS:但愿我理解的对,起码现在还没出现问题,有问题联系我,kuang.eagle@gmail.com,一起交流。