/SRC/MATH.C

https://github.com/kondrak/dos3d · C · 314 lines · 240 code · 51 blank · 23 comment · 4 complexity · 08e50ee3fa6d7b03d6429dd3712f10de MD5 · raw file

  1. #include "src/math.h"
  2. #include <math.h>
  3. #include <stdint.h>
  4. // internal: quick inverse sqrt()
  5. static double qInvSqrt(double number)
  6. {
  7. int32_t i;
  8. float x2, y;
  9. x2 = number * 0.5F;
  10. y = number;
  11. i = *(int32_t *)&y;
  12. i = 0x5f3759df - (i >> 1);
  13. y = *(float *)&i;
  14. y = y * (1.5f - (x2 * y * y)); // 1st iteration
  15. y = y * (1.5f - (x2 * y * y)); // 2nd iteration
  16. return y;
  17. }
  18. /* ***** */
  19. mth_Vector4 mth_crossProduct(const mth_Vector4 *v1, const mth_Vector4 *v2)
  20. {
  21. mth_Vector4 r;
  22. r.x = v1->y*v2->z - v1->z*v2->y;
  23. r.y = v1->z*v2->x - v1->x*v2->z;
  24. r.z = v1->x*v2->y - v1->y*v2->x;
  25. r.w = 1.f;
  26. return r;
  27. }
  28. /* ***** */
  29. mth_Vector4 mth_vecAdd(const mth_Vector4 *v1, const mth_Vector4 *v2)
  30. {
  31. mth_Vector4 r;
  32. r.x = v1->x + v2->x;
  33. r.y = v1->y + v2->y;
  34. r.z = v1->z + v2->z;
  35. r.w = 1.f;
  36. return r;
  37. }
  38. /* ***** */
  39. mth_Vector4 mth_vecSub(const mth_Vector4 *v1, const mth_Vector4 *v2)
  40. {
  41. mth_Vector4 r;
  42. r.x = v1->x - v2->x;
  43. r.y = v1->y - v2->y;
  44. r.z = v1->z - v2->z;
  45. r.w = 1.f;
  46. return r;
  47. }
  48. /* ***** */
  49. mth_Vector4 mth_vecScale(const mth_Vector4 *v, const float scale)
  50. {
  51. mth_Vector4 r;
  52. r.x = v->x * scale;
  53. r.y = v->y * scale;
  54. r.z = v->z * scale;
  55. r.w = 1.f;
  56. return r;
  57. }
  58. /* ***** */
  59. double mth_dotProduct(const mth_Vector4 *v1, const mth_Vector4 *v2)
  60. {
  61. return v1->x * v2->x + v1->y * v2->y + v1->z * v2->z;
  62. }
  63. /* ***** */
  64. double mth_lengthSquare(const mth_Vector4 *v)
  65. {
  66. return (v->x*v->x + v->y*v->y + v->z*v->z);
  67. }
  68. /* ***** */
  69. double mth_invLength(const mth_Vector4 *v)
  70. {
  71. return qInvSqrt(v->x*v->x + v->y*v->y + v->z*v->z);
  72. }
  73. /* ***** */
  74. void mth_normalize(mth_Vector4 *v)
  75. {
  76. double l = qInvSqrt(v->x*v->x + v->y*v->y + v->z*v->z);
  77. v->x *= l;
  78. v->y *= l;
  79. v->z *= l;
  80. }
  81. /* ***** */
  82. mth_Vector4 mth_matMulVec(const mth_Matrix4 *m, const mth_Vector4 *v)
  83. {
  84. mth_Vector4 r;
  85. r.x = m->m[0] * v->x + m->m[4] * v->y + m->m[8] * v->z + m->m[12] * v->w;
  86. r.y = m->m[1] * v->x + m->m[5] * v->y + m->m[9] * v->z + m->m[13] * v->w;
  87. r.z = m->m[2] * v->x + m->m[6] * v->y + m->m[10] * v->z + m->m[14] * v->w;
  88. r.w = m->m[3] * v->x + m->m[7] * v->y + m->m[11] * v->z + m->m[15] * v->w;
  89. return r;
  90. }
  91. /* ***** */
  92. mth_Matrix4 mth_matMul(const mth_Matrix4 *m1, const mth_Matrix4 *m2)
  93. {
  94. mth_Matrix4 r;
  95. r.m[0] = m1->m[0] * m2->m[0] + m1->m[1] * m2->m[4] + m1->m[2] * m2->m[8] + m1->m[3] * m2->m[12];
  96. r.m[1] = m1->m[0] * m2->m[1] + m1->m[1] * m2->m[5] + m1->m[2] * m2->m[9] + m1->m[3] * m2->m[13];
  97. r.m[2] = m1->m[0] * m2->m[2] + m1->m[1] * m2->m[6] + m1->m[2] * m2->m[10] + m1->m[3] * m2->m[14];
  98. r.m[3] = m1->m[0] * m2->m[3] + m1->m[1] * m2->m[7] + m1->m[2] * m2->m[11] + m1->m[3] * m2->m[15];
  99. r.m[4] = m1->m[4] * m2->m[0] + m1->m[5] * m2->m[4] + m1->m[6] * m2->m[8] + m1->m[7] * m2->m[12];
  100. r.m[5] = m1->m[4] * m2->m[1] + m1->m[5] * m2->m[5] + m1->m[6] * m2->m[9] + m1->m[7] * m2->m[13];
  101. r.m[6] = m1->m[4] * m2->m[2] + m1->m[5] * m2->m[6] + m1->m[6] * m2->m[10] + m1->m[7] * m2->m[14];
  102. r.m[7] = m1->m[4] * m2->m[3] + m1->m[5] * m2->m[7] + m1->m[6] * m2->m[11] + m1->m[7] * m2->m[15];
  103. r.m[8] = m1->m[8] * m2->m[0] + m1->m[9] * m2->m[4] + m1->m[10] * m2->m[8] + m1->m[11] * m2->m[12];
  104. r.m[9] = m1->m[8] * m2->m[1] + m1->m[9] * m2->m[5] + m1->m[10] * m2->m[9] + m1->m[11] * m2->m[13];
  105. r.m[10] = m1->m[8] * m2->m[2] + m1->m[9] * m2->m[6] + m1->m[10] * m2->m[10] + m1->m[11] * m2->m[14];
  106. r.m[11] = m1->m[8] * m2->m[3] + m1->m[9] * m2->m[7] + m1->m[10] * m2->m[11] + m1->m[11] * m2->m[15];
  107. r.m[12] = m1->m[12] * m2->m[0] + m1->m[13] * m2->m[4] + m1->m[14] * m2->m[8] + m1->m[15] * m2->m[12];
  108. r.m[13] = m1->m[12] * m2->m[1] + m1->m[13] * m2->m[5] + m1->m[14] * m2->m[9] + m1->m[15] * m2->m[13];
  109. r.m[14] = m1->m[12] * m2->m[2] + m1->m[13] * m2->m[6] + m1->m[14] * m2->m[10] + m1->m[15] * m2->m[14];
  110. r.m[15] = m1->m[12] * m2->m[3] + m1->m[13] * m2->m[7] + m1->m[14] * m2->m[11] + m1->m[15] * m2->m[15];
  111. return r;
  112. }
  113. /* ***** */
  114. void mth_matIdentity(mth_Matrix4 *m)
  115. {
  116. m->m[0] = m->m[5] = m->m[10] = m->m[15] = 1.f;
  117. m->m[1] = m->m[2] = m->m[3] = m->m[4] = 0.f;
  118. m->m[6] = m->m[7] = m->m[8] = m->m[9] = 0.f;
  119. m->m[11] = m->m[12] = m->m[13] = m->m[14] = 0.f;
  120. }
  121. /* ***** */
  122. void mth_matTranspose(mth_Matrix4 *m)
  123. {
  124. int i, j;
  125. mth_Matrix4 temp;
  126. for (i = 0; i < 16; i++)
  127. temp.m[i] = m->m[i];
  128. for (i = 0; i < 4; i++)
  129. {
  130. for (j = 0; j < 4; j++)
  131. {
  132. m->m[i * 4 + j] = temp.m[i + j * 4];
  133. }
  134. }
  135. }
  136. /* ***** */
  137. void mth_matPerspective(mth_Matrix4 *m, const float fov, const float scrRatio, const float nearPlane, const float farPlane)
  138. {
  139. int i;
  140. float tanFov;
  141. // zero the matrix first
  142. for(i = 0; i < 16; ++i)
  143. m->m[i] = 0.f;
  144. tanFov = tan(0.5f * fov);
  145. m->m[0] = 1.f / (scrRatio * tanFov);
  146. m->m[5] = 1.f / tanFov;
  147. m->m[10] = -(farPlane + nearPlane) / (farPlane - nearPlane);
  148. m->m[11] = -1.f;
  149. m->m[14] = -2.f * farPlane * nearPlane / (farPlane - nearPlane);
  150. }
  151. /* ***** */
  152. void mth_matOrtho(mth_Matrix4 *m, const float left, const float right, const float bottom, const float top, const float nearPlane, const float farPlane)
  153. {
  154. mth_matIdentity(m);
  155. m->m[0] = 2.f / (right - left);
  156. m->m[5] = 2.f / (top - bottom);
  157. m->m[10] = -2.f / (farPlane - nearPlane);
  158. m->m[12] = -(right + left) / (right - left);
  159. m->m[13] = -(top + bottom) / (top - bottom);
  160. m->m[14] = -(farPlane + nearPlane) / (farPlane - nearPlane);
  161. }
  162. /* ***** */
  163. void mth_matView(mth_Matrix4 *m, const mth_Vector4 *eye, const mth_Vector4 *target, const mth_Vector4 *up)
  164. {
  165. mth_Vector4 x,y,z;
  166. z.x = target->x;
  167. z.y = target->y;
  168. z.z = target->z;
  169. z.w = target->w;
  170. mth_normalize(&z);
  171. x = mth_crossProduct(&z, up);
  172. mth_normalize(&x);
  173. y = mth_crossProduct(&x, &z);
  174. mth_matIdentity(m);
  175. m->m[0] = x.x;
  176. m->m[4] = x.y;
  177. m->m[8] = x.z;
  178. m->m[1] = y.x;
  179. m->m[5] = y.y;
  180. m->m[9] = y.z;
  181. m->m[2] = -z.x;
  182. m->m[6] = -z.y;
  183. m->m[10] = -z.z;
  184. m->m[12] = -mth_dotProduct(&x, eye);
  185. m->m[13] = -mth_dotProduct(&y, eye);
  186. m->m[14] = mth_dotProduct(&z, eye);
  187. }
  188. /* ***** */
  189. mth_Quaternion mth_quatMul(const mth_Quaternion *q1, const mth_Quaternion *q2)
  190. {
  191. mth_Quaternion r;
  192. r.x = q1->w*q2->x + q1->x*q2->w + q1->y*q2->z - q1->z*q2->y;
  193. r.y = q1->w*q2->y - q1->x*q2->z + q1->y*q2->w + q1->z*q2->x;
  194. r.z = q1->w*q2->z + q1->x*q2->y - q1->y*q2->x + q1->z*q2->w;
  195. r.w = q1->w*q2->w - q1->x*q2->x - q1->y*q2->y - q1->z*q2->z;
  196. return r;
  197. }
  198. /* ***** */
  199. mth_Quaternion mth_quatConjugate(const mth_Quaternion *q)
  200. {
  201. mth_Quaternion r;
  202. r.x = -q->x;
  203. r.y = -q->y;
  204. r.z = -q->z;
  205. r.w = q->w;
  206. return r;
  207. }
  208. /* ***** */
  209. mth_Vector4 mth_quatMulVec(const mth_Quaternion *q, const mth_Vector4 *v)
  210. {
  211. mth_Vector4 vn, r;
  212. mth_Quaternion vq, cq, rq, rq2;
  213. vn.x = v->x;
  214. vn.y = v->y;
  215. vn.z = v->z;
  216. mth_normalize(&vn);
  217. vq.x = vn.x;
  218. vq.y = vn.y;
  219. vq.z = vn.z;
  220. vq.w = 0.f;
  221. cq = mth_quatConjugate(q);
  222. rq = mth_quatMul(&vq, &cq);
  223. rq2 = mth_quatMul(q, &rq);
  224. r.x = rq2.x;
  225. r.y = rq2.y;
  226. r.z = rq2.z;
  227. return r;
  228. }
  229. /* ***** */
  230. void mth_quatNormalize(mth_Quaternion *q)
  231. {
  232. double l = qInvSqrt(q->x*q->x + q->y*q->y + q->z*q->z + q->w*q->w);
  233. q->x *= l;
  234. q->y *= l;
  235. q->z *= l;
  236. q->w *= l;
  237. }
  238. /* ***** */
  239. void mth_rotateVecAxisAngle(mth_Vector4 *v, const float angle, const float x, const float y, const float z)
  240. {
  241. mth_Quaternion q;
  242. float hAngle = angle/2.f;
  243. q.x = x * sin(hAngle);
  244. q.y = y * sin(hAngle);
  245. q.z = z * sin(hAngle);
  246. q.w = cos(hAngle);
  247. mth_rotateVecQuat(v, &q);
  248. }
  249. /* ***** */
  250. void mth_rotateVecQuat(mth_Vector4 *v, const mth_Quaternion *q)
  251. {
  252. mth_Quaternion r, qv, qc, viewQuat;
  253. viewQuat.x = v->x;
  254. viewQuat.y = v->y;
  255. viewQuat.z = v->z;
  256. viewQuat.w = 0.f;
  257. qc = mth_quatConjugate(q);
  258. qv = mth_quatMul(q, &viewQuat);
  259. r = mth_quatMul(&qv, &qc);
  260. v->x = r.x;
  261. v->y = r.y;
  262. v->z = r.z;
  263. }