As Unity said:
Unity - Manual: Rotation and orientation in Unity
Unity - Scripting API: Quaternion
Benefit: Quaternion rotations do not suffer from Gimbal Lock.
Quaternions are used to represent rotations.
They are compact, don’t suffer from gimbal lock and can easily be interpolated. Unity internally uses Quaternions to represent all rotations.
And The Tramsform Rotation of unity is implemented by quaternions:
[124355-20180910202553.png*_|124355]
transform.rotation = Quaternion.identity;
So,why do I still encounter the Gimbal Lock problem when I use the tramsform by inspector panel?
Forexample,When I set the x-axis of an object to be 90 degrees by inspector panel, the Y-axis acts just like the Z-axis.
Then I wrote a test code:
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class QuaternionTest : MonoBehaviour {
public Vector3 El;
void Start () {
}
// Update is called once per frame
void Update () {
transform.rotation = Quaternion.Euler(El);
}
}
And this code also encounter the Gimbal Lock problem,So what is the use of quaternions?It can’t solve the problem of Gimbal lock.
I know that if I change the above code to this:
Vector3 offsetEl = El - oldEl;
transform.rotation = transform.rotation * Quaternion.Euler(El);
oldEl = El;
Gimbal lock can be solved.
But if the superposition algorithm can solve it, then the Euler angle algorithm can solve the same.Forexample:
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class EulerTest : MonoBehaviour
{
public Material mat;
public Vector3 El;
private Vector3 oldEl;
private Matrix4x4 matrS;
// Use this for initialization
void Start()
{
DrawCube();
}
private void OnEnable()
{
matrS = Matrix4x4.identity;
}
private void Update()
{
if (mat == null) return;
gameObject.GetComponent<MeshRenderer>().material = mat;
DrawCube();
}
Vector3[] test = new Vector3[]{
new Vector3(0, 0, 0),
new Vector3(1, 0, 0),
new Vector3(1, 1, 0),
new Vector3(0, 1, 0),
new Vector3(0, 1, 1),
new Vector3(1, 1, 1),
new Vector3(1, 0, 1),
new Vector3(0, 0, 1),
};
void DrawCube()
{
Mesh mesh = GetComponent<MeshFilter>().mesh;
mesh.Clear();
Vector3 offsetEl = El - oldEl;
Vector3[] test2 = (Vector3[])test.Clone();
float x = Mathf.PI * offsetEl.x / 180;
float y = Mathf.PI * offsetEl.y / 180;
float z = Mathf.PI * offsetEl.z / 180;
{
Matrix4x4 matr = new Matrix4x4();
matr.SetRow(0, new Vector4(Mathf.Cos(y), 0, Mathf.Sin(y), 0));
matr.SetRow(1, new Vector4(0, 1, 0, 0));
matr.SetRow(2, new Vector4(-Mathf.Sin(y), 0, Mathf.Cos(y), 0));
matr.SetRow(3, new Vector4(0, 0, 0, 1));
matrS = matrS * matr;
}
{
Matrix4x4 matr = new Matrix4x4();
matr.SetRow(0, new Vector4(1, 0, 0, 0));
matr.SetRow(1, new Vector4(0, Mathf.Cos(x), -Mathf.Sin(x), 0));
matr.SetRow(2, new Vector4(0, Mathf.Sin(x), Mathf.Cos(x), 0));
matr.SetRow(3, new Vector4(0, 0, 0, 1));
matrS = matrS * matr;
}
{
Matrix4x4 matr = new Matrix4x4();
matr.SetRow(0, new Vector4(Mathf.Cos(z), -Mathf.Sin(z), 0, 0));
matr.SetRow(1, new Vector4(Mathf.Sin(z), Mathf.Cos(z), 0, 0));
matr.SetRow(2, new Vector4(0, 0, 1, 0));
matr.SetRow(3, new Vector4(0, 0, 0, 1));
matrS = matrS * matr;
for (int i = 0; i < 8; ++i)
{
test2 _= matrS.MultiplyPoint(test2*);*_
* }*
* }*
* mesh.vertices = test2;*
* oldEl = El;*
* mesh.triangles = new int[]*
* {*
* 0, 2, 1,*
* 0,3,2,*
* 3,4,2,*
* 4,5,2,*
* 4,7,5,*
* 7,6,5,*
* 7,0,1,*
* 6,7,1,*
* 4,3,0,*
* 4,0,7,*
* 2,5,6,*
* 2,6,1*
* };*
* }*
}
Therefore, we can see that the quaternion is the same as the Euler angle, and does not solve the Gimbal Lock problem as Unity said. Or another algorithm can solve, but the same algorithm Euler angle can be solved too. So I was thinking, is it necessary to directly set the quaternary xyzw value to avoid the Gimbal lock, but the xyzw is very troublesome, the unity document said that it is not so troublesome, then what is the truth?
To sum up my problem:
1.Please provide a code example that can solve the Gimbal lock after the Euler angle encounters the universal lock and replace it with the quaternion.
2.Unity internally uses Quaternions to represent all rotations, why on the inspector panel still have a Gimbal lock problem.
Thank you all!
_*