2
0

Math.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  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 in root directory 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. // This is a really janky way to unroll everything...
  91. float tmp[12];
  92. float src[16];
  93. float dst[16];
  94. float det;
  95. // Transpose matrix
  96. // row 1 to col 1
  97. src[0] = mat[0][0];
  98. src[4] = mat[0][1];
  99. src[8] = mat[0][2];
  100. src[12] = mat[0][3];
  101. // row 2 to col 2
  102. src[1] = mat[1][0];
  103. src[5] = mat[1][1];
  104. src[9] = mat[1][2];
  105. src[13] = mat[1][3];
  106. // row 3 to col 3
  107. src[2] = mat[2][0];
  108. src[6] = mat[2][1];
  109. src[10] = mat[2][2];
  110. src[14] = mat[2][3];
  111. // row 4 to col 4
  112. src[3] = mat[3][0];
  113. src[7] = mat[3][1];
  114. src[11] = mat[3][2];
  115. src[15] = mat[3][3];
  116. // Calculate cofactors
  117. tmp[0] = src[10] * src[15];
  118. tmp[1] = src[11] * src[14];
  119. tmp[2] = src[9] * src[15];
  120. tmp[3] = src[11] * src[13];
  121. tmp[4] = src[9] * src[14];
  122. tmp[5] = src[10] * src[13];
  123. tmp[6] = src[8] * src[15];
  124. tmp[7] = src[11] * src[12];
  125. tmp[8] = src[8] * src[14];
  126. tmp[9] = src[10] * src[12];
  127. tmp[10] = src[8] * src[13];
  128. tmp[11] = src[9] * src[12];
  129. dst[0] = tmp[0] * src[5] + tmp[3] * src[6] + tmp[4] * src[7];
  130. dst[0] -= tmp[1] * src[5] + tmp[2] * src[6] + tmp[5] * src[7];
  131. dst[1] = tmp[1] * src[4] + tmp[6] * src[6] + tmp[9] * src[7];
  132. dst[1] -= tmp[0] * src[4] + tmp[7] * src[6] + tmp[8] * src[7];
  133. dst[2] = tmp[2] * src[4] + tmp[7] * src[5] + tmp[10] * src[7];
  134. dst[2] -= tmp[3] * src[4] + tmp[6] * src[5] + tmp[11] * src[7];
  135. dst[3] = tmp[5] * src[4] + tmp[8] * src[5] + tmp[11] * src[6];
  136. dst[3] -= tmp[4] * src[4] + tmp[9] * src[5] + tmp[10] * src[6];
  137. dst[4] = tmp[1] * src[1] + tmp[2] * src[2] + tmp[5] * src[3];
  138. dst[4] -= tmp[0] * src[1] + tmp[3] * src[2] + tmp[4] * src[3];
  139. dst[5] = tmp[0] * src[0] + tmp[7] * src[2] + tmp[8] * src[3];
  140. dst[5] -= tmp[1] * src[0] + tmp[6] * src[2] + tmp[9] * src[3];
  141. dst[6] = tmp[3] * src[0] + tmp[6] * src[1] + tmp[11] * src[3];
  142. dst[6] -= tmp[2] * src[0] + tmp[7] * src[1] + tmp[10] * src[3];
  143. dst[7] = tmp[4] * src[0] + tmp[9] * src[1] + tmp[10] * src[2];
  144. dst[7] -= tmp[5] * src[0] + tmp[8] * src[1] + tmp[11] * src[2];
  145. tmp[0] = src[2] * src[7];
  146. tmp[1] = src[3] * src[6];
  147. tmp[2] = src[1] * src[7];
  148. tmp[3] = src[3] * src[5];
  149. tmp[4] = src[1] * src[6];
  150. tmp[5] = src[2] * src[5];
  151. tmp[6] = src[0] * src[7];
  152. tmp[7] = src[3] * src[4];
  153. tmp[8] = src[0] * src[6];
  154. tmp[9] = src[2] * src[4];
  155. tmp[10] = src[0] * src[5];
  156. tmp[11] = src[1] * src[4];
  157. dst[8] = tmp[0] * src[13] + tmp[3] * src[14] + tmp[4] * src[15];
  158. dst[8] -= tmp[1] * src[13] + tmp[2] * src[14] + tmp[5] * src[15];
  159. dst[9] = tmp[1] * src[12] + tmp[6] * src[14] + tmp[9] * src[15];
  160. dst[9] -= tmp[0] * src[12] + tmp[7] * src[14] + tmp[8] * src[15];
  161. dst[10] = tmp[2] * src[12] + tmp[7] * src[13] + tmp[10] * src[15];
  162. dst[10] -= tmp[3] * src[12] + tmp[6] * src[13] + tmp[11] * src[15];
  163. dst[11] = tmp[5] * src[12] + tmp[8] * src[13] + tmp[11] * src[14];
  164. dst[11] -= tmp[4] * src[12] + tmp[9] * src[13] + tmp[10] * src[14];
  165. dst[12] = tmp[2] * src[10] + tmp[5] * src[11] + tmp[1] * src[9];
  166. dst[12] -= tmp[4] * src[11] + tmp[0] * src[9] + tmp[3] * src[10];
  167. dst[13] = tmp[8] * src[11] + tmp[0] * src[8] + tmp[7] * src[10];
  168. dst[13] -= tmp[6] * src[10] + tmp[9] * src[11] + tmp[1] * src[8];
  169. dst[14] = tmp[6] * src[9] + tmp[11] * src[11] + tmp[3] * src[8];
  170. dst[14] -= tmp[10] * src[11] + tmp[2] * src[8] + tmp[7] * src[9];
  171. dst[15] = tmp[10] * src[10] + tmp[4] * src[8] + tmp[9] * src[9];
  172. dst[15] -= tmp[8] * src[9] + tmp[11] * src[10] + tmp[5] * src[8];
  173. // Calculate determinant
  174. det = src[0] * dst[0] + src[1] * dst[1] + src[2] * dst[2] + src[3] * dst[3];
  175. // Inverse of matrix is divided by determinant
  176. det = 1 / det;
  177. for (int j = 0; j < 16; j++)
  178. {
  179. dst[j] *= det;
  180. }
  181. // Set it back
  182. for (int i = 0; i < 4; i++)
  183. {
  184. for (int j = 0; j < 4; j++)
  185. {
  186. mat[i][j] = dst[i * 4 + j];
  187. }
  188. }
  189. }
  190. Matrix4 Matrix4::CreateFromQuaternion(const class Quaternion& q)
  191. {
  192. float mat[4][4];
  193. mat[0][0] = 1.0f - 2.0f * q.y * q.y - 2.0f * q.z * q.z;
  194. mat[0][1] = 2.0f * q.x * q.y + 2.0f * q.w * q.z;
  195. mat[0][2] = 2.0f * q.x * q.z - 2.0f * q.w * q.y;
  196. mat[0][3] = 0.0f;
  197. mat[1][0] = 2.0f * q.x * q.y - 2.0f * q.w * q.z;
  198. mat[1][1] = 1.0f - 2.0f * q.x * q.x - 2.0f * q.z * q.z;
  199. mat[1][2] = 2.0f * q.y * q.z + 2.0f * q.w * q.x;
  200. mat[1][3] = 0.0f;
  201. mat[2][0] = 2.0f * q.x * q.z + 2.0f * q.w * q.y;
  202. mat[2][1] = 2.0f * q.y * q.z - 2.0f * q.w * q.x;
  203. mat[2][2] = 1.0f - 2.0f * q.x * q.x - 2.0f * q.y * q.y;
  204. mat[2][3] = 0.0f;
  205. mat[3][0] = 0.0f;
  206. mat[3][1] = 0.0f;
  207. mat[3][2] = 0.0f;
  208. mat[3][3] = 1.0f;
  209. return Matrix4(mat);
  210. }