Commit | Line | Data |
---|---|---|
3719602c PC |
1 | /* Copyright (C) 2010-2020 The RetroArch team |
2 | * | |
3 | * --------------------------------------------------------------------------------------- | |
4 | * The following license statement only applies to this file (matrix_4x4.h). | |
5 | * --------------------------------------------------------------------------------------- | |
6 | * | |
7 | * Permission is hereby granted, free of charge, | |
8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), | |
9 | * to deal in the Software without restriction, including without limitation the rights to | |
10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, | |
11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | |
12 | * | |
13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | |
14 | * | |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |
16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
21 | */ | |
22 | ||
23 | #ifndef __LIBRETRO_SDK_GFX_MATH_MATRIX_4X4_H__ | |
24 | #define __LIBRETRO_SDK_GFX_MATH_MATRIX_4X4_H__ | |
25 | ||
26 | #include <retro_common_api.h> | |
27 | ||
28 | #include <math.h> | |
29 | #include <gfx/math/vector_3.h> | |
30 | ||
31 | /* Column-major matrix (OpenGL-style). | |
32 | * Reimplements functionality from FF OpenGL pipeline to be able | |
33 | * to work on GLES 2.0 and modern GL variants. | |
34 | */ | |
35 | ||
36 | #define MAT_ELEM_4X4(mat, row, column) ((mat).data[4 * (column) + (row)]) | |
37 | ||
38 | RETRO_BEGIN_DECLS | |
39 | ||
40 | typedef struct math_matrix_4x4 | |
41 | { | |
42 | float data[16]; | |
43 | } math_matrix_4x4; | |
44 | ||
45 | #define matrix_4x4_copy(dst, src) \ | |
46 | MAT_ELEM_4X4(dst, 0, 0) = MAT_ELEM_4X4(src, 0, 0); \ | |
47 | MAT_ELEM_4X4(dst, 0, 1) = MAT_ELEM_4X4(src, 0, 1); \ | |
48 | MAT_ELEM_4X4(dst, 0, 2) = MAT_ELEM_4X4(src, 0, 2); \ | |
49 | MAT_ELEM_4X4(dst, 0, 3) = MAT_ELEM_4X4(src, 0, 3); \ | |
50 | MAT_ELEM_4X4(dst, 1, 0) = MAT_ELEM_4X4(src, 1, 0); \ | |
51 | MAT_ELEM_4X4(dst, 1, 1) = MAT_ELEM_4X4(src, 1, 1); \ | |
52 | MAT_ELEM_4X4(dst, 1, 2) = MAT_ELEM_4X4(src, 1, 2); \ | |
53 | MAT_ELEM_4X4(dst, 1, 3) = MAT_ELEM_4X4(src, 1, 3); \ | |
54 | MAT_ELEM_4X4(dst, 2, 0) = MAT_ELEM_4X4(src, 2, 0); \ | |
55 | MAT_ELEM_4X4(dst, 2, 1) = MAT_ELEM_4X4(src, 2, 1); \ | |
56 | MAT_ELEM_4X4(dst, 2, 2) = MAT_ELEM_4X4(src, 2, 2); \ | |
57 | MAT_ELEM_4X4(dst, 2, 3) = MAT_ELEM_4X4(src, 2, 3); \ | |
58 | MAT_ELEM_4X4(dst, 3, 0) = MAT_ELEM_4X4(src, 3, 0); \ | |
59 | MAT_ELEM_4X4(dst, 3, 1) = MAT_ELEM_4X4(src, 3, 1); \ | |
60 | MAT_ELEM_4X4(dst, 3, 2) = MAT_ELEM_4X4(src, 3, 2); \ | |
61 | MAT_ELEM_4X4(dst, 3, 3) = MAT_ELEM_4X4(src, 3, 3) | |
62 | ||
63 | /* | |
64 | * Sets mat to an identity matrix | |
65 | */ | |
66 | #define matrix_4x4_identity(mat) \ | |
67 | MAT_ELEM_4X4(mat, 0, 0) = 1.0f; \ | |
68 | MAT_ELEM_4X4(mat, 0, 1) = 0.0f; \ | |
69 | MAT_ELEM_4X4(mat, 0, 2) = 0.0f; \ | |
70 | MAT_ELEM_4X4(mat, 0, 3) = 0.0f; \ | |
71 | MAT_ELEM_4X4(mat, 1, 0) = 0.0f; \ | |
72 | MAT_ELEM_4X4(mat, 1, 1) = 1.0f; \ | |
73 | MAT_ELEM_4X4(mat, 1, 2) = 0.0f; \ | |
74 | MAT_ELEM_4X4(mat, 1, 3) = 0.0f; \ | |
75 | MAT_ELEM_4X4(mat, 2, 0) = 0.0f; \ | |
76 | MAT_ELEM_4X4(mat, 2, 1) = 0.0f; \ | |
77 | MAT_ELEM_4X4(mat, 2, 2) = 1.0f; \ | |
78 | MAT_ELEM_4X4(mat, 2, 3) = 0.0f; \ | |
79 | MAT_ELEM_4X4(mat, 3, 0) = 0.0f; \ | |
80 | MAT_ELEM_4X4(mat, 3, 1) = 0.0f; \ | |
81 | MAT_ELEM_4X4(mat, 3, 2) = 0.0f; \ | |
82 | MAT_ELEM_4X4(mat, 3, 3) = 1.0f | |
83 | ||
84 | /* | |
85 | * Sets out to the transposed matrix of in | |
86 | */ | |
87 | ||
88 | #define matrix_4x4_transpose(out, in) \ | |
89 | MAT_ELEM_4X4(out, 0, 0) = MAT_ELEM_4X4(in, 0, 0); \ | |
90 | MAT_ELEM_4X4(out, 1, 0) = MAT_ELEM_4X4(in, 0, 1); \ | |
91 | MAT_ELEM_4X4(out, 2, 0) = MAT_ELEM_4X4(in, 0, 2); \ | |
92 | MAT_ELEM_4X4(out, 3, 0) = MAT_ELEM_4X4(in, 0, 3); \ | |
93 | MAT_ELEM_4X4(out, 0, 1) = MAT_ELEM_4X4(in, 1, 0); \ | |
94 | MAT_ELEM_4X4(out, 1, 1) = MAT_ELEM_4X4(in, 1, 1); \ | |
95 | MAT_ELEM_4X4(out, 2, 1) = MAT_ELEM_4X4(in, 1, 2); \ | |
96 | MAT_ELEM_4X4(out, 3, 1) = MAT_ELEM_4X4(in, 1, 3); \ | |
97 | MAT_ELEM_4X4(out, 0, 2) = MAT_ELEM_4X4(in, 2, 0); \ | |
98 | MAT_ELEM_4X4(out, 1, 2) = MAT_ELEM_4X4(in, 2, 1); \ | |
99 | MAT_ELEM_4X4(out, 2, 2) = MAT_ELEM_4X4(in, 2, 2); \ | |
100 | MAT_ELEM_4X4(out, 3, 2) = MAT_ELEM_4X4(in, 2, 3); \ | |
101 | MAT_ELEM_4X4(out, 0, 3) = MAT_ELEM_4X4(in, 3, 0); \ | |
102 | MAT_ELEM_4X4(out, 1, 3) = MAT_ELEM_4X4(in, 3, 1); \ | |
103 | MAT_ELEM_4X4(out, 2, 3) = MAT_ELEM_4X4(in, 3, 2); \ | |
104 | MAT_ELEM_4X4(out, 3, 3) = MAT_ELEM_4X4(in, 3, 3) | |
105 | ||
106 | /* | |
107 | * Builds an X-axis rotation matrix | |
108 | */ | |
109 | #define matrix_4x4_rotate_x(mat, radians) \ | |
110 | { \ | |
111 | float cosine = cosf(radians); \ | |
112 | float sine = sinf(radians); \ | |
113 | MAT_ELEM_4X4(mat, 0, 0) = 1.0f; \ | |
114 | MAT_ELEM_4X4(mat, 0, 1) = 0.0f; \ | |
115 | MAT_ELEM_4X4(mat, 0, 2) = 0.0f; \ | |
116 | MAT_ELEM_4X4(mat, 0, 3) = 0.0f; \ | |
117 | MAT_ELEM_4X4(mat, 1, 0) = 0.0f; \ | |
118 | MAT_ELEM_4X4(mat, 1, 1) = cosine; \ | |
119 | MAT_ELEM_4X4(mat, 1, 2) = -sine; \ | |
120 | MAT_ELEM_4X4(mat, 1, 3) = 0.0f; \ | |
121 | MAT_ELEM_4X4(mat, 2, 0) = 0.0f; \ | |
122 | MAT_ELEM_4X4(mat, 2, 1) = sine; \ | |
123 | MAT_ELEM_4X4(mat, 2, 2) = cosine; \ | |
124 | MAT_ELEM_4X4(mat, 2, 3) = 0.0f; \ | |
125 | MAT_ELEM_4X4(mat, 3, 0) = 0.0f; \ | |
126 | MAT_ELEM_4X4(mat, 3, 1) = 0.0f; \ | |
127 | MAT_ELEM_4X4(mat, 3, 2) = 0.0f; \ | |
128 | MAT_ELEM_4X4(mat, 3, 3) = 1.0f; \ | |
129 | } | |
130 | ||
131 | /* | |
132 | * Builds a rotation matrix using the | |
133 | * rotation around the Y-axis. | |
134 | */ | |
135 | ||
136 | #define matrix_4x4_rotate_y(mat, radians) \ | |
137 | { \ | |
138 | float cosine = cosf(radians); \ | |
139 | float sine = sinf(radians); \ | |
140 | MAT_ELEM_4X4(mat, 0, 0) = cosine; \ | |
141 | MAT_ELEM_4X4(mat, 0, 1) = 0.0f; \ | |
142 | MAT_ELEM_4X4(mat, 0, 2) = -sine; \ | |
143 | MAT_ELEM_4X4(mat, 0, 3) = 0.0f; \ | |
144 | MAT_ELEM_4X4(mat, 1, 0) = 0.0f; \ | |
145 | MAT_ELEM_4X4(mat, 1, 1) = 1.0f; \ | |
146 | MAT_ELEM_4X4(mat, 1, 2) = 0.0f; \ | |
147 | MAT_ELEM_4X4(mat, 1, 3) = 0.0f; \ | |
148 | MAT_ELEM_4X4(mat, 2, 0) = sine; \ | |
149 | MAT_ELEM_4X4(mat, 2, 1) = 0.0f; \ | |
150 | MAT_ELEM_4X4(mat, 2, 2) = cosine; \ | |
151 | MAT_ELEM_4X4(mat, 2, 3) = 0.0f; \ | |
152 | MAT_ELEM_4X4(mat, 3, 0) = 0.0f; \ | |
153 | MAT_ELEM_4X4(mat, 3, 1) = 0.0f; \ | |
154 | MAT_ELEM_4X4(mat, 3, 2) = 0.0f; \ | |
155 | MAT_ELEM_4X4(mat, 3, 3) = 1.0f; \ | |
156 | } | |
157 | ||
158 | /* | |
159 | * Builds a rotation matrix using the | |
160 | * rotation around the Z-axis. | |
161 | */ | |
162 | #define matrix_4x4_rotate_z(mat, radians) \ | |
163 | { \ | |
164 | float cosine = cosf(radians); \ | |
165 | float sine = sinf(radians); \ | |
166 | MAT_ELEM_4X4(mat, 0, 0) = cosine; \ | |
167 | MAT_ELEM_4X4(mat, 0, 1) = -sine; \ | |
168 | MAT_ELEM_4X4(mat, 0, 2) = 0.0f; \ | |
169 | MAT_ELEM_4X4(mat, 0, 3) = 0.0f; \ | |
170 | MAT_ELEM_4X4(mat, 1, 0) = sine; \ | |
171 | MAT_ELEM_4X4(mat, 1, 1) = cosine; \ | |
172 | MAT_ELEM_4X4(mat, 1, 2) = 0.0f; \ | |
173 | MAT_ELEM_4X4(mat, 1, 3) = 0.0f; \ | |
174 | MAT_ELEM_4X4(mat, 2, 0) = 0.0f; \ | |
175 | MAT_ELEM_4X4(mat, 2, 1) = 0.0f; \ | |
176 | MAT_ELEM_4X4(mat, 2, 2) = 1.0f; \ | |
177 | MAT_ELEM_4X4(mat, 2, 3) = 0.0f; \ | |
178 | MAT_ELEM_4X4(mat, 3, 0) = 0.0f; \ | |
179 | MAT_ELEM_4X4(mat, 3, 1) = 0.0f; \ | |
180 | MAT_ELEM_4X4(mat, 3, 2) = 0.0f; \ | |
181 | MAT_ELEM_4X4(mat, 3, 3) = 1.0f; \ | |
182 | } | |
183 | ||
184 | /* | |
185 | * Creates an orthographic projection matrix. | |
186 | */ | |
187 | #define matrix_4x4_ortho(mat, left, right, bottom, top, znear, zfar) \ | |
188 | { \ | |
189 | float rl = (right) - (left); \ | |
190 | float tb = (top) - (bottom); \ | |
191 | float fn = (zfar) - (znear); \ | |
192 | MAT_ELEM_4X4(mat, 0, 0) = 2.0f / rl; \ | |
193 | MAT_ELEM_4X4(mat, 0, 1) = 0.0f; \ | |
194 | MAT_ELEM_4X4(mat, 0, 2) = 0.0f; \ | |
195 | MAT_ELEM_4X4(mat, 0, 3) = -((left) + (right)) / rl; \ | |
196 | MAT_ELEM_4X4(mat, 1, 0) = 0.0f; \ | |
197 | MAT_ELEM_4X4(mat, 1, 1) = 2.0f / tb; \ | |
198 | MAT_ELEM_4X4(mat, 1, 2) = 0.0f; \ | |
199 | MAT_ELEM_4X4(mat, 1, 3) = -((top) + (bottom)) / tb; \ | |
200 | MAT_ELEM_4X4(mat, 2, 0) = 0.0f; \ | |
201 | MAT_ELEM_4X4(mat, 2, 1) = 0.0f; \ | |
202 | MAT_ELEM_4X4(mat, 2, 2) = -2.0f / fn; \ | |
203 | MAT_ELEM_4X4(mat, 2, 3) = -((zfar) + (znear)) / fn; \ | |
204 | MAT_ELEM_4X4(mat, 3, 0) = 0.0f; \ | |
205 | MAT_ELEM_4X4(mat, 3, 1) = 0.0f; \ | |
206 | MAT_ELEM_4X4(mat, 3, 2) = 0.0f; \ | |
207 | MAT_ELEM_4X4(mat, 3, 3) = 1.0f; \ | |
208 | } | |
209 | ||
210 | #define matrix_4x4_lookat(out, eye, center, up) \ | |
211 | { \ | |
212 | vec3_t zaxis; /* the "forward" vector */ \ | |
213 | vec3_t xaxis; /* the "right" vector */ \ | |
214 | vec3_t yaxis; /* the "up" vector */ \ | |
215 | vec3_copy(zaxis, center); \ | |
216 | vec3_subtract(zaxis, eye); \ | |
217 | vec3_normalize(zaxis); \ | |
218 | vec3_cross(xaxis, zaxis, up); \ | |
219 | vec3_normalize(xaxis); \ | |
220 | vec3_cross(yaxis, xaxis, zaxis); \ | |
221 | MAT_ELEM_4X4(out, 0, 0) = xaxis[0]; \ | |
222 | MAT_ELEM_4X4(out, 0, 1) = yaxis[0]; \ | |
223 | MAT_ELEM_4X4(out, 0, 2) = -zaxis[0]; \ | |
224 | MAT_ELEM_4X4(out, 0, 3) = 0.0; \ | |
225 | MAT_ELEM_4X4(out, 1, 0) = xaxis[1]; \ | |
226 | MAT_ELEM_4X4(out, 1, 1) = yaxis[1]; \ | |
227 | MAT_ELEM_4X4(out, 1, 2) = -zaxis[1]; \ | |
228 | MAT_ELEM_4X4(out, 1, 3) = 0.0f; \ | |
229 | MAT_ELEM_4X4(out, 2, 0) = xaxis[2]; \ | |
230 | MAT_ELEM_4X4(out, 2, 1) = yaxis[2]; \ | |
231 | MAT_ELEM_4X4(out, 2, 2) = -zaxis[2]; \ | |
232 | MAT_ELEM_4X4(out, 2, 3) = 0.0f; \ | |
233 | MAT_ELEM_4X4(out, 3, 0) = -(xaxis[0] * eye[0] + xaxis[1] * eye[1] + xaxis[2] * eye[2]); \ | |
234 | MAT_ELEM_4X4(out, 3, 1) = -(yaxis[0] * eye[0] + yaxis[1] * eye[1] + yaxis[2] * eye[2]); \ | |
235 | MAT_ELEM_4X4(out, 3, 2) = (zaxis[0] * eye[0] + zaxis[1] * eye[1] + zaxis[2] * eye[2]); \ | |
236 | MAT_ELEM_4X4(out, 3, 3) = 1.f; \ | |
237 | } | |
238 | ||
239 | /* | |
240 | * Multiplies a with b, stores the result in out | |
241 | */ | |
242 | ||
243 | #define matrix_4x4_multiply(out, a, b) \ | |
244 | MAT_ELEM_4X4(out, 0, 0) = \ | |
245 | MAT_ELEM_4X4(a, 0, 0) * MAT_ELEM_4X4(b, 0, 0) + \ | |
246 | MAT_ELEM_4X4(a, 0, 1) * MAT_ELEM_4X4(b, 1, 0) + \ | |
247 | MAT_ELEM_4X4(a, 0, 2) * MAT_ELEM_4X4(b, 2, 0) + \ | |
248 | MAT_ELEM_4X4(a, 0, 3) * MAT_ELEM_4X4(b, 3, 0); \ | |
249 | MAT_ELEM_4X4(out, 0, 1) = \ | |
250 | MAT_ELEM_4X4(a, 0, 0) * MAT_ELEM_4X4(b, 0, 1) + \ | |
251 | MAT_ELEM_4X4(a, 0, 1) * MAT_ELEM_4X4(b, 1, 1) + \ | |
252 | MAT_ELEM_4X4(a, 0, 2) * MAT_ELEM_4X4(b, 2, 1) + \ | |
253 | MAT_ELEM_4X4(a, 0, 3) * MAT_ELEM_4X4(b, 3, 1); \ | |
254 | MAT_ELEM_4X4(out, 0, 2) = \ | |
255 | MAT_ELEM_4X4(a, 0, 0) * MAT_ELEM_4X4(b, 0, 2) + \ | |
256 | MAT_ELEM_4X4(a, 0, 1) * MAT_ELEM_4X4(b, 1, 2) + \ | |
257 | MAT_ELEM_4X4(a, 0, 2) * MAT_ELEM_4X4(b, 2, 2) + \ | |
258 | MAT_ELEM_4X4(a, 0, 3) * MAT_ELEM_4X4(b, 3, 2); \ | |
259 | MAT_ELEM_4X4(out, 0, 3) = \ | |
260 | MAT_ELEM_4X4(a, 0, 0) * MAT_ELEM_4X4(b, 0, 3) + \ | |
261 | MAT_ELEM_4X4(a, 0, 1) * MAT_ELEM_4X4(b, 1, 3) + \ | |
262 | MAT_ELEM_4X4(a, 0, 2) * MAT_ELEM_4X4(b, 2, 3) + \ | |
263 | MAT_ELEM_4X4(a, 0, 3) * MAT_ELEM_4X4(b, 3, 3); \ | |
264 | MAT_ELEM_4X4(out, 1, 0) = \ | |
265 | MAT_ELEM_4X4(a, 1, 0) * MAT_ELEM_4X4(b, 0, 0) + \ | |
266 | MAT_ELEM_4X4(a, 1, 1) * MAT_ELEM_4X4(b, 1, 0) + \ | |
267 | MAT_ELEM_4X4(a, 1, 2) * MAT_ELEM_4X4(b, 2, 0) + \ | |
268 | MAT_ELEM_4X4(a, 1, 3) * MAT_ELEM_4X4(b, 3, 0); \ | |
269 | MAT_ELEM_4X4(out, 1, 1) = \ | |
270 | MAT_ELEM_4X4(a, 1, 0) * MAT_ELEM_4X4(b, 0, 1) + \ | |
271 | MAT_ELEM_4X4(a, 1, 1) * MAT_ELEM_4X4(b, 1, 1) + \ | |
272 | MAT_ELEM_4X4(a, 1, 2) * MAT_ELEM_4X4(b, 2, 1) + \ | |
273 | MAT_ELEM_4X4(a, 1, 3) * MAT_ELEM_4X4(b, 3, 1); \ | |
274 | MAT_ELEM_4X4(out, 1, 2) = \ | |
275 | MAT_ELEM_4X4(a, 1, 0) * MAT_ELEM_4X4(b, 0, 2) + \ | |
276 | MAT_ELEM_4X4(a, 1, 1) * MAT_ELEM_4X4(b, 1, 2) + \ | |
277 | MAT_ELEM_4X4(a, 1, 2) * MAT_ELEM_4X4(b, 2, 2) + \ | |
278 | MAT_ELEM_4X4(a, 1, 3) * MAT_ELEM_4X4(b, 3, 2); \ | |
279 | MAT_ELEM_4X4(out, 1, 3) = \ | |
280 | MAT_ELEM_4X4(a, 1, 0) * MAT_ELEM_4X4(b, 0, 3) + \ | |
281 | MAT_ELEM_4X4(a, 1, 1) * MAT_ELEM_4X4(b, 1, 3) + \ | |
282 | MAT_ELEM_4X4(a, 1, 2) * MAT_ELEM_4X4(b, 2, 3) + \ | |
283 | MAT_ELEM_4X4(a, 1, 3) * MAT_ELEM_4X4(b, 3, 3); \ | |
284 | MAT_ELEM_4X4(out, 2, 0) = \ | |
285 | MAT_ELEM_4X4(a, 2, 0) * MAT_ELEM_4X4(b, 0, 0) + \ | |
286 | MAT_ELEM_4X4(a, 2, 1) * MAT_ELEM_4X4(b, 1, 0) + \ | |
287 | MAT_ELEM_4X4(a, 2, 2) * MAT_ELEM_4X4(b, 2, 0) + \ | |
288 | MAT_ELEM_4X4(a, 2, 3) * MAT_ELEM_4X4(b, 3, 0); \ | |
289 | MAT_ELEM_4X4(out, 2, 1) = \ | |
290 | MAT_ELEM_4X4(a, 2, 0) * MAT_ELEM_4X4(b, 0, 1) + \ | |
291 | MAT_ELEM_4X4(a, 2, 1) * MAT_ELEM_4X4(b, 1, 1) + \ | |
292 | MAT_ELEM_4X4(a, 2, 2) * MAT_ELEM_4X4(b, 2, 1) + \ | |
293 | MAT_ELEM_4X4(a, 2, 3) * MAT_ELEM_4X4(b, 3, 1); \ | |
294 | MAT_ELEM_4X4(out, 2, 2) = \ | |
295 | MAT_ELEM_4X4(a, 2, 0) * MAT_ELEM_4X4(b, 0, 2) + \ | |
296 | MAT_ELEM_4X4(a, 2, 1) * MAT_ELEM_4X4(b, 1, 2) + \ | |
297 | MAT_ELEM_4X4(a, 2, 2) * MAT_ELEM_4X4(b, 2, 2) + \ | |
298 | MAT_ELEM_4X4(a, 2, 3) * MAT_ELEM_4X4(b, 3, 2); \ | |
299 | MAT_ELEM_4X4(out, 2, 3) = \ | |
300 | MAT_ELEM_4X4(a, 2, 0) * MAT_ELEM_4X4(b, 0, 3) + \ | |
301 | MAT_ELEM_4X4(a, 2, 1) * MAT_ELEM_4X4(b, 1, 3) + \ | |
302 | MAT_ELEM_4X4(a, 2, 2) * MAT_ELEM_4X4(b, 2, 3) + \ | |
303 | MAT_ELEM_4X4(a, 2, 3) * MAT_ELEM_4X4(b, 3, 3); \ | |
304 | MAT_ELEM_4X4(out, 3, 0) = \ | |
305 | MAT_ELEM_4X4(a, 3, 0) * MAT_ELEM_4X4(b, 0, 0) + \ | |
306 | MAT_ELEM_4X4(a, 3, 1) * MAT_ELEM_4X4(b, 1, 0) + \ | |
307 | MAT_ELEM_4X4(a, 3, 2) * MAT_ELEM_4X4(b, 2, 0) + \ | |
308 | MAT_ELEM_4X4(a, 3, 3) * MAT_ELEM_4X4(b, 3, 0); \ | |
309 | MAT_ELEM_4X4(out, 3, 1) = \ | |
310 | MAT_ELEM_4X4(a, 3, 0) * MAT_ELEM_4X4(b, 0, 1) + \ | |
311 | MAT_ELEM_4X4(a, 3, 1) * MAT_ELEM_4X4(b, 1, 1) + \ | |
312 | MAT_ELEM_4X4(a, 3, 2) * MAT_ELEM_4X4(b, 2, 1) + \ | |
313 | MAT_ELEM_4X4(a, 3, 3) * MAT_ELEM_4X4(b, 3, 1); \ | |
314 | MAT_ELEM_4X4(out, 3, 2) = \ | |
315 | MAT_ELEM_4X4(a, 3, 0) * MAT_ELEM_4X4(b, 0, 2) + \ | |
316 | MAT_ELEM_4X4(a, 3, 1) * MAT_ELEM_4X4(b, 1, 2) + \ | |
317 | MAT_ELEM_4X4(a, 3, 2) * MAT_ELEM_4X4(b, 2, 2) + \ | |
318 | MAT_ELEM_4X4(a, 3, 3) * MAT_ELEM_4X4(b, 3, 2); \ | |
319 | MAT_ELEM_4X4(out, 3, 3) = \ | |
320 | MAT_ELEM_4X4(a, 3, 0) * MAT_ELEM_4X4(b, 0, 3) + \ | |
321 | MAT_ELEM_4X4(a, 3, 1) * MAT_ELEM_4X4(b, 1, 3) + \ | |
322 | MAT_ELEM_4X4(a, 3, 2) * MAT_ELEM_4X4(b, 2, 3) + \ | |
323 | MAT_ELEM_4X4(a, 3, 3) * MAT_ELEM_4X4(b, 3, 3) | |
324 | ||
325 | #define matrix_4x4_scale(mat, x, y, z) \ | |
326 | MAT_ELEM_4X4(mat, 0, 0) = x; \ | |
327 | MAT_ELEM_4X4(mat, 0, 1) = 0.0f; \ | |
328 | MAT_ELEM_4X4(mat, 0, 2) = 0.0f; \ | |
329 | MAT_ELEM_4X4(mat, 0, 3) = 0.0f; \ | |
330 | MAT_ELEM_4X4(mat, 1, 0) = 0.0f; \ | |
331 | MAT_ELEM_4X4(mat, 1, 1) = y; \ | |
332 | MAT_ELEM_4X4(mat, 1, 2) = 0.0f; \ | |
333 | MAT_ELEM_4X4(mat, 1, 3) = 0.0f; \ | |
334 | MAT_ELEM_4X4(mat, 2, 0) = 0.0f; \ | |
335 | MAT_ELEM_4X4(mat, 2, 1) = 0.0f; \ | |
336 | MAT_ELEM_4X4(mat, 2, 2) = z; \ | |
337 | MAT_ELEM_4X4(mat, 2, 3) = 0.0f; \ | |
338 | MAT_ELEM_4X4(mat, 3, 0) = 0.0f; \ | |
339 | MAT_ELEM_4X4(mat, 3, 1) = 0.0f; \ | |
340 | MAT_ELEM_4X4(mat, 3, 2) = 0.0f; \ | |
341 | MAT_ELEM_4X4(mat, 3, 3) = 1.0f | |
342 | ||
343 | /* | |
344 | * Builds a translation matrix. All other elements in | |
345 | * the matrix will be set to zero except for the | |
346 | * diagonal which is set to 1.0 | |
347 | */ | |
348 | ||
349 | #define matrix_4x4_translate(mat, x, y, z) \ | |
350 | MAT_ELEM_4X4(mat, 0, 0) = 1.0f; \ | |
351 | MAT_ELEM_4X4(mat, 0, 1) = 0.0f; \ | |
352 | MAT_ELEM_4X4(mat, 0, 2) = 0.0f; \ | |
353 | MAT_ELEM_4X4(mat, 0, 3) = x; \ | |
354 | MAT_ELEM_4X4(mat, 1, 0) = 0.0f; \ | |
355 | MAT_ELEM_4X4(mat, 1, 1) = 1.0f; \ | |
356 | MAT_ELEM_4X4(mat, 1, 2) = 1.0f; \ | |
357 | MAT_ELEM_4X4(mat, 1, 3) = y; \ | |
358 | MAT_ELEM_4X4(mat, 2, 0) = 0.0f; \ | |
359 | MAT_ELEM_4X4(mat, 2, 1) = 0.0f; \ | |
360 | MAT_ELEM_4X4(mat, 2, 2) = 1.0f; \ | |
361 | MAT_ELEM_4X4(mat, 2, 3) = z; \ | |
362 | MAT_ELEM_4X4(mat, 3, 0) = 0.0f; \ | |
363 | MAT_ELEM_4X4(mat, 3, 1) = 0.0f; \ | |
364 | MAT_ELEM_4X4(mat, 3, 2) = 0.0f; \ | |
365 | MAT_ELEM_4X4(mat, 3, 3) = 1.0f | |
366 | ||
367 | /* | |
368 | * Creates a perspective projection matrix. | |
369 | */ | |
370 | ||
371 | #define matrix_4x4_projection(mat, y_fov, aspect, znear, zfar) \ | |
372 | { \ | |
373 | float const a = 1.f / tan((y_fov) / 2.f); \ | |
374 | float delta_z = (zfar) - (znear); \ | |
375 | MAT_ELEM_4X4(mat, 0, 0) = a / (aspect); \ | |
376 | MAT_ELEM_4X4(mat, 0, 1) = 0.0f; \ | |
377 | MAT_ELEM_4X4(mat, 0, 2) = 0.0f; \ | |
378 | MAT_ELEM_4X4(mat, 0, 3) = 0.0f; \ | |
379 | MAT_ELEM_4X4(mat, 1, 0) = 0.0f; \ | |
380 | MAT_ELEM_4X4(mat, 1, 1) = a; \ | |
381 | MAT_ELEM_4X4(mat, 1, 2) = 0.0f; \ | |
382 | MAT_ELEM_4X4(mat, 1, 3) = 0.0f; \ | |
383 | MAT_ELEM_4X4(mat, 2, 0) = 0.0f; \ | |
384 | MAT_ELEM_4X4(mat, 2, 1) = 0.0f; \ | |
385 | MAT_ELEM_4X4(mat, 2, 2) = -(((zfar) + (znear)) / delta_z); \ | |
386 | MAT_ELEM_4X4(mat, 2, 3) = -1.f; \ | |
387 | MAT_ELEM_4X4(mat, 3, 0) = 0.0f; \ | |
388 | MAT_ELEM_4X4(mat, 3, 1) = 0.0f; \ | |
389 | MAT_ELEM_4X4(mat, 3, 2) = -((2.f * (zfar) * (znear)) / delta_z); \ | |
390 | MAT_ELEM_4X4(mat, 3, 3) = 0.0f; \ | |
391 | } | |
392 | ||
393 | RETRO_END_DECLS | |
394 | ||
395 | #endif |