matrix.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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. }
  45. return result;
  46. }
  47. /* Matrix operations */
  48. matrix4_t mat4ProdMat4(matrix4_t a, matrix4_t b)
  49. {
  50. matrix4_t ret;
  51. int x, y;
  52. for (y = 0 ; y < 4 ; y++)
  53. {
  54. for (x = 0 ; x < 4 ; x++)
  55. {
  56. double v = FastGet4(a, x, 0) * FastGet4(b, 0, y) +
  57. FastGet4(a, x, 1) * FastGet4(b, 1, y) +
  58. FastGet4(a, x, 2) * FastGet4(b, 2, y) +
  59. FastGet4(a, x, 3) * FastGet4(b, 3, y);
  60. FastSet4(ret, x, y, v);
  61. }
  62. }
  63. return ret;
  64. }
  65. /* Matrix creations */
  66. matrix4_t mat4Scale(double scaleX, double scaleY, double scaleZ)
  67. {
  68. matrix4_t ret =
  69. {
  70. .v =
  71. {
  72. scaleX, 0, 0, 0,
  73. 0, scaleY, 0, 0,
  74. 0, 0, scaleZ, 0,
  75. 0, 0, 0, 1
  76. }
  77. };
  78. return ret;
  79. }
  80. matrix4_t mat4Translate(double tX, double tY, double tZ)
  81. {
  82. matrix4_t ret =
  83. {
  84. .v =
  85. {
  86. 1, 0, 0, tX,
  87. 0, 1, 0, tY,
  88. 0, 0, 1, tZ,
  89. 0, 0, 0, 1
  90. }
  91. };
  92. return ret;
  93. }
  94. matrix4_t mat4RotationX(double angle)
  95. {
  96. matrix4_t ret =
  97. {
  98. .v =
  99. {
  100. 1, 0, 0, 0,
  101. 0, cos(angle), -sin(angle), 0,
  102. 0, sin(angle), cos(angle), 0,
  103. 0, 0, 0, 1
  104. }
  105. };
  106. return ret;
  107. }
  108. matrix4_t mat4RotationY(double angle)
  109. {
  110. matrix4_t ret =
  111. {
  112. .v =
  113. {
  114. cos(angle), 0, sin(angle), 0,
  115. 0, 1, 0, 0,
  116. -sin(angle), 0, cos(angle), 0,
  117. 0, 0, 0, 1
  118. }
  119. };
  120. return ret;
  121. }
  122. matrix4_t mat4RotationZ(double angle)
  123. {
  124. matrix4_t ret =
  125. {
  126. .v =
  127. {
  128. cos(angle), -sin(angle), 0, 0,
  129. sin(angle), cos(angle), 0, 0,
  130. 0, 0, 1, 0,
  131. 0, 0, 0, 1
  132. }
  133. };
  134. return ret;
  135. }
  136. matrix4_t mat4Perspective(double aspectRatio, double FOV, double zNear, double zFar)
  137. {
  138. double radFOV = (FOV * M_PI) / 180.;
  139. double f = 1. / tan(radFOV / 2.);
  140. matrix4_t ret =
  141. {
  142. .v =
  143. {
  144. aspectRatio * f, 0, 0, 0,
  145. 0, f, 0, 0,
  146. 0, 0, zFar / (zFar - zNear), -(zFar * zNear) / (zFar - zNear),
  147. 0, 0, 1, 0
  148. }
  149. };
  150. return ret;
  151. }