万向节死锁产生的根本原因是,旋转矩阵是依次进行的,假设先围绕x轴旋转,再围绕y轴旋转,最后围绕z轴旋转,这就导致物体其实是围绕自己的X轴旋转,而不是世界坐标的X轴旋转。
表现就是,在一个欧拉角(x,y,z)下,改变x的值,物体会围绕物体自己的x轴进行旋转,而不是世界坐标系的x轴进行旋转。
下图所示,改变x值,都是在绕自己的红色的轴(x轴)转。RGB三个颜色分别对应XYZ正半轴:
首先,旋转3D模型时,实际是对原始模型的顶点进行旋转。比如旋转(x1,y1,z1),就是把原始模型旋转到这个角度,然后渲染显示。当旋转变成(x2,y2,z2),会把原始模型旋转到这个角度,然后渲染显示。
然后,进行一次旋转时,物体是先围绕x轴进行旋转,这时候物体的局部坐标系和世界坐标系是重合的,虽然是围绕世界坐标的x轴旋转,但也是围绕自己的x轴进行旋转。最后得到的旋转结果,也变成了物体是绕自己的x轴转的结果了。
最后,当把物体的x轴旋转到与世界的z轴重合时,欧垃角的x和z旋转结果就都一样了,也就丢失了一个维度。另一方面,比如在(30, 30, 30)的欧垃角下,把y从30调到60会发现并不是绕自己的y轴在转,也不是绕世界坐标的y旋转。
可以自己通过欧拉角计算出顶点旋转后的坐标来验证这个。
参考资料:
附上自己的Unity测试代码:
using UnityEngine;
[ExecuteInEditMod