Matrix.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include <math.h>
  2. #include <stdio.h>
  3. #include "core/Generic.h"
  4. #include "core/ToString.h"
  5. #define M(m, x, y) ((m)->data[x].data[y])
  6. Matrix* transposeMatrix(Matrix* m) {
  7. Matrix c = ZERO_MATRIX;
  8. for(size_t x = 0; x < 4; x++) {
  9. for(size_t y = 0; y < 4; y++) {
  10. M(&c, x, y) = M(m, y, x);
  11. }
  12. }
  13. *m = c;
  14. return m;
  15. }
  16. Matrix* mulSetMatrix(Matrix* m, const Matrix* a) {
  17. for(int i = 0; i < 4; i++) {
  18. Vector4 d = VECTOR4;
  19. addSet(&d, mul(a->data + 0, m->data[i].x));
  20. addSet(&d, mul(a->data + 1, m->data[i].y));
  21. addSet(&d, mul(a->data + 2, m->data[i].z));
  22. addSet(&d, mul(a->data + 3, m->data[i].w));
  23. m->data[i] = d;
  24. }
  25. return m;
  26. }
  27. Matrix* mulMatrix(Matrix* m, const Matrix* a, const Matrix* b) {
  28. *m = *a;
  29. mulSetMatrix(m, b);
  30. return m;
  31. }
  32. Vector3* mulMatrixV3(Vector3* v, const Matrix* m, const Vector3* a) {
  33. Vector4 v4 = V(a->x, a->y, a->z, 1.0f);
  34. v->x = dot(m->data + 0, &v4);
  35. v->y = dot(m->data + 1, &v4);
  36. v->z = dot(m->data + 2, &v4);
  37. mulSet(v, 1.0f / dot(m->data + 3, &v4));
  38. return v;
  39. }
  40. Matrix* scaleMatrix(Matrix* m, const Vector3* v) {
  41. mulSet(m->data + 0, v->x);
  42. mulSet(m->data + 1, v->y);
  43. mulSet(m->data + 2, v->z);
  44. return m;
  45. }
  46. Matrix* scaleMatrixF(Matrix* m, float f) {
  47. return scaleMatrix(m, &V(f, f, f));
  48. }
  49. Matrix* translateMatrix(Matrix* m, const Vector3* v) {
  50. translateMatrixX(m, v->x);
  51. translateMatrixY(m, v->y);
  52. translateMatrixZ(m, v->z);
  53. return m;
  54. }
  55. Matrix* translateMatrixX(Matrix* m, float tx) {
  56. addSet(m->data + 0, mul(m->data + 3, tx));
  57. return m;
  58. }
  59. Matrix* translateMatrixY(Matrix* m, float ty) {
  60. addSet(m->data + 1, mul(m->data + 3, ty));
  61. return m;
  62. }
  63. Matrix* translateMatrixZ(Matrix* m, float tz) {
  64. addSet(m->data + 2, mul(m->data + 3, tz));
  65. return m;
  66. }
  67. Matrix* translateMatrixTo(Matrix* m, const Vector3* v) {
  68. m->data[0] = V(1.0f, 0.0f, 0.0f, v->x);
  69. m->data[1] = V(0.0f, 1.0f, 0.0f, v->y);
  70. m->data[2] = V(0.0f, 0.0f, 1.0f, v->z);
  71. m->data[3] = V(0.0f, 0.0f, 0.0f, 1.0f);
  72. return m;
  73. }
  74. static Matrix* rotate(Matrix* m, float radians, int a, int b) {
  75. float sin = sinf(radians);
  76. float cos = cosf(radians);
  77. Vector4 v = m->data[a];
  78. sub(m->data + a, mul(&v, cos), mul(m->data + b, sin));
  79. add(m->data + b, mul(&v, sin), mul(m->data + b, cos));
  80. return m;
  81. }
  82. Matrix* rotateMatrixX(Matrix* m, float radians) {
  83. return rotate(m, radians, 1, 2);
  84. }
  85. Matrix* rotateMatrixY(Matrix* m, float radians) {
  86. return rotate(m, -radians, 0, 2);
  87. }
  88. Matrix* rotateMatrixZ(Matrix* m, float radians) {
  89. return rotate(m, radians, 0, 1);
  90. }
  91. Matrix* rotateMatrix(Matrix* m, const Quaternion* q) {
  92. Vector3 a;
  93. Vector3 b;
  94. Vector3 c;
  95. Vector3 d;
  96. mul(&a, q, &V(M(m, 0, 0), M(m, 1, 0), M(m, 2, 0)));
  97. mul(&b, q, &V(M(m, 0, 1), M(m, 1, 1), M(m, 2, 1)));
  98. mul(&c, q, &V(M(m, 0, 2), M(m, 1, 2), M(m, 2, 2)));
  99. mul(&d, q, &V(M(m, 0, 3), M(m, 1, 3), M(m, 2, 3)));
  100. m->data[0] = V(a.x, b.x, c.x, d.x);
  101. m->data[1] = V(a.y, b.y, c.y, d.y);
  102. m->data[2] = V(a.z, b.z, c.z, d.z);
  103. return m;
  104. }
  105. size_t toStringMatrix(const Matrix* m, char* buffer, size_t n) {
  106. size_t w = 0;
  107. stringAdd(&w, &buffer, &n, toString(buffer, n, "["));
  108. stringAdd(&w, &buffer, &n, toStringV4(m->data + 0, buffer, n));
  109. stringAdd(&w, &buffer, &n, toString(buffer, n, ", "));
  110. stringAdd(&w, &buffer, &n, toStringV4(m->data + 1, buffer, n));
  111. stringAdd(&w, &buffer, &n, toString(buffer, n, ", "));
  112. stringAdd(&w, &buffer, &n, toStringV4(m->data + 2, buffer, n));
  113. stringAdd(&w, &buffer, &n, toString(buffer, n, ", "));
  114. stringAdd(&w, &buffer, &n, toStringV4(m->data + 3, buffer, n));
  115. stringAdd(&w, &buffer, &n, toString(buffer, n, "]"));
  116. return w;
  117. }