ARUtilityFunctions.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. 
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using UnityEngine;
  7. namespace Nxr.Internal
  8. {
  9. public static class ARUtilityFunctions
  10. {
  11. /// <summary>
  12. /// Returns the named camera or null if not found.
  13. /// </summary>
  14. /// <param name="name">Camera name to search for.</param>
  15. /// <returns>The named <see cref="Camera"/> or null if not found.</returns>
  16. public static Camera FindCameraByName(string name)
  17. {
  18. foreach (Camera c in Camera.allCameras)
  19. {
  20. if (c.gameObject.name == name) return c;
  21. }
  22. return null;
  23. }
  24. /// <summary>
  25. /// Creates a Unity matrix from an array of floats.
  26. /// </summary>
  27. /// <param name="values">Array of 16 floats to populate the matrix.</param>
  28. /// <returns>A new <see cref="Matrix4x4"/> with the given values.</returns>
  29. public static Matrix4x4 MatrixFromFloatArray(float[] values)
  30. {
  31. if (values == null || values.Length < 16) throw new ArgumentException("Expected 16 elements in values array", "values");
  32. Matrix4x4 mat = new Matrix4x4();
  33. for (int i = 0; i < 16; i++) mat[i] = values[i];
  34. return mat;
  35. }
  36. #if false
  37. // Posted on: http://answers.unity3d.com/questions/11363/converting-matrix4x4-to-quaternion-vector3.html
  38. public static Quaternion QuaternionFromMatrix(Matrix4x4 m)
  39. {
  40. // Adapted from: http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
  41. Quaternion q = new Quaternion();
  42. q.w = Mathf.Sqrt(Mathf.Max(0, 1 + m[0, 0] + m[1, 1] + m[2, 2])) / 2;
  43. q.x = Mathf.Sqrt(Mathf.Max(0, 1 + m[0, 0] - m[1, 1] - m[2, 2])) / 2;
  44. q.y = Mathf.Sqrt(Mathf.Max(0, 1 - m[0, 0] + m[1, 1] - m[2, 2])) / 2;
  45. q.z = Mathf.Sqrt(Mathf.Max(0, 1 - m[0, 0] - m[1, 1] + m[2, 2])) / 2;
  46. q.x *= Mathf.Sign(q.x * (m[2, 1] - m[1, 2]));
  47. q.y *= Mathf.Sign(q.y * (m[0, 2] - m[2, 0]));
  48. q.z *= Mathf.Sign(q.z * (m[1, 0] - m[0, 1]));
  49. return q;
  50. }
  51. #else
  52. public static Quaternion QuaternionFromMatrix(Matrix4x4 m)
  53. {
  54. if(float.IsNaN(m[0]) || float.IsNaN(m[5]))
  55. {
  56. Debug.LogError("QuaternionFromMatrix is NaN !!!");
  57. return Quaternion.identity;
  58. }
  59. // Trap the case where the matrix passed in has an invalid rotation submatrix.
  60. if (m.GetColumn(2) == Vector4.zero)
  61. {
  62. return Quaternion.identity;
  63. }
  64. return Quaternion.LookRotation(m.GetColumn(2), m.GetColumn(1));
  65. }
  66. #endif
  67. public static Vector3 PositionFromMatrix(Matrix4x4 m)
  68. {
  69. Vector3 posVec = m.GetColumn(3);
  70. if(float.IsNaN(posVec.x) || float.IsNaN(posVec.y) || float.IsNaN(posVec.z))
  71. {
  72. Debug.LogError("PositionFromMatrix is NaN !!!");
  73. return Vector3.zero;
  74. }
  75. return posVec;
  76. }
  77. // Convert from right-hand coordinate system with <normal vector> in direction of +x,
  78. // <orthorgonal vector> in direction of +y, and <approach vector> in direction of +z,
  79. // to Unity's left-hand coordinate system with <normal vector> in direction of +x,
  80. // <orthorgonal vector> in direction of +y, and <approach vector> in direction of +z.
  81. // This is equivalent to negating row 2, and then negating column 2.
  82. public static Matrix4x4 LHMatrixFromRHMatrix(Matrix4x4 rhm)
  83. {
  84. Matrix4x4 lhm = new Matrix4x4(); ;
  85. // Column 0.
  86. lhm[0, 0] = rhm[0, 0];
  87. lhm[1, 0] = rhm[1, 0];
  88. lhm[2, 0] = -rhm[2, 0];
  89. lhm[3, 0] = rhm[3, 0];
  90. // Column 1.
  91. lhm[0, 1] = rhm[0, 1];
  92. lhm[1, 1] = rhm[1, 1];
  93. lhm[2, 1] = -rhm[2, 1];
  94. lhm[3, 1] = rhm[3, 1];
  95. // Column 2.
  96. lhm[0, 2] = -rhm[0, 2];
  97. lhm[1, 2] = -rhm[1, 2];
  98. lhm[2, 2] = rhm[2, 2];
  99. lhm[3, 2] = -rhm[3, 2];
  100. // Column 3.
  101. lhm[0, 3] = rhm[0, 3];
  102. lhm[1, 3] = rhm[1, 3];
  103. lhm[2, 3] = -rhm[2, 3];
  104. lhm[3, 3] = rhm[3, 3];
  105. return lhm;
  106. }
  107. //test
  108. //float[] cameraMatrix = new float[] { 678.29388f, 637.77411f, 318.29779f, 237.90047f };
  109. //projectionMatrix = ARUtilityFunctions.GetGLProjectionMatrix(0.01f, 1000f, cameraMatrix, 1920, 1080);
  110. //test
  111. // 相机内部矩阵转换成GL投影矩阵
  112. public static Matrix4x4 GetGLProjectionMatrix(float near, float far, float[] cameraMatrix, int cameraPreviewWidth, int cameraPreviewHeight)
  113. //-----------------------------------------------------------------------------
  114. {
  115. // float near = 0.01; // Near clipping distance
  116. // float far = 1000; // Far clipping distance
  117. float f_x = cameraMatrix[0]; // Focal length in x axis
  118. float f_y = cameraMatrix[1]; // Focal length in y axis (usually the same?)
  119. float c_x = cameraMatrix[2]; // Camera primary point x
  120. float c_y = cameraMatrix[3]; // Camera primary point y
  121. float[] glMatrix = new float[16];
  122. glMatrix[0] = 2.0f * f_x / cameraPreviewWidth;
  123. glMatrix[1] = 0.0f;
  124. glMatrix[2] = 0.0f;
  125. glMatrix[3] = 0.0f;
  126. glMatrix[4] = 0.0f;
  127. glMatrix[5] = 2.0f * f_y / cameraPreviewHeight;
  128. glMatrix[6] = 0.0f;
  129. glMatrix[7] = 0.0f;
  130. glMatrix[8] = 1.0f - 2.0f * c_x / cameraPreviewWidth;
  131. glMatrix[9] = -1.0f + 2.0f * c_y / cameraPreviewHeight;
  132. glMatrix[10] = -(far + near) / (far - near);
  133. glMatrix[11] = -1.0f;
  134. glMatrix[12] = 0.0f;
  135. glMatrix[13] = 0.0f;
  136. glMatrix[14] = -2.0f * far * near / (far - near);
  137. glMatrix[15] = 0.0f;
  138. return MatrixFromFloatArray(glMatrix);
  139. }
  140. }
  141. }