Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Calculate euler angles in DOTS by the Quaternion class

Discussion in 'Entity Component System' started by Yuriy_Sevastyanov, Mar 3, 2020.

  1. Yuriy_Sevastyanov

    Yuriy_Sevastyanov

    Joined:
    Apr 9, 2017
    Posts:
    25
    Hello everyone!
    I use Euler angles to calculate a boolean value:

    Code (CSharp):
    1.     public static bool GetIsFlipDirection(Rotation rotation)
    2.     {
    3.         Quaternion rotationValue = rotation.Value;
    4.         var anglesZ = rotationValue.eulerAngles.z;
    5.         bool flipY = anglesZ > 90 && anglesZ < 270;
    6.         return flipY;
    7.     }
    8.  
    Is it a good way to use Quaternion in DOTS? Is it compatible with Burst? I really couldn't find a way to use Unity.Mathematics to calculate Euler angles.
     
  2. mr-gmg

    mr-gmg

    Joined:
    Aug 31, 2015
    Posts:
    62
    I used this
    Code (CSharp):
    1. public static float3 ToEulerAngles(quaternion q) {
    2.     float3 angles;
    3.  
    4.     // roll (x-axis rotation)
    5.     double sinr_cosp = 2 * (q.value.w * q.value.x + q.value.y * q.value.z);
    6.     double cosr_cosp = 1 - 2 * (q.value.x * q.value.x + q.value.y * q.value.y);
    7.     angles.x = (float)math.atan2(sinr_cosp, cosr_cosp);
    8.  
    9.     // pitch (y-axis rotation)
    10.     double sinp = 2 * (q.value.w * q.value.y - q.value.z * q.value.x);
    11.     if (math.abs(sinp) >= 1)
    12.         angles.y = (float)CopySign(math.PI / 2, sinp); // use 90 degrees if out of range
    13.     else
    14.         angles.y = (float)math.asin(sinp);
    15.  
    16.     // yaw (z-axis rotation)
    17.     double siny_cosp = 2 * (q.value.w * q.value.z + q.value.x * q.value.y);
    18.     double cosy_cosp = 1 - 2 * (q.value.y * q.value.y + q.value.z * q.value.z);
    19.     angles.z = (float)math.atan2(siny_cosp, cosy_cosp);
    20.  
    21.     return angles;
    22. }
    23.  
    24. private static double CopySign(double a, double b) {
    25.     return math.abs(a) * math.sign(b);
    26. }
     
  3. Yuriy_Sevastyanov

    Yuriy_Sevastyanov

    Joined:
    Apr 9, 2017
    Posts:
    25
    @mr-gmg Thank you very much.
    I checked the performance of your solution.
    Code (CSharp):
    1. [BurstCompile]
    2. iterations: 10000000
    3. Quaternion.eulerAngles   =>  ~670ms
    4. ToEulerAngles()            =>  ~260ms
     
    layker90524, addent, Nyanpas and 2 others like this.