Math.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. // ----------------------------------------------------------------
  2. // From Game Programming in C++ by Sanjay Madhav
  3. // Copyright (C) 2017 Sanjay Madhav. All rights reserved.
  4. //
  5. // Released under the BSD License
  6. // See LICENSE.txt for full details.
  7. // ----------------------------------------------------------------
  8. #include "Math.h"
  9. const Vector2 Vector2::Zero(0.0f, 0.0f);
  10. const Vector2 Vector2::UnitX(1.0f, 0.0f);
  11. const Vector2 Vector2::UnitY(0.0f, 1.0f);
  12. const Vector2 Vector2::NegUnitX(-1.0f, 0.0f);
  13. const Vector2 Vector2::NegUnitY(0.0f, -1.0f);
  14. const Vector3 Vector3::Zero(0.0f, 0.0f, 0.f);
  15. const Vector3 Vector3::UnitX(1.0f, 0.0f, 0.0f);
  16. const Vector3 Vector3::UnitY(0.0f, 1.0f, 0.0f);
  17. const Vector3 Vector3::UnitZ(0.0f, 0.0f, 1.0f);
  18. const Vector3 Vector3::NegUnitX(-1.0f, 0.0f, 0.0f);
  19. const Vector3 Vector3::NegUnitY(0.0f, -1.0f, 0.0f);
  20. const Vector3 Vector3::NegUnitZ(0.0f, 0.0f, -1.0f);
  21. const Vector3 Vector3::Infinity(Math::Infinity, Math::Infinity, Math::Infinity);
  22. const Vector3 Vector3::NegInfinity(Math::NegInfinity, Math::NegInfinity, Math::NegInfinity);
  23. static float m3Ident[3][3] =
  24. {
  25. { 1.0f, 0.0f, 0.0f },
  26. { 0.0f, 1.0f, 0.0f },
  27. { 0.0f, 0.0f, 1.0f }
  28. };
  29. const Matrix3 Matrix3::Identity(m3Ident);
  30. static float m4Ident[4][4] =
  31. {
  32. { 1.0f, 0.0f, 0.0f, 0.0f },
  33. { 0.0f, 1.0f, 0.0f, 0.0f },
  34. { 0.0f, 0.0f, 1.0f, 0.0f },
  35. { 0.0f, 0.0f, 0.0f, 1.0f }
  36. };
  37. const Matrix4 Matrix4::Identity(m4Ident);
  38. const Quaternion Quaternion::Identity(0.0f, 0.0f, 0.0f, 1.0f);
  39. Vector2 Vector2::Transform(const Vector2& vec, const Matrix3& mat, float w /*= 1.0f*/)
  40. {
  41. Vector2 retVal;
  42. retVal.x = vec.x * mat.mat[0][0] + vec.y * mat.mat[1][0] + w * mat.mat[2][0];
  43. retVal.y = vec.x * mat.mat[0][1] + vec.y * mat.mat[1][1] + w * mat.mat[2][1];
  44. //ignore w since we aren't returning a new value for it...
  45. return retVal;
  46. }
  47. Vector3 Vector3::Transform(const Vector3& vec, const Matrix4& mat, float w /*= 1.0f*/)
  48. {
  49. Vector3 retVal;
  50. retVal.x = vec.x * mat.mat[0][0] + vec.y * mat.mat[1][0] +
  51. vec.z * mat.mat[2][0] + w * mat.mat[3][0];
  52. retVal.y = vec.x * mat.mat[0][1] + vec.y * mat.mat[1][1] +
  53. vec.z * mat.mat[2][1] + w * mat.mat[3][1];
  54. retVal.z = vec.x * mat.mat[0][2] + vec.y * mat.mat[1][2] +
  55. vec.z * mat.mat[2][2] + w * mat.mat[3][2];
  56. //ignore w since we aren't returning a new value for it...
  57. return retVal;
  58. }
  59. // This will transform the vector and renormalize the w component
  60. Vector3 Vector3::TransformWithPerspDiv(const Vector3& vec, const Matrix4& mat, float w /*= 1.0f*/)
  61. {
  62. Vector3 retVal;
  63. retVal.x = vec.x * mat.mat[0][0] + vec.y * mat.mat[1][0] +
  64. vec.z * mat.mat[2][0] + w * mat.mat[3][0];
  65. retVal.y = vec.x * mat.mat[0][1] + vec.y * mat.mat[1][1] +
  66. vec.z * mat.mat[2][1] + w * mat.mat[3][1];
  67. retVal.z = vec.x * mat.mat[0][2] + vec.y * mat.mat[1][2] +
  68. vec.z * mat.mat[2][2] + w * mat.mat[3][2];
  69. float transformedW = vec.x * mat.mat[0][3] + vec.y * mat.mat[1][3] +
  70. vec.z * mat.mat[2][3] + w * mat.mat[3][3];
  71. if (!Math::NearZero(Math::Abs(transformedW)))
  72. {
  73. transformedW = 1.0f / transformedW;
  74. retVal *= transformedW;
  75. }
  76. return retVal;
  77. }
  78. // Transform a Vector3 by a quaternion
  79. Vector3 Vector3::Transform(const Vector3& v, const Quaternion& q)
  80. {
  81. // v + 2.0*cross(q.xyz, cross(q.xyz,v) + q.w*v);
  82. Vector3 qv(q.x, q.y, q.z);
  83. Vector3 retVal = v;
  84. retVal += 2.0f * Vector3::Cross(qv, Vector3::Cross(qv, v) + q.w * v);
  85. return retVal;
  86. }
  87. void Matrix4::Invert()
  88. {
  89. // Thanks slow math
  90. float tmp[12]; /* temp array for pairs */
  91. float src[16]; /* array of transpose source matrix */
  92. float dst[16]; /* storage */
  93. float det; /* determinant */
  94. /* transpose matrix */
  95. // row 1 to col 1
  96. src[0] = mat[0][0];
  97. src[4] = mat[0][1];
  98. src[8] = mat[0][2];
  99. src[12] = mat[0][3];
  100. // row 2 to col 2
  101. src[1] = mat[1][0];
  102. src[5] = mat[1][1];
  103. src[9] = mat[1][2];
  104. src[13] = mat[1][3];
  105. // row 3 to col 3
  106. src[2] = mat[2][0];
  107. src[6] = mat[2][1];
  108. src[10] = mat[2][2];
  109. src[14] = mat[2][3];
  110. // row 4 to col 4
  111. src[3] = mat[3][0];
  112. src[7] = mat[3][1];
  113. src[11] = mat[3][2];
  114. src[15] = mat[3][3];
  115. // for (int i = 0; i < 4; i++) {
  116. // src[i] = mat[i*4];
  117. // src[i + 4] = mat[i*4 + 1];
  118. // src[i + 8] = mat[i*4 + 2];
  119. // src[i + 12] = mat[i*4 + 3];
  120. // }
  121. /* calculate pairs for first 8 elements (cofactors) */
  122. tmp[0] = src[10] * src[15];
  123. tmp[1] = src[11] * src[14];
  124. tmp[2] = src[9] * src[15];
  125. tmp[3] = src[11] * src[13];
  126. tmp[4] = src[9] * src[14];
  127. tmp[5] = src[10] * src[13];
  128. tmp[6] = src[8] * src[15];
  129. tmp[7] = src[11] * src[12];
  130. tmp[8] = src[8] * src[14];
  131. tmp[9] = src[10] * src[12];
  132. tmp[10] = src[8] * src[13];
  133. tmp[11] = src[9] * src[12];
  134. /* calculate first 8 elements (cofactors) */
  135. dst[0] = tmp[0] * src[5] + tmp[3] * src[6] + tmp[4] * src[7];
  136. dst[0] -= tmp[1] * src[5] + tmp[2] * src[6] + tmp[5] * src[7];
  137. dst[1] = tmp[1] * src[4] + tmp[6] * src[6] + tmp[9] * src[7];
  138. dst[1] -= tmp[0] * src[4] + tmp[7] * src[6] + tmp[8] * src[7];
  139. dst[2] = tmp[2] * src[4] + tmp[7] * src[5] + tmp[10] * src[7];
  140. dst[2] -= tmp[3] * src[4] + tmp[6] * src[5] + tmp[11] * src[7];
  141. dst[3] = tmp[5] * src[4] + tmp[8] * src[5] + tmp[11] * src[6];
  142. dst[3] -= tmp[4] * src[4] + tmp[9] * src[5] + tmp[10] * src[6];
  143. dst[4] = tmp[1] * src[1] + tmp[2] * src[2] + tmp[5] * src[3];
  144. dst[4] -= tmp[0] * src[1] + tmp[3] * src[2] + tmp[4] * src[3];
  145. dst[5] = tmp[0] * src[0] + tmp[7] * src[2] + tmp[8] * src[3];
  146. dst[5] -= tmp[1] * src[0] + tmp[6] * src[2] + tmp[9] * src[3];
  147. dst[6] = tmp[3] * src[0] + tmp[6] * src[1] + tmp[11] * src[3];
  148. dst[6] -= tmp[2] * src[0] + tmp[7] * src[1] + tmp[10] * src[3];
  149. dst[7] = tmp[4] * src[0] + tmp[9] * src[1] + tmp[10] * src[2];
  150. dst[7] -= tmp[5] * src[0] + tmp[8] * src[1] + tmp[11] * src[2];
  151. /* calculate pairs for second 8 elements (cofactors) */
  152. tmp[0] = src[2] * src[7];
  153. tmp[1] = src[3] * src[6];
  154. tmp[2] = src[1] * src[7];
  155. tmp[3] = src[3] * src[5];
  156. tmp[4] = src[1] * src[6];
  157. tmp[5] = src[2] * src[5];
  158. tmp[6] = src[0] * src[7];
  159. tmp[7] = src[3] * src[4];
  160. tmp[8] = src[0] * src[6];
  161. tmp[9] = src[2] * src[4];
  162. tmp[10] = src[0] * src[5];
  163. tmp[11] = src[1] * src[4];
  164. /* calculate second 8 elements (cofactors) */
  165. dst[8] = tmp[0] * src[13] + tmp[3] * src[14] + tmp[4] * src[15];
  166. dst[8] -= tmp[1] * src[13] + tmp[2] * src[14] + tmp[5] * src[15];
  167. dst[9] = tmp[1] * src[12] + tmp[6] * src[14] + tmp[9] * src[15];
  168. dst[9] -= tmp[0] * src[12] + tmp[7] * src[14] + tmp[8] * src[15];
  169. dst[10] = tmp[2] * src[12] + tmp[7] * src[13] + tmp[10] * src[15];
  170. dst[10] -= tmp[3] * src[12] + tmp[6] * src[13] + tmp[11] * src[15];
  171. dst[11] = tmp[5] * src[12] + tmp[8] * src[13] + tmp[11] * src[14];
  172. dst[11] -= tmp[4] * src[12] + tmp[9] * src[13] + tmp[10] * src[14];
  173. dst[12] = tmp[2] * src[10] + tmp[5] * src[11] + tmp[1] * src[9];
  174. dst[12] -= tmp[4] * src[11] + tmp[0] * src[9] + tmp[3] * src[10];
  175. dst[13] = tmp[8] * src[11] + tmp[0] * src[8] + tmp[7] * src[10];
  176. dst[13] -= tmp[6] * src[10] + tmp[9] * src[11] + tmp[1] * src[8];
  177. dst[14] = tmp[6] * src[9] + tmp[11] * src[11] + tmp[3] * src[8];
  178. dst[14] -= tmp[10] * src[11] + tmp[2] * src[8] + tmp[7] * src[9];
  179. dst[15] = tmp[10] * src[10] + tmp[4] * src[8] + tmp[9] * src[9];
  180. dst[15] -= tmp[8] * src[9] + tmp[11] * src[10] + tmp[5] * src[8];
  181. /* calculate determinant */
  182. det = src[0] * dst[0] + src[1] * dst[1] + src[2] * dst[2] + src[3] * dst[3];
  183. /* calculate matrix inverse */
  184. det = 1 / det;
  185. for (int j = 0; j < 16; j++)
  186. dst[j] *= det;
  187. // Set it back
  188. for (int i = 0; i < 4; i++)
  189. {
  190. for (int j = 0; j < 4; j++)
  191. {
  192. mat[i][j] = dst[i * 4 + j];
  193. }
  194. }
  195. }
  196. Matrix4 Matrix4::CreateFromQuaternion(const class Quaternion& q)
  197. {
  198. float mat[4][4];
  199. mat[0][0] = 1.0f - 2.0f * q.y * q.y - 2.0f * q.z * q.z;
  200. mat[0][1] = 2.0f * q.x * q.y + 2.0f * q.w * q.z;
  201. mat[0][2] = 2.0f * q.x * q.z - 2.0f * q.w * q.y;
  202. mat[0][3] = 0.0f;
  203. mat[1][0] = 2.0f * q.x * q.y - 2.0f * q.w * q.z;
  204. mat[1][1] = 1.0f - 2.0f * q.x * q.x - 2.0f * q.z * q.z;
  205. mat[1][2] = 2.0f * q.y * q.z + 2.0f * q.w * q.x;
  206. mat[1][3] = 0.0f;
  207. mat[2][0] = 2.0f * q.x * q.z + 2.0f * q.w * q.y;
  208. mat[2][1] = 2.0f * q.y * q.z - 2.0f * q.w * q.x;
  209. mat[2][2] = 1.0f - 2.0f * q.x * q.x - 2.0f * q.y * q.y;
  210. mat[2][3] = 0.0f;
  211. mat[3][0] = 0.0f;
  212. mat[3][1] = 0.0f;
  213. mat[3][2] = 0.0f;
  214. mat[3][3] = 1.0f;
  215. return Matrix4(mat);
  216. }