1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19 
20 //
21 // m_mat4.c
22 //
23 
24 #include "shared.h"
25 
26 mat4x4_t	mat4x4Identity = {
27 	1, 0, 0, 0,
28 	0, 1, 0, 0,
29 	0, 0, 1, 0,
30 	0, 0, 0, 1
31 };
32 
33 /*
34 Multiply matrices together for combined results.
35 
36 Identity
37 [ 1,   0,   0,   0 ]
38 [ 0,   1,   0,   0 ]
39 [ 0,   0,   1,   0 ]
40 [ 0,   0,   0,   1 ]
41 
42 Rotation on X
43 [ 1,   0,   0,   0 ]
44 [ 0,   cx,  -sx, 0 ]
45 [ 0,   sx,  cx,  0 ]
46 [ 0,   0,   0,   1 ]
47 
48 Rotation on Y
49 [ cy,  0,   sy,  0 ]
50 [ 0,   1,   0,   0 ]
51 [ -sy, 0,   cy,  0 ]
52 [ 0,   0,   0,   1 ]
53 
54 Rotation on Z
55 [ cz,  -sz, 0,   0 ]
56 [ sz,  cz,  0,   0 ]
57 [ 0,   0,   1,   0 ]
58 [ 0,   0,   0,   1 ]
59 
60 Scale
61 [ sx,  0,   0,   0 ]
62 [ 0,   sy,  0,   0 ]
63 [ 0,   0,   sz,  0 ]
64 [ 0,   0,   0,   1 ]
65 
66 Translation
67 [ 1,   0,   0,   0 ]
68 [ 0,   1,   0,   0 ]
69 [ 0,   0,   1,   0 ]
70 [ tx,  ty,  tz,  1 ]
71 */
72 
73 /*
74 =============================================================================
75 
76 	4x4 MATRICES
77 
78 =============================================================================
79 */
80 
81 /*
82 ===============
83 Matrix4_Compare
84 ===============
85 */
Matrix4_Compare(mat4x4_t a,mat4x4_t b)86 qBool Matrix4_Compare (mat4x4_t a, mat4x4_t b)
87 {
88 	int		i;
89 
90 	for (i=0 ; i<16 ; i++) {
91 		if (a[i] != b[i])
92 			return qFalse;
93 	}
94 
95 	return qTrue;
96 }
97 
98 
99 /*
100 ===============
101 Matrix4_Copy
102 ===============
103 */
Matrix4_Copy(mat4x4_t a,mat4x4_t b)104 void Matrix4_Copy (mat4x4_t a, mat4x4_t b)
105 {
106 	b[0 ] = a[0 ];
107 	b[1 ] = a[1 ];
108 	b[2 ] = a[2 ];
109 	b[3 ] = a[3 ];
110 	b[4 ] = a[4 ];
111 	b[5 ] = a[5 ];
112 	b[6 ] = a[6 ];
113 	b[7 ] = a[7 ];
114 	b[8 ] = a[8 ];
115 	b[9 ] = a[9 ];
116 	b[10] = a[10];
117 	b[11] = a[11];
118 	b[12] = a[12];
119 	b[13] = a[13];
120 	b[14] = a[14];
121 	b[15] = a[15];
122 }
123 
124 
125 /*
126 ===============
127 Matrix4_Identity
128 ===============
129 */
Matrix4_Identity(mat4x4_t mat)130 void Matrix4_Identity (mat4x4_t mat)
131 {
132 	mat[0 ] = mat4x4Identity[0 ];
133 	mat[1 ] = mat4x4Identity[1 ];
134 	mat[2 ] = mat4x4Identity[2 ];
135 	mat[3 ] = mat4x4Identity[3 ];
136 	mat[4 ] = mat4x4Identity[4 ];
137 	mat[5 ] = mat4x4Identity[5 ];
138 	mat[6 ] = mat4x4Identity[6 ];
139 	mat[7 ] = mat4x4Identity[7 ];
140 	mat[8 ] = mat4x4Identity[8 ];
141 	mat[9 ] = mat4x4Identity[9 ];
142 	mat[10] = mat4x4Identity[10];
143 	mat[11] = mat4x4Identity[11];
144 	mat[12] = mat4x4Identity[12];
145 	mat[13] = mat4x4Identity[13];
146 	mat[14] = mat4x4Identity[14];
147 	mat[15] = mat4x4Identity[15];
148 }
149 
150 
151 /*
152 ===============
153 Matrix4_Matrix3
154 ===============
155 */
Matrix4_Matrix3(mat4x4_t in,mat3x3_t out)156 void Matrix4_Matrix3 (mat4x4_t in, mat3x3_t out)
157 {
158 	out[0][0] = in[0 ];
159 	out[0][1] = in[4 ];
160 	out[0][2] = in[8 ];
161 
162 	out[1][0] = in[1 ];
163 	out[1][1] = in[5 ];
164 	out[1][2] = in[9 ];
165 
166 	out[2][0] = in[2 ];
167 	out[2][1] = in[6 ];
168 	out[2][2] = in[10];
169 }
170 
171 
172 /*
173 ===============
174 Matrix4_Multiply
175 ===============
176 */
Matrix4_Multiply(mat4x4_t a,mat4x4_t b,mat4x4_t product)177 void Matrix4_Multiply (mat4x4_t a, mat4x4_t b, mat4x4_t product)
178 {
179 	product[0 ] = a[0]*b[0 ] + a[4]*b[1 ] + a[8 ]*b[2 ] + a[12]*b[3 ];
180 	product[1 ] = a[1]*b[0 ] + a[5]*b[1 ] + a[9 ]*b[2 ] + a[13]*b[3 ];
181 	product[2 ] = a[2]*b[0 ] + a[6]*b[1 ] + a[10]*b[2 ] + a[14]*b[3 ];
182 	product[3 ] = a[3]*b[0 ] + a[7]*b[1 ] + a[11]*b[2 ] + a[15]*b[3 ];
183 	product[4 ] = a[0]*b[4 ] + a[4]*b[5 ] + a[8 ]*b[6 ] + a[12]*b[7 ];
184 	product[5 ] = a[1]*b[4 ] + a[5]*b[5 ] + a[9 ]*b[6 ] + a[13]*b[7 ];
185 	product[6 ] = a[2]*b[4 ] + a[6]*b[5 ] + a[10]*b[6 ] + a[14]*b[7 ];
186 	product[7 ] = a[3]*b[4 ] + a[7]*b[5 ] + a[11]*b[6 ] + a[15]*b[7 ];
187 	product[8 ] = a[0]*b[8 ] + a[4]*b[9 ] + a[8 ]*b[10] + a[12]*b[11];
188 	product[9 ] = a[1]*b[8 ] + a[5]*b[9 ] + a[9 ]*b[10] + a[13]*b[11];
189 	product[10] = a[2]*b[8 ] + a[6]*b[9 ] + a[10]*b[10] + a[14]*b[11];
190 	product[11] = a[3]*b[8 ] + a[7]*b[9 ] + a[11]*b[10] + a[15]*b[11];
191 	product[12] = a[0]*b[12] + a[4]*b[13] + a[8 ]*b[14] + a[12]*b[15];
192 	product[13] = a[1]*b[12] + a[5]*b[13] + a[9 ]*b[14] + a[13]*b[15];
193 	product[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15];
194 	product[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15];
195 }
196 
197 
198 /*
199 ===============
200 Matrix4_Multiply_Vec3
201 ===============
202 */
Matrix4_Multiply_Vec3(mat4x4_t m,vec3_t v,vec3_t out)203 void Matrix4_Multiply_Vec3 (mat4x4_t m, vec3_t v, vec3_t out)
204 {
205 	out[0] = (float)(m[0]*v[0] + m[1]*v[1] + m[2 ]*v[2]);
206 	out[1] = (float)(m[4]*v[0] + m[5]*v[1] + m[6 ]*v[2]);
207 	out[2] = (float)(m[8]*v[0] + m[9]*v[1] + m[10]*v[2]);
208 }
209 
210 
211 /*
212 ===============
213 Matrix4_Multiply_Vec4
214 ===============
215 */
Matrix4_Multiply_Vec4(mat4x4_t m,vec4_t v,vec4_t out)216 void Matrix4_Multiply_Vec4 (mat4x4_t m, vec4_t v, vec4_t out)
217 {
218 	out[0] = (float)(m[0]*v[0] + m[4]*v[1] + m[8 ]*v[2] + m[12]*v[3]);
219 	out[1] = (float)(m[1]*v[0] + m[5]*v[1] + m[9 ]*v[2] + m[13]*v[3]);
220 	out[2] = (float)(m[2]*v[0] + m[6]*v[1] + m[10]*v[2] + m[14]*v[3]);
221 	out[3] = (float)(m[3]*v[0] + m[7]*v[1] + m[11]*v[2] + m[15]*v[3]);
222 }
223 
224 /*
225 ===============
226 Matrix4_MultiplyFast
227 ===============
228 */
Matrix4_MultiplyFast(mat4x4_t a,mat4x4_t b,mat4x4_t product)229 void Matrix4_MultiplyFast (mat4x4_t a, mat4x4_t b, mat4x4_t product)
230 {
231 	product[0]  = a[0] * b[0 ] + a[4] * b[1 ] + a[8 ] * b[2];
232 	product[1]  = a[1] * b[0 ] + a[5] * b[1 ] + a[9 ] * b[2];
233 	product[2]  = a[2] * b[0 ] + a[6] * b[1 ] + a[10] * b[2];
234 	product[3]  = 0.0f;
235 	product[4]  = a[0] * b[4 ] + a[4] * b[5 ] + a[8 ] * b[6];
236 	product[5]  = a[1] * b[4 ] + a[5] * b[5 ] + a[9 ] * b[6];
237 	product[6]  = a[2] * b[4 ] + a[6] * b[5 ] + a[10] * b[6];
238 	product[7]  = 0.0f;
239 	product[8]  = a[0] * b[8 ] + a[4] * b[9 ] + a[8 ] * b[10];
240 	product[9]  = a[1] * b[8 ] + a[5] * b[9 ] + a[9 ] * b[10];
241 	product[10] = a[2] * b[8 ] + a[6] * b[9 ] + a[10] * b[10];
242 	product[11] = 0.0f;
243 	product[12] = a[0] * b[12] + a[4] * b[13] + a[8 ] * b[14] + a[12];
244 	product[13] = a[1] * b[12] + a[5] * b[13] + a[9 ] * b[14] + a[13];
245 	product[14] = a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14];
246 	product[15] = 1.0f;
247 }
248 
249 
250 /*
251 ===============
252 Matrix4_MultiplyFast
253 ===============
254 */
Matrix4_MultiplyFast2(const mat4x4_t m1,const mat4x4_t m2,mat4x4_t out)255 void Matrix4_MultiplyFast2 (const mat4x4_t m1, const mat4x4_t m2, mat4x4_t out)
256 {
257 	out[0]  = m1[0] * m2[0] + m1[4] * m2[1] + m1[12] * m2[3];
258 	out[1]  = m1[1] * m2[0] + m1[5] * m2[1] + m1[13] * m2[3];
259 	out[2]  = m2[2];
260 	out[3]  = m2[3];
261 	out[4]  = m1[0] * m2[4] + m1[4] * m2[5] + m1[12] * m2[7];
262 	out[5]  = m1[1] * m2[4] + m1[5] * m2[5] + m1[13] * m2[7];
263 	out[6]  = m2[6];
264 	out[7]  = m2[7];
265 	out[8]  = m1[0] * m2[8] + m1[4] * m2[9] + m1[12] * m2[11];
266 	out[9]  = m1[1] * m2[8] + m1[5] * m2[9] + m1[13] * m2[11];
267 	out[10] = m2[10];
268 	out[11] = m2[11];
269 	out[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[12] * m2[15];
270 	out[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[13] * m2[15];
271 	out[14] = m2[14];
272 	out[15] = m2[15];
273 }
274 
275 
276 /*
277 ===============
278 Matrix4_Rotate
279 ===============
280 */
Matrix4_Rotate(mat4x4_t a,float angle,float x,float y,float z)281 void Matrix4_Rotate (mat4x4_t a, float angle, float x, float y, float z)
282 {
283 	mat4x4_t	m, b;
284 	double	c = cos (DEG2RAD (angle));
285 	double	s = sin (DEG2RAD (angle));
286 	double	mc = 1 - c, t1, t2;
287 
288 	m[0]  = (x * x * mc) + c;
289 	m[5]  = (y * y * mc) + c;
290 	m[10] = (z * z * mc) + c;
291 
292 	t1 = y * x * mc;
293 	t2 = z * s;
294 	m[1] = t1 + t2;
295 	m[4] = t1 - t2;
296 
297 	t1 = x * z * mc;
298 	t2 = y * s;
299 	m[2] = t1 - t2;
300 	m[8] = t1 + t2;
301 
302 	t1 = y * z * mc;
303 	t2 = x * s;
304 	m[6] = t1 + t2;
305 	m[9] = t1 - t2;
306 
307 	m[3] = m[7] = m[11] = m[12] = m[13] = m[14] = 0;
308 	m[15] = 1;
309 
310 	Matrix4_Copy (a, b);
311 	Matrix4_MultiplyFast (b, m, a);
312 }
313 
314 
315 /*
316 ===============
317 Matrix4_Scale
318 ===============
319 */
Matrix4_Scale(mat4x4_t m,float x,float y,float z)320 void Matrix4_Scale (mat4x4_t m, float x, float y, float z)
321 {
322 	m[0] *= x;		m[4] *= y;		m[8 ] *= z;
323 	m[1] *= x;		m[5] *= y;		m[9 ] *= z;
324 	m[2] *= x;		m[6] *= y;		m[10] *= z;
325 	m[3] *= x;		m[7] *= y;		m[11] *= z;
326 }
327 
328 
329 /*
330 ===============
331 Matrix4_Translate
332 ===============
333 */
Matrix4_Translate(mat4x4_t m,float x,float y,float z)334 void Matrix4_Translate (mat4x4_t m, float x, float y, float z)
335 {
336 	m[12] = m[0] * x + m[4] * y + m[8 ] * z + m[12];
337 	m[13] = m[1] * x + m[5] * y + m[9 ] * z + m[13];
338 	m[14] = m[2] * x + m[6] * y + m[10] * z + m[14];
339 	m[15] = m[3] * x + m[7] * y + m[11] * z + m[15];
340 }
341 
342 /*
343 ===============
344 Matrix4_Transpose
345 ===============
346 */
Matrix4_Transpose(mat4x4_t m,mat4x4_t ret)347 void Matrix4_Transpose (mat4x4_t m, mat4x4_t ret)
348 {
349 	ret[0 ] = m[0]; ret[1 ] = m[4]; ret[2 ] = m[8 ]; ret[3 ] = m[12];
350 	ret[4 ] = m[1]; ret[5 ] = m[5]; ret[6 ] = m[9 ]; ret[7 ] = m[13];
351 	ret[8 ] = m[2]; ret[9 ] = m[6]; ret[10] = m[10]; ret[11] = m[14];
352 	ret[12] = m[3]; ret[13] = m[7]; ret[14] = m[11]; ret[15] = m[15];
353 }
354