|
发表于 2008-4-17 00:08:00
|
显示全部楼层
Re:问个Gimbal Lock的问题
CS里面的旋转,你可以体会一下,是这样的:
<和天线一样,天线的旋转机构就叫做"Ginbal">
左右旋转,是绕着世界的 y 轴进行的,(竖直向上的轴)
抬头低头,是绕着自己的 x 轴进行的,(你身体左侧方向的轴)
当头抬到顶的时候,你自己的 z 轴(视线方向)和世界的 y 轴重合(竖直向上了),
(你自己的 y 轴,即头顶方向将会变成地平线)
这时候你自己的 z 轴(视线方向)便不会旋转,视野里天花板上的灯的位置也不会移动。
因为人的左右旋转,是躯干的旋转(躯干是竖直的),而上下旋转,是头部的旋转。
在CS中,你从未看见过一个倾斜的大楼!
这是因为:
1 没有倾斜旋转操作(倾斜头部)
2 左右旋转总是围绕竖直方向,那么你自己的 x 轴将总是水平的,具体是因为:
你的 x 轴(身体左侧方向)初始是水平的,旋转过程中只有2种情况:
(1)左右移动鼠标: 你的 x 轴可以绕 铅直线旋转,当然还是水平的。
(2)上下移动鼠标: 你的 y,z 轴围绕你的 x 轴旋转,所以 x 轴自己就不转。
写这个帖子把我写的快要晕了。。。
总的来说,我用3个坐标轴来控制旋转,这样不会有问题,
其中一个轴不转了,其他的轴会转。
看一下我的摄像机的位置控制:
case 'L':
pcamera->RotateByParent(0,RotateSpeed,0);
break;
case 'J':
pcamera->RotateByParent(0,-RotateSpeed,0);
break;
case 'I':
pcamera->RotateByLocal(-RotateSpeed,0,0);
break;
case 'K':
pcamera->RotateByLocal(RotateSpeed,0,0);
break;
// 从父母空间到本地空间的矩阵。(这里,世界是摄像机的父母)
g_pg->SetTransform(TS_VIEW,pcamera->GetMat44FromParent());
我的 CPosCtrl 类里面通过维护3个本地坐标轴在父母空间中的坐标值,来进行位置控制:
void MoveByParent(Float dx,Float dy,Float dz);
void MoveByLocal(Float dx,Float dy,Float dz);
void SetPosByParent(const VEC3 *pos);
void SetPosByParent(Float x,Float y,Float z);
const VEC3 *GetPosByParent()const;
void GetPosByParent(Float *x,Float *y,Float *z)const;
void RotateByLocal(Float x,Float y,Float z);
void RotateByParent(Float x,Float y,Float z);
MAT44 GetMat44ToParent()const;
MAT44 GetMat44FromParent()const;
VEC3 m_Pos; // by parent coord
VEC3 m_Look; // z axis ,by parent coord
VEC3 m_Up; // y axis ,by parent coord
VEC3 m_Right; // x axis ,by parent coord |
|