matrix4.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /******************************************************************************
  2. Copyright (C) 2013 by Hugh Bailey <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ******************************************************************************/
  14. #include "math-defs.h"
  15. #include "matrix4.h"
  16. #include "matrix3.h"
  17. void matrix4_from_matrix3(struct matrix4 *dst, const struct matrix3 *m)
  18. {
  19. dst->x.m = m->x.m;
  20. dst->y.m = m->y.m;
  21. dst->z.m = m->z.m;
  22. dst->t.m = m->t.m;
  23. dst->t.w = 1.0f;
  24. }
  25. void matrix4_mul(struct matrix4 *dst, const struct matrix4 *m1,
  26. const struct matrix4 *m2)
  27. {
  28. const struct vec4 *m1v = (const struct vec4*)m1;
  29. const float *m2f = (const float*)m2;
  30. struct vec4 out[4];
  31. int i, j;
  32. for (i = 0; i < 4; i++) {
  33. for (j=0; j<4; j++) {
  34. struct vec4 temp;
  35. vec4_set(&temp, m2f[j], m2f[j+4], m2f[j+8], m2f[j+12]);
  36. out[i].ptr[j] = vec4_dot(&m1v[i], &temp);
  37. }
  38. }
  39. matrix4_copy(dst, (struct matrix4*)out);
  40. }
  41. static inline void get_3x3_submatrix(float *dst, const struct matrix4 *m,
  42. int i, int j)
  43. {
  44. const float *mf = (const float *)m;
  45. int ti, tj, idst, jdst;
  46. for (ti = 0; ti < 4; ti++) {
  47. if (ti < i)
  48. idst = ti;
  49. else if (ti > i)
  50. idst = ti-1;
  51. else
  52. continue;
  53. for (tj = 0; tj < 4; tj++) {
  54. if (tj < j)
  55. jdst = tj;
  56. else if (tj > j)
  57. jdst = tj-1;
  58. else
  59. continue;
  60. dst[(idst*3) + jdst] = mf[(ti*4) + tj];
  61. }
  62. }
  63. }
  64. static inline float get_3x3_determinant(const float *m)
  65. {
  66. return (m[0] * ((m[4]*m[8]) - (m[7]*m[5]))) -
  67. (m[1] * ((m[3]*m[8]) - (m[6]*m[5]))) +
  68. (m[2] * ((m[3]*m[7]) - (m[6]*m[4])));
  69. }
  70. float matrix4_determinant(const struct matrix4 *m)
  71. {
  72. const float *mf = (const float *)m;
  73. float det, result = 0.0f, i = 1.0f;
  74. float m3x3[9];
  75. int n;
  76. for (n = 0; n < 4; n++, i *= -1.0f) {
  77. get_3x3_submatrix(m3x3, m, 0, n);
  78. det = get_3x3_determinant(m3x3);
  79. result += mf[n] * det * i;
  80. }
  81. return result;
  82. }
  83. bool matrix4_inv(struct matrix4 *dst, const struct matrix4 *m)
  84. {
  85. struct vec4 *dstv = (struct vec4 *)dst;
  86. float det = matrix4_determinant(m);
  87. float m3x3[9];
  88. int i, j, sign;
  89. if (fabs(det) < 0.0005f)
  90. return false;
  91. for (i = 0; i < 4; i++) {
  92. for (j = 0; j < 4; j++) {
  93. sign = 1 - ((i+j) % 2) * 2;
  94. get_3x3_submatrix(m3x3, m, i, j);
  95. dstv[j].ptr[i] = get_3x3_determinant(m3x3) *
  96. (float)sign / det;
  97. }
  98. }
  99. return true;
  100. }
  101. void matrix4_transpose(struct matrix4 *dst, const struct matrix4 *m)
  102. {
  103. struct matrix4 temp;
  104. /* TODO: Add SSE */
  105. temp.x.x = m->x.x;
  106. temp.x.y = m->y.x;
  107. temp.x.z = m->z.x;
  108. temp.x.w = m->t.x;
  109. temp.y.x = m->x.y;
  110. temp.y.y = m->y.y;
  111. temp.y.z = m->z.y;
  112. temp.y.w = m->t.y;
  113. temp.z.x = m->x.z;
  114. temp.z.y = m->y.z;
  115. temp.z.z = m->z.z;
  116. temp.z.w = m->t.z;
  117. temp.t.x = m->x.w;
  118. temp.t.y = m->y.w;
  119. temp.t.z = m->z.w;
  120. temp.t.w = m->t.w;
  121. matrix4_copy(dst, &temp);
  122. }