title: How to convert Euler Rotations from one Coordinate System to another? Right Handed Y-up to Left handed Z-up
body: <p>I wrote a plugin for UE4 for matching and spawning Static Mesh Actors into the level of UE4.<br>
  The plugin reads coordinates from a text file (Scale,Rotation,Transformation) which are exported from Softimage XSI per script. Everything works already. BUT not the Rotations.</p>
  
  <p>I know it has something to do with the coordinate system.
  But how exactly do i convert from one to the other?</p>
  
  <p>What i think that i found out so far (not 100% sure)<br>
  XSI is Right handed Y-up , Rotation Order XYZ <br>
  UE4 is Left handed Z-up, Rotation Order XZY<br></p>
  
  <p>In both applications i have Euler angles in degrees.<br>
  So in my 3D software (Softimage XSI) i have XYZ degrees which i store to a text file on disk.<br> 
  Line by line where each line is an object.<br>
  In UE4 the plugin reads this lines and spawns an SM Actor to the level.</p>
  
  <p>+++++ New Information +++++<br></p>
  
  <p>Hello, thanks for the answers so far!<br></p>
  
  <p>I made a video to show the details, and to show the circumstances.<br></p>
  
  <p><a href="https://www.youtube.com/watch?v=sWX84FxZTw0" rel="nofollow noreferrer">https://www.youtube.com/watch?v=sWX84FxZTw0</a></p>
  
  <p><br>
  +++++ The Actor spawn function +++++<br></p>
  
  <pre><code>void SpawnSMActor(const TCHAR *path,float sX,float sY,float sZ,float rX,float rY,float rZ,float pX,float pY,float pZ) 
  {
      // Load Static Mesh from given Reference Path from UE4 Explorer
      UStaticMesh* StaMesh = LoadObject&lt;UStaticMesh&gt;(nullptr, path);
  
      // Transform
      FVector objectScale(sX, sY, sZ);        // Scale
  
      // ********************************************************************************
      // Conversion XSI Coordinate System to UE4 Coordinate System
  
      FVector NewPosition;
      FRotator NewRotation;
  
      // We just simply swap the Z and Y Coordinates
  
      NewPosition.X = pX * 100; //    TX
      NewPosition.Y = pZ * 100; //    TZ
      NewPosition.Z = pY * 100; //    TY
  
      // We just simply swap the Pitch(Y) and Yaw(Z) angles
  
      NewRotation.Roll =  rX;     //  RX
      NewRotation.Pitch = rZ;     //  RZ
      NewRotation.Yaw =   -rY;    //  RY
  
      FRotator NewobjectRotation(NewRotation.Quaternion());
  
      FTransform objectTransform(NewobjectRotation, NewPosition, objectScale);
  
      // ********************************************************************************
  
      // Creating the Actor and Positioning it in the World based on the Static Mesh
      UWorld* currentWorld = GEditor-&gt;GetEditorWorldContext().World();
      ULevel* currentLevel = currentWorld-&gt;GetCurrentLevel();
      UClass* StaticMeshClass = AStaticMeshActor::StaticClass();
      AActor* NewActorCreated = GEditor-&gt;AddActor(currentLevel, StaticMeshClass, objectTransform, true, RF_Public | RF_Standalone | RF_Transactional);
      AStaticMeshActor* smActor = Cast&lt;AStaticMeshActor&gt;(NewActorCreated);
  
      smActor-&gt;GetStaticMeshComponent()-&gt;SetStaticMesh(StaMesh);
      smActor-&gt;SetActorScale3D(objectScale);
  
      // ID Name &amp; Visible Name
      //smActor-&gt;Rename(TEXT("MyStaticMeshInTheWorld"));
      //smActor-&gt;SetActorLabel("MyStaticMeshInTheWorld");
  
      GEditor-&gt;EditorUpdateComponents();
      smActor-&gt;GetStaticMeshComponent()-&gt;RegisterComponentWithWorld(currentWorld);
      currentWorld-&gt;UpdateWorldComponents(true, false);
      smActor-&gt;RerunConstructionScripts();
      GLevelEditorModeTools().MapChangeNotify();
  }
  </code></pre>
  
  <p><br>
  If i rotate an object in my 3D app by 45 degree clockwise on the UP axis<br> and 45 degree on the X-axis i get:<br><br>
  X -54,7356 °<br>
  Y -30 °<br>
  Z 35,2644 °<br><br></p>
  
  <p>If i do the same Rotations in UE4 i get:<br><br>
  X -35,2644 °<br>
  Y 30 °<br>
  Z 35,2644 °<br><br></p>
  
  <p>So those would be the correct rotation angles in UE4!<br></p>
  
  <p>But with the code listed above i get:<br><br></p>
  
  <p>X -54,7355 °<br>
  Y 35,2643 °<br>
  Z 30 °<br><br></p>
  
  <p>And thats wrong! Because it just flips some positions as it seems. The angles are essentialy the same as from my 3D app.</p>
  
  <p><a href="https://i.imgur.com/zEVe7JP.png" rel="nofollow noreferrer">Picture</a><br>
  <br>
  <br></p>
  
  <hr>
  
  <p>Here is my second attempt to solve the conversion without the UE4 API.<br>
  I know its not complete and i still dont fully understand the steps i will have to take.<br></p>
  
  <p>But its hopefully a start.<br>
  As @DavidC.Rankin menntioned above i need to define the (1) the original coordinate system.<br>
  Not sure if this is what is necessary but i put the info from Wikipedia about Euler to matrix in C++ code.<br>
  This are all 6 of the Tait–Bryan angles matrices: <br>
  Is this correct? And if so how will i define<br>
  (2) the target coordinate system ?<br> 
  (3) the order of rotations ?<br><br></p>
  
  <pre><code>#include "pch.h"
  #include &lt;iostream&gt;
  #include &lt;string&gt;
  #include "linalg.h"
  using namespace linalg::aliases;
  using namespace std;
  
  float x,y,z;
  
  //Pre
  
  void MatrixXZY(float3 angles, float3x3&amp; matrix);
  void MatrixXYZ(float3 angles, float3x3&amp; matrix);
  void MatrixYXZ(float3 angles, float3x3&amp; matrix);
  void MatrixYZX(float3 angles, float3x3&amp; matrix);
  void MatrixZYX(float3 angles, float3x3&amp; matrix);
  void MatrixZXY(float3 angles, float3x3&amp; matrix);
  
  void PrintMatrix(string name, float3 angles, float3x3&amp; matrix);
  void MatrixDecomposeYXZ(float3x3&amp; matrix, float3&amp; angles);
  
  
  
  
  int main()
  {
      float3 AnglesIn = { 0, 0, 0 };
      float3 AnglesOut;
      float3x3 Matrix;  // Matrix [Spalte][Zeile]
  
      cout &lt;&lt; "-----------------------------" &lt;&lt; endl;
      cout &lt;&lt; "Input" &lt;&lt; endl;
      cout &lt;&lt; AnglesIn[0] &lt;&lt; " " &lt;&lt; AnglesIn[1] &lt;&lt; " " &lt;&lt; AnglesIn[2] &lt;&lt; " " &lt;&lt; endl;
      cout &lt;&lt; "-----------------------------" &lt;&lt; endl &lt;&lt; endl;
  
      MatrixXZY(AnglesIn, Matrix);
      PrintMatrix("XZY", AnglesIn, Matrix);
      MatrixXYZ(AnglesIn, Matrix);
      PrintMatrix("XYZ", AnglesIn, Matrix);
  
      MatrixYXZ(AnglesIn, Matrix);
      PrintMatrix("YXZ", AnglesIn, Matrix);
      MatrixDecomposeYXZ(Matrix, AnglesOut);
      cout &lt;&lt; "-----------------------------" &lt;&lt; endl;
      cout &lt;&lt; AnglesOut.x &lt;&lt; " " &lt;&lt; AnglesOut.y &lt;&lt; " " &lt;&lt; AnglesOut.z &lt;&lt; " " &lt;&lt; endl;
      cout &lt;&lt; "-----------------------------" &lt;&lt; endl &lt;&lt; endl;
  
  
      MatrixYZX(AnglesIn, Matrix);
      PrintMatrix("YZX", AnglesIn, Matrix);
  
      MatrixZYX(AnglesIn, Matrix);
      PrintMatrix("ZYX", AnglesIn, Matrix);
      MatrixZXY(AnglesIn, Matrix);
      PrintMatrix("ZXY", AnglesIn, Matrix);
  
  }
  
  
  
  void MatrixXZY(float3 angles, float3x3&amp; matrix)
  {
      float cosX = cosf(angles.x);     // X
      float sinX = sinf(angles.x);
  
      float cosY = cosf(angles.y);     // Y
      float sinY = sinf(angles.y);
  
      float cosZ = cosf(angles.z);     // Z
      float sinZ = sinf(angles.z);
  
  
      matrix[0][0] = cosZ * cosY;                         // Spalte 1
      matrix[0][1] = sinX * sinY + cosX * cosY * sinZ;
      matrix[0][2] = cosY * sinX * sinZ - cosX * sinY;
  
      matrix[1][0] = -sinZ;                               // Spalte 2
      matrix[1][1] = cosX * cosZ;
      matrix[1][2] = cosZ * sinX;
  
      matrix[2][0] = cosZ * sinY;                         // Spalte 3
      matrix[2][1] = cosX * sinZ * sinY - cosY * sinX;
      matrix[2][2] = cosX * cosY + sinX * sinZ * sinY;
  
  }
  void MatrixXYZ(float3 angles, float3x3&amp; matrix)
  {
      float cosX = cosf(angles.x);     // X
      float sinX = sinf(angles.x);
  
      float cosY = cosf(angles.y);     // Y
      float sinY = sinf(angles.y);
  
      float cosZ = cosf(angles.z);     // Z
      float sinZ = sinf(angles.z);
  
  
      matrix[0][0] = cosY * cosZ;                         // Spalte 1
      matrix[0][1] = cosX * sinZ + cosZ * sinX * sinY;
      matrix[0][2] = sinX * sinZ - cosX * cosZ * sinY;
  
      matrix[1][0] = -cosY * sinZ;                        // Spalte 2
      matrix[1][1] = cosX * cosZ - sinX * sinY * sinZ;
      matrix[1][2] = cosZ * sinX + cosX * sinY * sinZ;
  
      matrix[2][0] = sinY;                                // Spalte 3
      matrix[2][1] = -cosY * sinX;
      matrix[2][2] = cosX * cosY;
  
  }
  
  void MatrixYXZ(float3 angles, float3x3&amp; matrix)
  {
      float cosX = cosf(angles.x);     // X
      float sinX = sinf(angles.x);
  
      float cosY = cosf(angles.y);     // Y
      float sinY = sinf(angles.y);
  
      float cosZ = cosf(angles.z);     // Z
      float sinZ = sinf(angles.z);
  
      matrix[0][0] = cosY * cosZ + sinY * sinX * sinZ;    // Spalte 1
      matrix[0][1] = cosX * sinZ;
      matrix[0][2] = cosY * sinX * sinZ - cosZ * sinY;
  
      matrix[1][0] = cosZ * sinY * sinX - cosY * sinZ;    // Spalte 2
      matrix[1][1] = cosX * cosZ;
      matrix[1][2] = cosY * cosZ * sinX + sinY * sinZ;
  
      matrix[2][0] = cosX * sinY;                         // Spalte 3
      matrix[2][1] = -sinX;
      matrix[2][2] = cosY * cosX;
  
  }
  void MatrixYZX(float3 angles, float3x3&amp; matrix)
  {
      float cosX = cosf(angles.x);     // X
      float sinX = sinf(angles.x);
  
      float cosY = cosf(angles.y);     // Y
      float sinY = sinf(angles.y);
  
      float cosZ = cosf(angles.z);     // Z
      float sinZ = sinf(angles.z);
  
  
      matrix[0][0] = cosY * cosZ;                         // Spalte 1
      matrix[0][1] = sinZ;
      matrix[0][2] = -cosZ * sinY;
  
      matrix[1][0] = sinY * sinX - cosY * cosX * sinZ;    // Spalte 2
      matrix[1][1] = cosZ * cosX;
      matrix[1][2] = cosY * sinX + cosX * sinY * sinZ;
  
      matrix[2][0] = cosX * sinY + cosY * sinZ * sinX;    // Spalte 3
      matrix[2][1] = -cosZ * sinX;
      matrix[2][2] = cosY * cosX - sinY * sinZ * sinX;
  
  }
  
  void MatrixZYX(float3 angles, float3x3&amp; matrix)
  {
      float cosX = cosf(angles.x);     // X
      float sinX = sinf(angles.x);
  
      float cosY = cosf(angles.y);     // Y
      float sinY = sinf(angles.y);
  
      float cosZ = cosf(angles.z);     // Z
      float sinZ = sinf(angles.z);
  
  
      matrix[0][0] = cosZ * cosY;                         // Spalte 1
      matrix[0][1] = cosY * sinZ;
      matrix[0][2] = -sinY;
  
      matrix[1][0] = cosZ * sinY * sinX - cosX * sinZ;    // Spalte 2
      matrix[1][1] = cosZ * cosX + sinZ * sinY * sinX;
      matrix[1][2] = cosY * sinX;
  
      matrix[2][0] = sinZ * sinX + cosZ * cosX * sinY;    // Spalte 3
      matrix[2][1] = cosX * sinZ * sinY - cosZ * sinX;
      matrix[2][2] = cosY * cosX;
  
  }
  void MatrixZXY(float3 angles, float3x3&amp; matrix)
  {
      float cosX = cosf(angles.x);     // X
      float sinX = sinf(angles.x);
  
      float cosY = cosf(angles.y);     // Y
      float sinY = sinf(angles.y);
  
      float cosZ = cosf(angles.z);     // Z
      float sinZ = sinf(angles.z);
  
  
      matrix[0][0] = cosZ * cosY - sinZ * sinX * sinY;        // Spalte 1
      matrix[0][1] = cosY * sinZ + cosZ * sinX * sinY;
      matrix[0][2] = -cosX * sinY;
  
      matrix[1][0] = -cosX * sinZ;                            // Spalte 2
      matrix[1][1] = cosZ * cosX;
      matrix[1][2] = sinX;
  
      matrix[2][0] = cosZ * sinY + cosY * sinZ * sinX;        // Spalte 3
      matrix[2][1] = sinZ * sinY - cosZ * cosY * sinX;
      matrix[2][2] = cosX * cosY;
  
  }
  
  
  void PrintMatrix(string name, float3 angles, float3x3&amp; matrix)
  {
      cout &lt;&lt; "-----------------------------" &lt;&lt; endl;
      cout &lt;&lt; name &lt;&lt; "-Matrix" &lt;&lt; endl;
      cout &lt;&lt; "-----------------------------" &lt;&lt; endl;
  
      cout &lt;&lt; matrix[0][0] &lt;&lt; " " &lt;&lt; matrix[1][0] &lt;&lt; " " &lt;&lt; matrix[2][0] &lt;&lt; " " &lt;&lt; endl;
      cout &lt;&lt; matrix[0][1] &lt;&lt; " " &lt;&lt; matrix[1][1] &lt;&lt; " " &lt;&lt; matrix[2][1] &lt;&lt; " " &lt;&lt; endl;
      cout &lt;&lt; matrix[0][2] &lt;&lt; " " &lt;&lt; matrix[1][2] &lt;&lt; " " &lt;&lt; matrix[2][2] &lt;&lt; " " &lt;&lt; endl;
      cout &lt;&lt; "-----------------------------" &lt;&lt; endl &lt;&lt; endl &lt;&lt; endl;
  }
  
  
  
  void MatrixDecomposeYXZ(float3x3&amp; matrix, float3&amp; angles)
  {
      angles.x = asinf(-matrix[2][1]);                        //              X
      if (cosf(angles.x) &gt; 0.0001)                            // Not at poles X
      {
          angles.y = atan2f(matrix[2][0], matrix[2][2]);      //              Y
          angles.z = atan2f(matrix[0][1], matrix[1][1]);      //              Z
      }
      else
      {
          angles.y = 0.0f;                                    //              Y
          angles.z = atan2f(-matrix[1][0], matrix[0][0]);     //              Z
      }
  }
  </code></pre>