matrix.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * 3D Engine
  3. * matrice.c:
  4. * Based on pikuma.com 3D software renderer in C
  5. * Copyright (c) 2021 986-Studio. All rights reserved.
  6. *
  7. * Created by Manoël Trapier on 06/03/2021.
  8. */
  9. #include <math.h>
  10. #include <matrix.h>
  11. /* Matrix operations */
  12. vec4_t mat4ProdVec4(matrix4_t mat, vec4_t v)
  13. {
  14. vec4_t ret =
  15. {
  16. .x = FastGet4(mat, 0, 0) * v.x +
  17. FastGet4(mat, 0, 1) * v.y +
  18. FastGet4(mat, 0, 2) * v.z +
  19. FastGet4(mat, 0, 3) * v.w,
  20. .y = FastGet4(mat, 1, 0) * v.x +
  21. FastGet4(mat, 1, 1) * v.y +
  22. FastGet4(mat, 1, 2) * v.z +
  23. FastGet4(mat, 1, 3) * v.w,
  24. .z = FastGet4(mat, 2, 0) * v.x +
  25. FastGet4(mat, 2, 1) * v.y +
  26. FastGet4(mat, 2, 2) * v.z +
  27. FastGet4(mat, 2, 3) * v.w,
  28. .w = FastGet4(mat, 3, 0) * v.x +
  29. FastGet4(mat, 3, 1) * v.y +
  30. FastGet4(mat, 3, 2) * v.z +
  31. FastGet4(mat, 3, 3) * v.w,
  32. };
  33. return ret;
  34. }
  35. vec4_t mat4ProdVec4Project(matrix4_t mat, vec4_t v)
  36. {
  37. vec4_t result = mat4ProdVec4(mat, v);
  38. /* Normalise the vector if needed */
  39. if (result.w != 0.0)
  40. {
  41. result.x /= result.w;
  42. result.y /= result.w;
  43. result.z /= result.w;
  44. result.w = 0;
  45. }
  46. return result;
  47. }
  48. /* Matrix operations */
  49. matrix4_t mat4ProdMat4(matrix4_t a, matrix4_t b)
  50. {
  51. matrix4_t ret;
  52. int x, y, k;
  53. for (y = 0 ; y < 4 ; y++)
  54. {
  55. for (x = 0 ; x < 4 ; x++)
  56. {
  57. double v = FastGet4(a, x, 0) * FastGet4(b, 0, y) +
  58. FastGet4(a, x, 1) * FastGet4(b, 1, y) +
  59. FastGet4(a, x, 2) * FastGet4(b, 2, y) +
  60. FastGet4(a, x, 3) * FastGet4(b, 3, y);
  61. FastSet4(ret, x, y, v);
  62. }
  63. }
  64. return ret;
  65. }
  66. /* Matrix creations */
  67. matrix4_t mat4Scale(double scaleX, double scaleY, double scaleZ)
  68. {
  69. matrix4_t ret =
  70. {
  71. .v =
  72. {
  73. scaleX, 0, 0, 0,
  74. 0, scaleY, 0, 0,
  75. 0, 0, scaleZ, 0,
  76. 0, 0, 0, 1
  77. }
  78. };
  79. return ret;
  80. }
  81. matrix4_t mat4Translate(double tX, double tY, double tZ)
  82. {
  83. matrix4_t ret =
  84. {
  85. .v =
  86. {
  87. 1, 0, 0, tX,
  88. 0, 1, 0, tY,
  89. 0, 0, 1, tZ,
  90. 0, 0, 0, 1
  91. }
  92. };
  93. return ret;
  94. }
  95. matrix4_t mat4RotationX(double angle)
  96. {
  97. matrix4_t ret =
  98. {
  99. .v =
  100. {
  101. 1, 0, 0, 0,
  102. 0, cos(angle), -sin(angle), 0,
  103. 0, sin(angle), cos(angle), 0,
  104. 0, 0, 0, 1
  105. }
  106. };
  107. return ret;
  108. }
  109. matrix4_t mat4RotationY(double angle)
  110. {
  111. matrix4_t ret =
  112. {
  113. .v =
  114. {
  115. cos(angle), 0, sin(angle), 0,
  116. 0, 1, 0, 0,
  117. -sin(angle), 0, cos(angle), 0,
  118. 0, 0, 0, 1
  119. }
  120. };
  121. return ret;
  122. }
  123. matrix4_t mat4RotationZ(double angle)
  124. {
  125. matrix4_t ret =
  126. {
  127. .v =
  128. {
  129. cos(angle), -sin(angle), 0, 0,
  130. sin(angle), cos(angle), 0, 0,
  131. 0, 0, 1, 0,
  132. 0, 0, 0, 1
  133. }
  134. };
  135. return ret;
  136. }
  137. matrix4_t mat4Perspective(double aspectRatio, double FOV, double zNear, double zFar)
  138. {
  139. double radFOV = (FOV * M_PI) / 180.;
  140. double f = 1. / tan(radFOV / 2.);
  141. matrix4_t ret =
  142. {
  143. .v =
  144. {
  145. aspectRatio * f, 0, 0, 0,
  146. 0, f, 0, 0,
  147. 0, 0, zFar / (zFar - zNear), -(zFar * zNear) / (zFar - zNear),
  148. 0, 0, 1, 0
  149. }
  150. };
  151. return ret;
  152. }