ConversionUtility.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /****************************************************************************
  2. * Copyright 2019 Nreal Techonology Limited. All rights reserved.
  3. *
  4. * This file is part of NRSDK.
  5. *
  6. * https://www.nreal.ai/
  7. *
  8. *****************************************************************************/
  9. namespace NRKernal
  10. {
  11. using UnityEngine;
  12. /// <summary> A conversion utility. </summary>
  13. public class ConversionUtility
  14. {
  15. #region transform utility
  16. /// <summary> Get a matrix from position and rotation. </summary>
  17. /// <param name="position"> The position.</param>
  18. /// <param name="rotation"> The rotation.</param>
  19. /// <returns> The matrix. </returns>
  20. public static Matrix4x4 GetTMatrix(Vector3 position, Quaternion rotation)
  21. {
  22. return Matrix4x4.TRS(position, rotation, Vector3.one);
  23. }
  24. /// <summary> Get a matrix from position , rotation and scale. </summary>
  25. /// <param name="position"> The position.</param>
  26. /// <param name="rotation"> The rotation.</param>
  27. /// <param name="scale"> The scale.</param>
  28. /// <returns> The matrix. </returns>
  29. public static Matrix4x4 GetTMatrix(Vector3 position, Quaternion rotation, Vector3 scale)
  30. {
  31. return Matrix4x4.TRS(position, rotation, scale);
  32. }
  33. /// <summary> Get the position from a matrix4x4. </summary>
  34. /// <param name="matrix"> The matrix.</param>
  35. /// <returns> The position from t matrix. </returns>
  36. public static Vector3 GetPositionFromTMatrix(Matrix4x4 matrix)
  37. {
  38. Vector3 position;
  39. position.x = matrix.m03;
  40. position.y = matrix.m13;
  41. position.z = matrix.m23;
  42. return position;
  43. }
  44. /// <summary> Get the rotation from a matrix4x4. </summary>
  45. /// <param name="matrix"> The matrix.</param>
  46. /// <returns> The rotation from t matrix. </returns>
  47. public static Quaternion GetRotationFromTMatrix(Matrix4x4 matrix)
  48. {
  49. Vector3 forward;
  50. forward.x = matrix.m02;
  51. forward.y = matrix.m12;
  52. forward.z = matrix.m22;
  53. Vector3 upwards;
  54. upwards.x = matrix.m01;
  55. upwards.y = matrix.m11;
  56. upwards.z = matrix.m21;
  57. return Quaternion.LookRotation(forward, upwards);
  58. }
  59. /// <summary> Convert position. </summary>
  60. /// <param name="vec"> The vector.</param>
  61. /// <returns> The position converted. </returns>
  62. public static Vector3 ConvertPosition(Vector3 vec)
  63. {
  64. // Convert to left-handed
  65. return new Vector3((float)vec.x, (float)vec.y, (float)-vec.z);
  66. }
  67. /// <summary> Convert orientation. </summary>
  68. /// <param name="quat"> The quaternion.</param>
  69. /// <returns> The orientation converted. </returns>
  70. public static Quaternion ConvertOrientation(Quaternion quat)
  71. {
  72. // Convert to left-handed
  73. return new Quaternion(-(float)quat.x, -(float)quat.y, (float)quat.z, (float)quat.w);
  74. }
  75. #endregion
  76. /// <summary> Unity pose to API pose. </summary>
  77. /// <param name="unityPose"> [out] The unity pose.</param>
  78. /// <param name="apiPose"> [out] The API pose.</param>
  79. public static void UnityPoseToApiPose(Pose unityPose, out NativeMat4f apiPose)
  80. {
  81. Matrix4x4 glWorld_T_glLocal = Matrix4x4.TRS(unityPose.position, unityPose.rotation, Vector3.one);
  82. Matrix4x4 unityWorld_T_glWorld = Matrix4x4.Scale(new Vector3(1, 1, -1));
  83. Matrix4x4 unityWorld_T_unityLocal = unityWorld_T_glWorld * glWorld_T_glLocal * unityWorld_T_glWorld.inverse;
  84. Vector3 position = unityWorld_T_unityLocal.GetColumn(3);
  85. Quaternion rotation = Quaternion.LookRotation(unityWorld_T_unityLocal.GetColumn(2),
  86. unityWorld_T_unityLocal.GetColumn(1));
  87. Matrix4x4 matrix = Matrix4x4.TRS(position, rotation, Vector3.one);
  88. apiPose = new NativeMat4f(matrix);
  89. }
  90. /// <summary> API pose to unity pose. </summary>
  91. /// <param name="apiPose"> The API pose.</param>
  92. /// <param name="unityPose"> [out] The unity pose.</param>
  93. public static void ApiPoseToUnityPose(NativeMat4f apiPose, out Pose unityPose)
  94. {
  95. Matrix4x4 glWorld_T_glLocal = apiPose.ToUnityMat4f();
  96. Matrix4x4 unityWorld_T_glWorld = Matrix4x4.Scale(new Vector3(1, 1, -1));
  97. Matrix4x4 unityWorld_T_unityLocal = unityWorld_T_glWorld * glWorld_T_glLocal * unityWorld_T_glWorld.inverse;
  98. Vector3 position = unityWorld_T_unityLocal.GetColumn(3);
  99. Quaternion rotation = unityWorld_T_unityLocal.rotation;
  100. unityPose = new Pose(position, rotation);
  101. }
  102. /// <summary> API pose to unity matrix. </summary>
  103. /// <param name="apiPose"> The API pose.</param>
  104. /// <param name="unityMatrix"> [out] The unity matrix.</param>
  105. public static void ApiPoseToUnityMatrix(NativeMat4f apiPose, out Matrix4x4 unityMatrix)
  106. {
  107. Matrix4x4 glWorld_T_glLocal = apiPose.ToUnityMat4f();
  108. Matrix4x4 unityWorld_T_glWorld = Matrix4x4.Scale(new Vector3(1, 1, -1));
  109. Matrix4x4 unityWorld_T_unityLocal = unityWorld_T_glWorld * glWorld_T_glLocal * unityWorld_T_glWorld.inverse;
  110. unityMatrix = unityWorld_T_unityLocal;
  111. }
  112. /// <summary> Gets projection matrix from fov. </summary>
  113. /// <param name="fov"> The fov.</param>
  114. /// <param name="z_near"> The near.</param>
  115. /// <param name="z_far"> The far.</param>
  116. /// <returns> The projection matrix from fov. </returns>
  117. public static NativeMat4f GetProjectionMatrixFromFov(NativeFov4f fov, float z_near, float z_far)
  118. {
  119. NativeMat4f pm = NativeMat4f.identity;
  120. float l = fov.left_tan;
  121. float r = fov.right_tan;
  122. float t = fov.top_tan;
  123. float b = fov.bottom_tan;
  124. pm.column0.X = 2f / (r - l);
  125. pm.column1.Y = 2f / (t - b);
  126. pm.column2.X = (r + l) / (r - l);
  127. pm.column2.Y = (t + b) / (t - b);
  128. pm.column2.Z = (z_near + z_far) / (z_near - z_far);
  129. pm.column2.W = -1f;
  130. pm.column3.Z = (2 * z_near * z_far) / (z_near - z_far);
  131. pm.column3.W = 0f;
  132. return pm;
  133. }
  134. public static Pose ApiWorldToUnityWorld(Pose apiworld)
  135. {
  136. Matrix4x4 world_offse_matrix = NRFrame.GetWorldMatrixFromUnityToNative();
  137. Matrix4x4 native_pose_matrix = world_offse_matrix * Matrix4x4.TRS(apiworld.position, apiworld.rotation, Vector3.one);
  138. return new Pose(ConversionUtility.GetPositionFromTMatrix(native_pose_matrix), ConversionUtility.GetRotationFromTMatrix(native_pose_matrix));
  139. }
  140. public static Matrix4x4 UnityPoseToCVMatrix(Pose unityPose)
  141. {
  142. Matrix4x4 unityMat = GetTMatrix(unityPose.position, unityPose.rotation);
  143. Matrix4x4 cv_T_unity = Matrix4x4.Scale(new Vector3(1, -1, 1));
  144. Matrix4x4 cvWorld = cv_T_unity * unityMat * cv_T_unity.inverse;
  145. return cvWorld;
  146. }
  147. public static Matrix4x4 UnityMatrixToCVMatrix(Matrix4x4 unityMat)
  148. {
  149. Matrix4x4 cv_T_unity = Matrix4x4.Scale(new Vector3(1, -1, 1));
  150. Matrix4x4 cvWorld = cv_T_unity * unityMat * cv_T_unity.inverse;
  151. return cvWorld;
  152. }
  153. }
  154. }