|
|
本来想来请教一下的,后来自己给想清楚了(一看本人就是不熟悉矩阵操作的菜鸟,高手看了别笑,呵呵)
我先慢慢说清来龙去脉
我要给我的物理程序要加入标准的刚体运动模拟,包括旋转
刚体就两种,球和立方体
物体分物理模型和网格,
球的物理模型 一个中心点和半径
立方体的也一样简单,就是8个顶点
对于刚体运动的计算只考虑物理模型,传给OpenGL的网格顶点坐标不动(网格不形变,渲染时用OpenGL内部变换方向,位置),所以用OpenGL列表渲染
立方体没有旋转角时,它的棱是和坐标轴平行的
可以想象,当立方体旋转后,它就不是坐标轴平行的了,因此物理模型8个顶点需要用矩阵进行坐标旋转,才能得到它们的坐标
一开始,我这样处理:
Dim Rot As Matrix4x4
Rot.LoadIdentity()
Rot *= Matrix4x4.GetRotateXMatrix(pAngle.x)
Rot *= Matrix4x4.GetRotateYMatrix(pAngle.y)
Rot *= Matrix4x4.GetRotateZMatrix(pAngle.z)
Rot *= Matrix4x4.GetTranslateMatrix(pMassCentre) 'pMassCentre质心
结果发现不对,物体模型和网格旋转情况不一(红框为物理模型)
注:我检查了一下,确定旋转矩阵不是适用于DX的坐标系的,

但是网格渲染前,有
GL.glTranslated(pMassCentre.x, pMassCentre.y, pMassCentre.z)
GL.glRotated(pAngle.x * (180 / PI), 1, 0, 0)
GL.glRotated(pAngle.y * (180 / PI), 0, 1, 0)
GL.glRotated(pAngle.z * (180 / PI), 0, 0, 1)
我发现矩阵操作和OpenGL变换相比,Translate放在最后(放在前面更不行),我就想:是不是这里的操作是相反的呢?再加之我本来就比较喜欢EG,就胡乱的把矩阵相乘瞎排列了一下,角度也换城相反数(反方向) [em10]
Rot *= Matrix4x4.GetRotateZMatrix(-pAngle.z)
Rot *= Matrix4x4.GetRotateYMatrix(-pAngle.y)
Rot *= Matrix4x4.GetRotateXMatrix(-pAngle.x)
Rot *= Matrix4x4.GetTranslateMatrix(pMassCentre)
结果一试,竟然成功了。

我也没多想什么……
实现了物理模型8个顶点位置计算,拾取应该没什么问题(射线拾取按物理模型拾取)
然后就继续实现物体受冲量时的运动
我发现当立方体旋转到一定角度时,再用重力枪给他冲量时,旋转方向就不对了。
这次解决这个问题时,我终于意识到局部坐标系和全局坐标系的存在了(俺没学过刚体运动学,刚体绕定轴旋转也是就自学记了些公式……)[em6]
于是我就把刚才那个矩阵改成类的公有字段,每个物理frame更新,然后拿它来旋转冲量向量和半径向量,发现还不对……
没办法,继续EG,我又加了个矩阵,只是变换顺序和OpenGL的一样(和上面那个相反),用这个矩阵旋转上面提到的向量,才正确

然后改名
字段mInvTransformMatrix:第一个
mTransformMatrix第二个
总结:
mTransformMatrix:从全局坐标系到局部坐标系
可以看到:半径向量,冲量向量,都是全局坐标系里的(图里那三个线组成的坐标系),通过mTransformMatrix.TransformVec()后就会变成物体上的局部空间直角坐标系(当物体的pMassCentre在全局空间直角坐标系的原点且无旋转角时,此局部坐标系与全局坐标系重合)
mInvTransformMatrix:从局部坐标系到全局坐标系
这个不好表述……
相当于给定坐标(初始和坐标轴平行的物理模型)和旋转角,求旋转后的坐标
可以看到,“给定坐标” 就是局部坐标系里的,旋转后的坐标在全局坐标系里,以便以后的碰撞检测等工作。
球是对称的,旋转惯量一样,碰撞检测比较简单,因此不mInvTransformMatrix.Transform(Something),只用前面那个mTransformMatrix处理外部作用
|
|