UFO: Alien Invasion
Loading...
Searching...
No Matches
r_matrix.cpp
Go to the documentation of this file.
1/*
2 * Copyright(c) 2010 DarkPlaces.
3 * Copyright(c) 2010 Quake2World.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or(at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 *
14 * See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include "r_local.h"
22#include "r_matrix.h"
23
24const matrix4x4_t identitymatrix = { { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } } };
25
27{
28 *out = *in;
29}
30
32{
33 out->m[0][0] = in->m[0][0];
34 out->m[0][1] = in->m[0][1];
35 out->m[0][2] = in->m[0][2];
36 out->m[0][3] = 0.0f;
37 out->m[1][0] = in->m[1][0];
38 out->m[1][1] = in->m[1][1];
39 out->m[1][2] = in->m[1][2];
40 out->m[1][3] = 0.0f;
41 out->m[2][0] = in->m[2][0];
42 out->m[2][1] = in->m[2][1];
43 out->m[2][2] = in->m[2][2];
44 out->m[2][3] = 0.0f;
45 out->m[3][0] = 0.0f;
46 out->m[3][1] = 0.0f;
47 out->m[3][2] = 0.0f;
48 out->m[3][3] = 1.0f;
49}
50
52{
53#ifdef MATRIX4x4_OPENGLORIENTATION
54 out->m[0][0] = 1.0f;
55 out->m[1][0] = 0.0f;
56 out->m[2][0] = 0.0f;
57 out->m[3][0] = in->m[0][3];
58 out->m[0][1] = 0.0f;
59 out->m[1][1] = 1.0f;
60 out->m[2][1] = 0.0f;
61 out->m[3][1] = in->m[1][3];
62 out->m[0][2] = 0.0f;
63 out->m[1][2] = 0.0f;
64 out->m[2][2] = 1.0f;
65 out->m[3][2] = in->m[2][3];
66 out->m[0][3] = 0.0f;
67 out->m[1][3] = 0.0f;
68 out->m[2][3] = 0.0f;
69 out->m[3][3] = 1.0f;
70#else
71 out->m[0][0] = 1.0f;
72 out->m[0][1] = 0.0f;
73 out->m[0][2] = 0.0f;
74 out->m[0][3] = in->m[0][3];
75 out->m[1][0] = 0.0f;
76 out->m[1][1] = 1.0f;
77 out->m[1][2] = 0.0f;
78 out->m[1][3] = in->m[1][3];
79 out->m[2][0] = 0.0f;
80 out->m[2][1] = 0.0f;
81 out->m[2][2] = 1.0f;
82 out->m[2][3] = in->m[2][3];
83 out->m[3][0] = 0.0f;
84 out->m[3][1] = 0.0f;
85 out->m[3][2] = 0.0f;
86 out->m[3][3] = 1.0f;
87#endif
88}
89
90void Matrix4x4_Concat (matrix4x4_t* out, const matrix4x4_t* in1, const matrix4x4_t* in2)
91{
92#ifdef MATRIX4x4_OPENGLORIENTATION
93 out->m[0][0] = in1->m[0][0] * in2->m[0][0] + in1->m[1][0] * in2->m[0][1] + in1->m[2][0] * in2->m[0][2] + in1->m[3][0] * in2->m[0][3];
94 out->m[1][0] = in1->m[0][0] * in2->m[1][0] + in1->m[1][0] * in2->m[1][1] + in1->m[2][0] * in2->m[1][2] + in1->m[3][0] * in2->m[1][3];
95 out->m[2][0] = in1->m[0][0] * in2->m[2][0] + in1->m[1][0] * in2->m[2][1] + in1->m[2][0] * in2->m[2][2] + in1->m[3][0] * in2->m[2][3];
96 out->m[3][0] = in1->m[0][0] * in2->m[3][0] + in1->m[1][0] * in2->m[3][1] + in1->m[2][0] * in2->m[3][2] + in1->m[3][0] * in2->m[3][3];
97 out->m[0][1] = in1->m[0][1] * in2->m[0][0] + in1->m[1][1] * in2->m[0][1] + in1->m[2][1] * in2->m[0][2] + in1->m[3][1] * in2->m[0][3];
98 out->m[1][1] = in1->m[0][1] * in2->m[1][0] + in1->m[1][1] * in2->m[1][1] + in1->m[2][1] * in2->m[1][2] + in1->m[3][1] * in2->m[1][3];
99 out->m[2][1] = in1->m[0][1] * in2->m[2][0] + in1->m[1][1] * in2->m[2][1] + in1->m[2][1] * in2->m[2][2] + in1->m[3][1] * in2->m[2][3];
100 out->m[3][1] = in1->m[0][1] * in2->m[3][0] + in1->m[1][1] * in2->m[3][1] + in1->m[2][1] * in2->m[3][2] + in1->m[3][1] * in2->m[3][3];
101 out->m[0][2] = in1->m[0][2] * in2->m[0][0] + in1->m[1][2] * in2->m[0][1] + in1->m[2][2] * in2->m[0][2] + in1->m[3][2] * in2->m[0][3];
102 out->m[1][2] = in1->m[0][2] * in2->m[1][0] + in1->m[1][2] * in2->m[1][1] + in1->m[2][2] * in2->m[1][2] + in1->m[3][2] * in2->m[1][3];
103 out->m[2][2] = in1->m[0][2] * in2->m[2][0] + in1->m[1][2] * in2->m[2][1] + in1->m[2][2] * in2->m[2][2] + in1->m[3][2] * in2->m[2][3];
104 out->m[3][2] = in1->m[0][2] * in2->m[3][0] + in1->m[1][2] * in2->m[3][1] + in1->m[2][2] * in2->m[3][2] + in1->m[3][2] * in2->m[3][3];
105 out->m[0][3] = in1->m[0][3] * in2->m[0][0] + in1->m[1][3] * in2->m[0][1] + in1->m[2][3] * in2->m[0][2] + in1->m[3][3] * in2->m[0][3];
106 out->m[1][3] = in1->m[0][3] * in2->m[1][0] + in1->m[1][3] * in2->m[1][1] + in1->m[2][3] * in2->m[1][2] + in1->m[3][3] * in2->m[1][3];
107 out->m[2][3] = in1->m[0][3] * in2->m[2][0] + in1->m[1][3] * in2->m[2][1] + in1->m[2][3] * in2->m[2][2] + in1->m[3][3] * in2->m[2][3];
108 out->m[3][3] = in1->m[0][3] * in2->m[3][0] + in1->m[1][3] * in2->m[3][1] + in1->m[2][3] * in2->m[3][2] + in1->m[3][3] * in2->m[3][3];
109#else
110 out->m[0][0] = in1->m[0][0] * in2->m[0][0] + in1->m[0][1] * in2->m[1][0] + in1->m[0][2] * in2->m[2][0]
111 + in1->m[0][3] * in2->m[3][0];
112 out->m[0][1] = in1->m[0][0] * in2->m[0][1] + in1->m[0][1] * in2->m[1][1] + in1->m[0][2] * in2->m[2][1]
113 + in1->m[0][3] * in2->m[3][1];
114 out->m[0][2] = in1->m[0][0] * in2->m[0][2] + in1->m[0][1] * in2->m[1][2] + in1->m[0][2] * in2->m[2][2]
115 + in1->m[0][3] * in2->m[3][2];
116 out->m[0][3] = in1->m[0][0] * in2->m[0][3] + in1->m[0][1] * in2->m[1][3] + in1->m[0][2] * in2->m[2][3]
117 + in1->m[0][3] * in2->m[3][3];
118 out->m[1][0] = in1->m[1][0] * in2->m[0][0] + in1->m[1][1] * in2->m[1][0] + in1->m[1][2] * in2->m[2][0]
119 + in1->m[1][3] * in2->m[3][0];
120 out->m[1][1] = in1->m[1][0] * in2->m[0][1] + in1->m[1][1] * in2->m[1][1] + in1->m[1][2] * in2->m[2][1]
121 + in1->m[1][3] * in2->m[3][1];
122 out->m[1][2] = in1->m[1][0] * in2->m[0][2] + in1->m[1][1] * in2->m[1][2] + in1->m[1][2] * in2->m[2][2]
123 + in1->m[1][3] * in2->m[3][2];
124 out->m[1][3] = in1->m[1][0] * in2->m[0][3] + in1->m[1][1] * in2->m[1][3] + in1->m[1][2] * in2->m[2][3]
125 + in1->m[1][3] * in2->m[3][3];
126 out->m[2][0] = in1->m[2][0] * in2->m[0][0] + in1->m[2][1] * in2->m[1][0] + in1->m[2][2] * in2->m[2][0]
127 + in1->m[2][3] * in2->m[3][0];
128 out->m[2][1] = in1->m[2][0] * in2->m[0][1] + in1->m[2][1] * in2->m[1][1] + in1->m[2][2] * in2->m[2][1]
129 + in1->m[2][3] * in2->m[3][1];
130 out->m[2][2] = in1->m[2][0] * in2->m[0][2] + in1->m[2][1] * in2->m[1][2] + in1->m[2][2] * in2->m[2][2]
131 + in1->m[2][3] * in2->m[3][2];
132 out->m[2][3] = in1->m[2][0] * in2->m[0][3] + in1->m[2][1] * in2->m[1][3] + in1->m[2][2] * in2->m[2][3]
133 + in1->m[2][3] * in2->m[3][3];
134 out->m[3][0] = in1->m[3][0] * in2->m[0][0] + in1->m[3][1] * in2->m[1][0] + in1->m[3][2] * in2->m[2][0]
135 + in1->m[3][3] * in2->m[3][0];
136 out->m[3][1] = in1->m[3][0] * in2->m[0][1] + in1->m[3][1] * in2->m[1][1] + in1->m[3][2] * in2->m[2][1]
137 + in1->m[3][3] * in2->m[3][1];
138 out->m[3][2] = in1->m[3][0] * in2->m[0][2] + in1->m[3][1] * in2->m[1][2] + in1->m[3][2] * in2->m[2][2]
139 + in1->m[3][3] * in2->m[3][2];
140 out->m[3][3] = in1->m[3][0] * in2->m[0][3] + in1->m[3][1] * in2->m[1][3] + in1->m[3][2] * in2->m[2][3]
141 + in1->m[3][3] * in2->m[3][3];
142#endif
143}
144
146{
147 out->m[0][0] = in1->m[0][0];
148 out->m[0][1] = in1->m[1][0];
149 out->m[0][2] = in1->m[2][0];
150 out->m[0][3] = in1->m[3][0];
151 out->m[1][0] = in1->m[0][1];
152 out->m[1][1] = in1->m[1][1];
153 out->m[1][2] = in1->m[2][1];
154 out->m[1][3] = in1->m[3][1];
155 out->m[2][0] = in1->m[0][2];
156 out->m[2][1] = in1->m[1][2];
157 out->m[2][2] = in1->m[2][2];
158 out->m[2][3] = in1->m[3][2];
159 out->m[3][0] = in1->m[0][3];
160 out->m[3][1] = in1->m[1][3];
161 out->m[3][2] = in1->m[2][3];
162 out->m[3][3] = in1->m[3][3];
163}
164
165#if 1
171{
172 float det;
173
174 /* note: orientation does not matter, as transpose(invert(transpose(m))) == invert(m), proof:
175 * transpose(invert(transpose(m))) * m
176 * = transpose(invert(transpose(m))) * transpose(transpose(m))
177 * = transpose(transpose(m) * invert(transpose(m)))
178 * = transpose(identity)
179 * = identity
180 */
181
182 /* this seems to help gcc's common subexpression elimination, and also makes the code look nicer */
183 float m00 = in1->m[0][0], m01 = in1->m[0][1], m02 = in1->m[0][2], m03 = in1->m[0][3], m10 = in1->m[1][0], m11 =
184 in1->m[1][1], m12 = in1->m[1][2], m13 = in1->m[1][3], m20 = in1->m[2][0], m21 = in1->m[2][1], m22 =
185 in1->m[2][2], m23 = in1->m[2][3], m30 = in1->m[3][0], m31 = in1->m[3][1], m32 = in1->m[3][2], m33 =
186 in1->m[3][3];
187
188 /* calculate the adjoint */
189 out->m[0][0] = (m11 * (m22 * m33 - m23 * m32) - m21 * (m12 * m33 - m13 * m32) + m31 * (m12 * m23 - m13 * m22));
190 out->m[0][1] = -(m01 * (m22 * m33 - m23 * m32) - m21 * (m02 * m33 - m03 * m32) + m31 * (m02 * m23 - m03 * m22));
191 out->m[0][2] = (m01 * (m12 * m33 - m13 * m32) - m11 * (m02 * m33 - m03 * m32) + m31 * (m02 * m13 - m03 * m12));
192 out->m[0][3] = -(m01 * (m12 * m23 - m13 * m22) - m11 * (m02 * m23 - m03 * m22) + m21 * (m02 * m13 - m03 * m12));
193 out->m[1][0] = -(m10 * (m22 * m33 - m23 * m32) - m20 * (m12 * m33 - m13 * m32) + m30 * (m12 * m23 - m13 * m22));
194 out->m[1][1] = (m00 * (m22 * m33 - m23 * m32) - m20 * (m02 * m33 - m03 * m32) + m30 * (m02 * m23 - m03 * m22));
195 out->m[1][2] = -(m00 * (m12 * m33 - m13 * m32) - m10 * (m02 * m33 - m03 * m32) + m30 * (m02 * m13 - m03 * m12));
196 out->m[1][3] = (m00 * (m12 * m23 - m13 * m22) - m10 * (m02 * m23 - m03 * m22) + m20 * (m02 * m13 - m03 * m12));
197 out->m[2][0] = (m10 * (m21 * m33 - m23 * m31) - m20 * (m11 * m33 - m13 * m31) + m30 * (m11 * m23 - m13 * m21));
198 out->m[2][1] = -(m00 * (m21 * m33 - m23 * m31) - m20 * (m01 * m33 - m03 * m31) + m30 * (m01 * m23 - m03 * m21));
199 out->m[2][2] = (m00 * (m11 * m33 - m13 * m31) - m10 * (m01 * m33 - m03 * m31) + m30 * (m01 * m13 - m03 * m11));
200 out->m[2][3] = -(m00 * (m11 * m23 - m13 * m21) - m10 * (m01 * m23 - m03 * m21) + m20 * (m01 * m13 - m03 * m11));
201 out->m[3][0] = -(m10 * (m21 * m32 - m22 * m31) - m20 * (m11 * m32 - m12 * m31) + m30 * (m11 * m22 - m12 * m21));
202 out->m[3][1] = (m00 * (m21 * m32 - m22 * m31) - m20 * (m01 * m32 - m02 * m31) + m30 * (m01 * m22 - m02 * m21));
203 out->m[3][2] = -(m00 * (m11 * m32 - m12 * m31) - m10 * (m01 * m32 - m02 * m31) + m30 * (m01 * m12 - m02 * m11));
204 out->m[3][3] = (m00 * (m11 * m22 - m12 * m21) - m10 * (m01 * m22 - m02 * m21) + m20 * (m01 * m12 - m02 * m11));
205
206 /* calculate the determinant (as inverse == 1/det * adjoint, adjoint * m == identity * det, so this calculates the det) */
207 det = m00 * out->m[0][0] + m10 * out->m[0][1] + m20 * out->m[0][2] + m30 * out->m[0][3];
208 if (det == 0.0f)
209 return 0;
210
211 /* multiplications are faster than divisions, usually */
212 det = 1.0f / det;
213
214 /* manually unrolled loop to multiply all matrix elements by 1/det */
215 out->m[0][0] *= det;
216 out->m[0][1] *= det;
217 out->m[0][2] *= det;
218 out->m[0][3] *= det;
219 out->m[1][0] *= det;
220 out->m[1][1] *= det;
221 out->m[1][2] *= det;
222 out->m[1][3] *= det;
223 out->m[2][0] *= det;
224 out->m[2][1] *= det;
225 out->m[2][2] *= det;
226 out->m[2][3] *= det;
227 out->m[3][0] *= det;
228 out->m[3][1] *= det;
229 out->m[3][2] *= det;
230 out->m[3][3] *= det;
231
232 return 1;
233}
234#elif 1
238int Matrix4x4_Invert_Full (matrix4x4_t* out, const matrix4x4_t* in1)
239{
240 matrix4x4_t temp;
241 double det;
242 int i, j;
243
244#ifdef MATRIX4x4_OPENGLORIENTATION
245 temp.m[0][0] = in1->m[1][1]*in1->m[2][2]*in1->m[3][3] - in1->m[1][1]*in1->m[2][3]*in1->m[3][2] - in1->m[2][1]*in1->m[1][2]*in1->m[3][3] + in1->m[2][1]*in1->m[1][3]*in1->m[3][2] + in1->m[3][1]*in1->m[1][2]*in1->m[2][3] - in1->m[3][1]*in1->m[1][3]*in1->m[2][2];
246 temp.m[1][0] = -in1->m[1][0]*in1->m[2][2]*in1->m[3][3] + in1->m[1][0]*in1->m[2][3]*in1->m[3][2] + in1->m[2][0]*in1->m[1][2]*in1->m[3][3] - in1->m[2][0]*in1->m[1][3]*in1->m[3][2] - in1->m[3][0]*in1->m[1][2]*in1->m[2][3] + in1->m[3][0]*in1->m[1][3]*in1->m[2][2];
247 temp.m[2][0] = in1->m[1][0]*in1->m[2][1]*in1->m[3][3] - in1->m[1][0]*in1->m[2][3]*in1->m[3][1] - in1->m[2][0]*in1->m[1][1]*in1->m[3][3] + in1->m[2][0]*in1->m[1][3]*in1->m[3][1] + in1->m[3][0]*in1->m[1][1]*in1->m[2][3] - in1->m[3][0]*in1->m[1][3]*in1->m[2][1];
248 temp.m[3][0] = -in1->m[1][0]*in1->m[2][1]*in1->m[3][2] + in1->m[1][0]*in1->m[2][2]*in1->m[3][1] + in1->m[2][0]*in1->m[1][1]*in1->m[3][2] - in1->m[2][0]*in1->m[1][2]*in1->m[3][1] - in1->m[3][0]*in1->m[1][1]*in1->m[2][2] + in1->m[3][0]*in1->m[1][2]*in1->m[2][1];
249 temp.m[0][1] = -in1->m[0][1]*in1->m[2][2]*in1->m[3][3] + in1->m[0][1]*in1->m[2][3]*in1->m[3][2] + in1->m[2][1]*in1->m[0][2]*in1->m[3][3] - in1->m[2][1]*in1->m[0][3]*in1->m[3][2] - in1->m[3][1]*in1->m[0][2]*in1->m[2][3] + in1->m[3][1]*in1->m[0][3]*in1->m[2][2];
250 temp.m[1][1] = in1->m[0][0]*in1->m[2][2]*in1->m[3][3] - in1->m[0][0]*in1->m[2][3]*in1->m[3][2] - in1->m[2][0]*in1->m[0][2]*in1->m[3][3] + in1->m[2][0]*in1->m[0][3]*in1->m[3][2] + in1->m[3][0]*in1->m[0][2]*in1->m[2][3] - in1->m[3][0]*in1->m[0][3]*in1->m[2][2];
251 temp.m[2][1] = -in1->m[0][0]*in1->m[2][1]*in1->m[3][3] + in1->m[0][0]*in1->m[2][3]*in1->m[3][1] + in1->m[2][0]*in1->m[0][1]*in1->m[3][3] - in1->m[2][0]*in1->m[0][3]*in1->m[3][1] - in1->m[3][0]*in1->m[0][1]*in1->m[2][3] + in1->m[3][0]*in1->m[0][3]*in1->m[2][1];
252 temp.m[3][1] = in1->m[0][0]*in1->m[2][1]*in1->m[3][2] - in1->m[0][0]*in1->m[2][2]*in1->m[3][1] - in1->m[2][0]*in1->m[0][1]*in1->m[3][2] + in1->m[2][0]*in1->m[0][2]*in1->m[3][1] + in1->m[3][0]*in1->m[0][1]*in1->m[2][2] - in1->m[3][0]*in1->m[0][2]*in1->m[2][1];
253 temp.m[0][2] = in1->m[0][1]*in1->m[1][2]*in1->m[3][3] - in1->m[0][1]*in1->m[1][3]*in1->m[3][2] - in1->m[1][1]*in1->m[0][2]*in1->m[3][3] + in1->m[1][1]*in1->m[0][3]*in1->m[3][2] + in1->m[3][1]*in1->m[0][2]*in1->m[1][3] - in1->m[3][1]*in1->m[0][3]*in1->m[1][2];
254 temp.m[1][2] = -in1->m[0][0]*in1->m[1][2]*in1->m[3][3] + in1->m[0][0]*in1->m[1][3]*in1->m[3][2] + in1->m[1][0]*in1->m[0][2]*in1->m[3][3] - in1->m[1][0]*in1->m[0][3]*in1->m[3][2] - in1->m[3][0]*in1->m[0][2]*in1->m[1][3] + in1->m[3][0]*in1->m[0][3]*in1->m[1][2];
255 temp.m[2][2] = in1->m[0][0]*in1->m[1][1]*in1->m[3][3] - in1->m[0][0]*in1->m[1][3]*in1->m[3][1] - in1->m[1][0]*in1->m[0][1]*in1->m[3][3] + in1->m[1][0]*in1->m[0][3]*in1->m[3][1] + in1->m[3][0]*in1->m[0][1]*in1->m[1][3] - in1->m[3][0]*in1->m[0][3]*in1->m[1][1];
256 temp.m[3][2] = -in1->m[0][0]*in1->m[1][1]*in1->m[3][2] + in1->m[0][0]*in1->m[1][2]*in1->m[3][1] + in1->m[1][0]*in1->m[0][1]*in1->m[3][2] - in1->m[1][0]*in1->m[0][2]*in1->m[3][1] - in1->m[3][0]*in1->m[0][1]*in1->m[1][2] + in1->m[3][0]*in1->m[0][2]*in1->m[1][1];
257 temp.m[0][3] = -in1->m[0][1]*in1->m[1][2]*in1->m[2][3] + in1->m[0][1]*in1->m[1][3]*in1->m[2][2] + in1->m[1][1]*in1->m[0][2]*in1->m[2][3] - in1->m[1][1]*in1->m[0][3]*in1->m[2][2] - in1->m[2][1]*in1->m[0][2]*in1->m[1][3] + in1->m[2][1]*in1->m[0][3]*in1->m[1][2];
258 temp.m[1][3] = in1->m[0][0]*in1->m[1][2]*in1->m[2][3] - in1->m[0][0]*in1->m[1][3]*in1->m[2][2] - in1->m[1][0]*in1->m[0][2]*in1->m[2][3] + in1->m[1][0]*in1->m[0][3]*in1->m[2][2] + in1->m[2][0]*in1->m[0][2]*in1->m[1][3] - in1->m[2][0]*in1->m[0][3]*in1->m[1][2];
259 temp.m[2][3] = -in1->m[0][0]*in1->m[1][1]*in1->m[2][3] + in1->m[0][0]*in1->m[1][3]*in1->m[2][1] + in1->m[1][0]*in1->m[0][1]*in1->m[2][3] - in1->m[1][0]*in1->m[0][3]*in1->m[2][1] - in1->m[2][0]*in1->m[0][1]*in1->m[1][3] + in1->m[2][0]*in1->m[0][3]*in1->m[1][1];
260 temp.m[3][3] = in1->m[0][0]*in1->m[1][1]*in1->m[2][2] - in1->m[0][0]*in1->m[1][2]*in1->m[2][1] - in1->m[1][0]*in1->m[0][1]*in1->m[2][2] + in1->m[1][0]*in1->m[0][2]*in1->m[2][1] + in1->m[2][0]*in1->m[0][1]*in1->m[1][2] - in1->m[2][0]*in1->m[0][2]*in1->m[1][1];
261#else
262 temp.m[0][0] = in1->m[1][1]*in1->m[2][2]*in1->m[3][3] - in1->m[1][1]*in1->m[3][2]*in1->m[2][3] - in1->m[1][2]*in1->m[2][1]*in1->m[3][3] + in1->m[1][2]*in1->m[3][1]*in1->m[2][3] + in1->m[1][3]*in1->m[2][1]*in1->m[3][2] - in1->m[1][3]*in1->m[3][1]*in1->m[2][2];
263 temp.m[0][1] = -in1->m[0][1]*in1->m[2][2]*in1->m[3][3] + in1->m[0][1]*in1->m[3][2]*in1->m[2][3] + in1->m[0][2]*in1->m[2][1]*in1->m[3][3] - in1->m[0][2]*in1->m[3][1]*in1->m[2][3] - in1->m[0][3]*in1->m[2][1]*in1->m[3][2] + in1->m[0][3]*in1->m[3][1]*in1->m[2][2];
264 temp.m[0][2] = in1->m[0][1]*in1->m[1][2]*in1->m[3][3] - in1->m[0][1]*in1->m[3][2]*in1->m[1][3] - in1->m[0][2]*in1->m[1][1]*in1->m[3][3] + in1->m[0][2]*in1->m[3][1]*in1->m[1][3] + in1->m[0][3]*in1->m[1][1]*in1->m[3][2] - in1->m[0][3]*in1->m[3][1]*in1->m[1][2];
265 temp.m[0][3] = -in1->m[0][1]*in1->m[1][2]*in1->m[2][3] + in1->m[0][1]*in1->m[2][2]*in1->m[1][3] + in1->m[0][2]*in1->m[1][1]*in1->m[2][3] - in1->m[0][2]*in1->m[2][1]*in1->m[1][3] - in1->m[0][3]*in1->m[1][1]*in1->m[2][2] + in1->m[0][3]*in1->m[2][1]*in1->m[1][2];
266 temp.m[1][0] = -in1->m[1][0]*in1->m[2][2]*in1->m[3][3] + in1->m[1][0]*in1->m[3][2]*in1->m[2][3] + in1->m[1][2]*in1->m[2][0]*in1->m[3][3] - in1->m[1][2]*in1->m[3][0]*in1->m[2][3] - in1->m[1][3]*in1->m[2][0]*in1->m[3][2] + in1->m[1][3]*in1->m[3][0]*in1->m[2][2];
267 temp.m[1][1] = in1->m[0][0]*in1->m[2][2]*in1->m[3][3] - in1->m[0][0]*in1->m[3][2]*in1->m[2][3] - in1->m[0][2]*in1->m[2][0]*in1->m[3][3] + in1->m[0][2]*in1->m[3][0]*in1->m[2][3] + in1->m[0][3]*in1->m[2][0]*in1->m[3][2] - in1->m[0][3]*in1->m[3][0]*in1->m[2][2];
268 temp.m[1][2] = -in1->m[0][0]*in1->m[1][2]*in1->m[3][3] + in1->m[0][0]*in1->m[3][2]*in1->m[1][3] + in1->m[0][2]*in1->m[1][0]*in1->m[3][3] - in1->m[0][2]*in1->m[3][0]*in1->m[1][3] - in1->m[0][3]*in1->m[1][0]*in1->m[3][2] + in1->m[0][3]*in1->m[3][0]*in1->m[1][2];
269 temp.m[1][3] = in1->m[0][0]*in1->m[1][2]*in1->m[2][3] - in1->m[0][0]*in1->m[2][2]*in1->m[1][3] - in1->m[0][2]*in1->m[1][0]*in1->m[2][3] + in1->m[0][2]*in1->m[2][0]*in1->m[1][3] + in1->m[0][3]*in1->m[1][0]*in1->m[2][2] - in1->m[0][3]*in1->m[2][0]*in1->m[1][2];
270 temp.m[2][0] = in1->m[1][0]*in1->m[2][1]*in1->m[3][3] - in1->m[1][0]*in1->m[3][1]*in1->m[2][3] - in1->m[1][1]*in1->m[2][0]*in1->m[3][3] + in1->m[1][1]*in1->m[3][0]*in1->m[2][3] + in1->m[1][3]*in1->m[2][0]*in1->m[3][1] - in1->m[1][3]*in1->m[3][0]*in1->m[2][1];
271 temp.m[2][1] = -in1->m[0][0]*in1->m[2][1]*in1->m[3][3] + in1->m[0][0]*in1->m[3][1]*in1->m[2][3] + in1->m[0][1]*in1->m[2][0]*in1->m[3][3] - in1->m[0][1]*in1->m[3][0]*in1->m[2][3] - in1->m[0][3]*in1->m[2][0]*in1->m[3][1] + in1->m[0][3]*in1->m[3][0]*in1->m[2][1];
272 temp.m[2][2] = in1->m[0][0]*in1->m[1][1]*in1->m[3][3] - in1->m[0][0]*in1->m[3][1]*in1->m[1][3] - in1->m[0][1]*in1->m[1][0]*in1->m[3][3] + in1->m[0][1]*in1->m[3][0]*in1->m[1][3] + in1->m[0][3]*in1->m[1][0]*in1->m[3][1] - in1->m[0][3]*in1->m[3][0]*in1->m[1][1];
273 temp.m[2][3] = -in1->m[0][0]*in1->m[1][1]*in1->m[2][3] + in1->m[0][0]*in1->m[2][1]*in1->m[1][3] + in1->m[0][1]*in1->m[1][0]*in1->m[2][3] - in1->m[0][1]*in1->m[2][0]*in1->m[1][3] - in1->m[0][3]*in1->m[1][0]*in1->m[2][1] + in1->m[0][3]*in1->m[2][0]*in1->m[1][1];
274 temp.m[3][0] = -in1->m[1][0]*in1->m[2][1]*in1->m[3][2] + in1->m[1][0]*in1->m[3][1]*in1->m[2][2] + in1->m[1][1]*in1->m[2][0]*in1->m[3][2] - in1->m[1][1]*in1->m[3][0]*in1->m[2][2] - in1->m[1][2]*in1->m[2][0]*in1->m[3][1] + in1->m[1][2]*in1->m[3][0]*in1->m[2][1];
275 temp.m[3][1] = in1->m[0][0]*in1->m[2][1]*in1->m[3][2] - in1->m[0][0]*in1->m[3][1]*in1->m[2][2] - in1->m[0][1]*in1->m[2][0]*in1->m[3][2] + in1->m[0][1]*in1->m[3][0]*in1->m[2][2] + in1->m[0][2]*in1->m[2][0]*in1->m[3][1] - in1->m[0][2]*in1->m[3][0]*in1->m[2][1];
276 temp.m[3][2] = -in1->m[0][0]*in1->m[1][1]*in1->m[3][2] + in1->m[0][0]*in1->m[3][1]*in1->m[1][2] + in1->m[0][1]*in1->m[1][0]*in1->m[3][2] - in1->m[0][1]*in1->m[3][0]*in1->m[1][2] - in1->m[0][2]*in1->m[1][0]*in1->m[3][1] + in1->m[0][2]*in1->m[3][0]*in1->m[1][1];
277 temp.m[3][3] = in1->m[0][0]*in1->m[1][1]*in1->m[2][2] - in1->m[0][0]*in1->m[2][1]*in1->m[1][2] - in1->m[0][1]*in1->m[1][0]*in1->m[2][2] + in1->m[0][1]*in1->m[2][0]*in1->m[1][2] + in1->m[0][2]*in1->m[1][0]*in1->m[2][1] - in1->m[0][2]*in1->m[2][0]*in1->m[1][1];
278#endif
279
280 det = in1->m[0][0]*temp.m[0][0] + in1->m[1][0]*temp.m[0][1] + in1->m[2][0]*temp.m[0][2] + in1->m[3][0]*temp.m[0][3];
281 if (det == 0.0f)
282 return 0;
283
284 det = 1.0f / det;
285
286 for (i = 0;i < 4;i++)
287 for (j = 0;j < 4;j++)
288 out->m[i][j] = temp.m[i][j] * det;
289
290 return 1;
291}
292#else
293int Matrix4x4_Invert_Full (matrix4x4_t* out, const matrix4x4_t* in1)
294{
295 double* temp;
296 double* r[4];
297 double rtemp[4][8];
298 double m[4];
299 double s;
300
301 r[0] = rtemp[0];
302 r[1] = rtemp[1];
303 r[2] = rtemp[2];
304 r[3] = rtemp[3];
305
306#ifdef MATRIX4x4_OPENGLORIENTATION
307 r[0][0] = in1->m[0][0]; r[0][1] = in1->m[1][0]; r[0][2] = in1->m[2][0]; r[0][3] = in1->m[3][0];
308 r[0][4] = 1.0; r[0][5] = r[0][6] = r[0][7] = 0.0;
309
310 r[1][0] = in1->m[0][1]; r[1][1] = in1->m[1][1]; r[1][2] = in1->m[2][1]; r[1][3] = in1->m[3][1];
311 r[1][5] = 1.0; r[1][4] = r[1][6] = r[1][7] = 0.0;
312
313 r[2][0] = in1->m[0][2]; r[2][1] = in1->m[1][2]; r[2][2] = in1->m[2][2]; r[2][3] = in1->m[3][2];
314 r[2][6] = 1.0; r[2][4] = r[2][5] = r[2][7] = 0.0;
315
316 r[3][0] = in1->m[0][3]; r[3][1] = in1->m[1][3]; r[3][2] = in1->m[2][3]; r[3][3] = in1->m[3][3];
317 r[3][7] = 1.0; r[3][4] = r[3][5] = r[3][6] = 0.0;
318#else
319 r[0][0] = in1->m[0][0]; r[0][1] = in1->m[0][1]; r[0][2] = in1->m[0][2]; r[0][3] = in1->m[0][3];
320 r[0][4] = 1.0; r[0][5] = r[0][6] = r[0][7] = 0.0;
321
322 r[1][0] = in1->m[1][0]; r[1][1] = in1->m[1][1]; r[1][2] = in1->m[1][2]; r[1][3] = in1->m[1][3];
323 r[1][5] = 1.0; r[1][4] = r[1][6] = r[1][7] = 0.0;
324
325 r[2][0] = in1->m[2][0]; r[2][1] = in1->m[2][1]; r[2][2] = in1->m[2][2]; r[2][3] = in1->m[2][3];
326 r[2][6] = 1.0; r[2][4] = r[2][5] = r[2][7] = 0.0;
327
328 r[3][0] = in1->m[3][0]; r[3][1] = in1->m[3][1]; r[3][2] = in1->m[3][2]; r[3][3] = in1->m[3][3];
329 r[3][7] = 1.0; r[3][4] = r[3][5] = r[3][6] = 0.0;
330#endif
331
332 if (fabs (r[3][0]) > fabs (r[2][0])) {temp = r[3]; r[3] = r[2]; r[2] = temp;}
333 if (fabs (r[2][0]) > fabs (r[1][0])) {temp = r[2]; r[2] = r[1]; r[1] = temp;}
334 if (fabs (r[1][0]) > fabs (r[0][0])) {temp = r[1]; r[1] = r[0]; r[0] = temp;}
335
336 if (r[0][0])
337 {
338 m[1] = r[1][0] / r[0][0];
339 m[2] = r[2][0] / r[0][0];
340 m[3] = r[3][0] / r[0][0];
341
342 s = r[0][1]; r[1][1] -= m[1] * s; r[2][1] -= m[2] * s; r[3][1] -= m[3] * s;
343 s = r[0][2]; r[1][2] -= m[1] * s; r[2][2] -= m[2] * s; r[3][2] -= m[3] * s;
344 s = r[0][3]; r[1][3] -= m[1] * s; r[2][3] -= m[2] * s; r[3][3] -= m[3] * s;
345
346 s = r[0][4]; if (s) {r[1][4] -= m[1] * s; r[2][4] -= m[2] * s; r[3][4] -= m[3] * s;}
347 s = r[0][5]; if (s) {r[1][5] -= m[1] * s; r[2][5] -= m[2] * s; r[3][5] -= m[3] * s;}
348 s = r[0][6]; if (s) {r[1][6] -= m[1] * s; r[2][6] -= m[2] * s; r[3][6] -= m[3] * s;}
349 s = r[0][7]; if (s) {r[1][7] -= m[1] * s; r[2][7] -= m[2] * s; r[3][7] -= m[3] * s;}
350
351 if (fabs (r[3][1]) > fabs (r[2][1])) {temp = r[3]; r[3] = r[2]; r[2] = temp;}
352 if (fabs (r[2][1]) > fabs (r[1][1])) {temp = r[2]; r[2] = r[1]; r[1] = temp;}
353
354 if (r[1][1])
355 {
356 m[2] = r[2][1] / r[1][1];
357 m[3] = r[3][1] / r[1][1];
358 r[2][2] -= m[2] * r[1][2];
359 r[3][2] -= m[3] * r[1][2];
360 r[2][3] -= m[2] * r[1][3];
361 r[3][3] -= m[3] * r[1][3];
362
363 s = r[1][4]; if (s) {r[2][4] -= m[2] * s; r[3][4] -= m[3] * s;}
364 s = r[1][5]; if (s) {r[2][5] -= m[2] * s; r[3][5] -= m[3] * s;}
365 s = r[1][6]; if (s) {r[2][6] -= m[2] * s; r[3][6] -= m[3] * s;}
366 s = r[1][7]; if (s) {r[2][7] -= m[2] * s; r[3][7] -= m[3] * s;}
367
368 if (fabs (r[3][2]) > fabs (r[2][2])) {temp = r[3]; r[3] = r[2]; r[2] = temp;}
369
370 if (r[2][2])
371 {
372 m[3] = r[3][2] / r[2][2];
373 r[3][3] -= m[3] * r[2][3];
374 r[3][4] -= m[3] * r[2][4];
375 r[3][5] -= m[3] * r[2][5];
376 r[3][6] -= m[3] * r[2][6];
377 r[3][7] -= m[3] * r[2][7];
378
379 if (r[3][3])
380 {
381 s = 1.0 / r[3][3];
382 r[3][4] *= s;
383 r[3][5] *= s;
384 r[3][6] *= s;
385 r[3][7] *= s;
386
387 m[2] = r[2][3];
388 s = 1.0 / r[2][2];
389 r[2][4] = s * (r[2][4] - r[3][4] * m[2]);
390 r[2][5] = s * (r[2][5] - r[3][5] * m[2]);
391 r[2][6] = s * (r[2][6] - r[3][6] * m[2]);
392 r[2][7] = s * (r[2][7] - r[3][7] * m[2]);
393
394 m[1] = r[1][3];
395 r[1][4] -= r[3][4] * m[1], r[1][5] -= r[3][5] * m[1];
396 r[1][6] -= r[3][6] * m[1], r[1][7] -= r[3][7] * m[1];
397
398 m[0] = r[0][3];
399 r[0][4] -= r[3][4] * m[0], r[0][5] -= r[3][5] * m[0];
400 r[0][6] -= r[3][6] * m[0], r[0][7] -= r[3][7] * m[0];
401
402 m[1] = r[1][2];
403 s = 1.0 / r[1][1];
404 r[1][4] = s * (r[1][4] - r[2][4] * m[1]), r[1][5] = s * (r[1][5] - r[2][5] * m[1]);
405 r[1][6] = s * (r[1][6] - r[2][6] * m[1]), r[1][7] = s * (r[1][7] - r[2][7] * m[1]);
406
407 m[0] = r[0][2];
408 r[0][4] -= r[2][4] * m[0], r[0][5] -= r[2][5] * m[0];
409 r[0][6] -= r[2][6] * m[0], r[0][7] -= r[2][7] * m[0];
410
411 m[0] = r[0][1];
412 s = 1.0 / r[0][0];
413 r[0][4] = s * (r[0][4] - r[1][4] * m[0]), r[0][5] = s * (r[0][5] - r[1][5] * m[0]);
414 r[0][6] = s * (r[0][6] - r[1][6] * m[0]), r[0][7] = s * (r[0][7] - r[1][7] * m[0]);
415
416#ifdef MATRIX4x4_OPENGLORIENTATION
417 out->m[0][0] = r[0][4];
418 out->m[0][1] = r[1][4];
419 out->m[0][2] = r[2][4];
420 out->m[0][3] = r[3][4];
421 out->m[1][0] = r[0][5];
422 out->m[1][1] = r[1][5];
423 out->m[1][2] = r[2][5];
424 out->m[1][3] = r[3][5];
425 out->m[2][0] = r[0][6];
426 out->m[2][1] = r[1][6];
427 out->m[2][2] = r[2][6];
428 out->m[2][3] = r[3][6];
429 out->m[3][0] = r[0][7];
430 out->m[3][1] = r[1][7];
431 out->m[3][2] = r[2][7];
432 out->m[3][3] = r[3][7];
433#else
434 out->m[0][0] = r[0][4];
435 out->m[0][1] = r[0][5];
436 out->m[0][2] = r[0][6];
437 out->m[0][3] = r[0][7];
438 out->m[1][0] = r[1][4];
439 out->m[1][1] = r[1][5];
440 out->m[1][2] = r[1][6];
441 out->m[1][3] = r[1][7];
442 out->m[2][0] = r[2][4];
443 out->m[2][1] = r[2][5];
444 out->m[2][2] = r[2][6];
445 out->m[2][3] = r[2][7];
446 out->m[3][0] = r[3][4];
447 out->m[3][1] = r[3][5];
448 out->m[3][2] = r[3][6];
449 out->m[3][3] = r[3][7];
450#endif
451
452 return 1;
453 }
454 }
455 }
456 }
457
458 return 0;
459}
460#endif
461
463{
464 /* we only support uniform scaling, so assume the first row is enough
465 * (note the lack of sqrt here, because we're trying to undo the scaling,
466 * this means multiplying by the inverse scale twice - squaring it, which
467 * makes the sqrt a waste of time) */
468#if 1
469 double scale = 1.0 / (in1->m[0][0] * in1->m[0][0] + in1->m[0][1] * in1->m[0][1] + in1->m[0][2] * in1->m[0][2]);
470#else
471 double scale = 3.0 / sqrt
472 (in1->m[0][0] * in1->m[0][0] + in1->m[0][1] * in1->m[0][1] + in1->m[0][2] * in1->m[0][2]
473 + in1->m[1][0] * in1->m[1][0] + in1->m[1][1] * in1->m[1][1] + in1->m[1][2] * in1->m[1][2]
474 + in1->m[2][0] * in1->m[2][0] + in1->m[2][1] * in1->m[2][1] + in1->m[2][2] * in1->m[2][2]);
475 scale *= scale;
476#endif
477
478 /* invert the rotation by transposing and multiplying by the squared
479 * recipricol of the input matrix scale as described above */
480 out->m[0][0] = in1->m[0][0] * scale;
481 out->m[0][1] = in1->m[1][0] * scale;
482 out->m[0][2] = in1->m[2][0] * scale;
483 out->m[1][0] = in1->m[0][1] * scale;
484 out->m[1][1] = in1->m[1][1] * scale;
485 out->m[1][2] = in1->m[2][1] * scale;
486 out->m[2][0] = in1->m[0][2] * scale;
487 out->m[2][1] = in1->m[1][2] * scale;
488 out->m[2][2] = in1->m[2][2] * scale;
489
490#ifdef MATRIX4x4_OPENGLORIENTATION
491 /* invert the translate */
492 out->m[3][0] = -(in1->m[3][0] * out->m[0][0] + in1->m[3][1] * out->m[1][0] + in1->m[3][2] * out->m[2][0]);
493 out->m[3][1] = -(in1->m[3][0] * out->m[0][1] + in1->m[3][1] * out->m[1][1] + in1->m[3][2] * out->m[2][1]);
494 out->m[3][2] = -(in1->m[3][0] * out->m[0][2] + in1->m[3][1] * out->m[1][2] + in1->m[3][2] * out->m[2][2]);
495
496 /* don't know if there's anything worth doing here */
497 out->m[0][3] = 0;
498 out->m[1][3] = 0;
499 out->m[2][3] = 0;
500 out->m[3][3] = 1;
501#else
502 /* invert the translate */
503 out->m[0][3] = -(in1->m[0][3] * out->m[0][0] + in1->m[1][3] * out->m[0][1] + in1->m[2][3] * out->m[0][2]);
504 out->m[1][3] = -(in1->m[0][3] * out->m[1][0] + in1->m[1][3] * out->m[1][1] + in1->m[2][3] * out->m[1][2]);
505 out->m[2][3] = -(in1->m[0][3] * out->m[2][0] + in1->m[1][3] * out->m[2][1] + in1->m[2][3] * out->m[2][2]);
506
507 /* don't know if there's anything worth doing here */
508 out->m[3][0] = 0;
509 out->m[3][1] = 0;
510 out->m[3][2] = 0;
511 out->m[3][3] = 1;
512#endif
513}
514
515void Matrix4x4_Interpolate (matrix4x4_t* out, matrix4x4_t* in1, matrix4x4_t* in2, double frac)
516{
517 for (int i = 0; i < 4; i++)
518 for (int j = 0; j < 4; j++)
519 out->m[i][j] = in1->m[i][j] + frac * (in2->m[i][j] - in1->m[i][j]);
520}
521
523{
524 for (int i = 0; i < 4; i++)
525 for (int j = 0; j < 4; j++)
526 out->m[i][j] = 0;
527}
528
529void Matrix4x4_Accumulate (matrix4x4_t* out, matrix4x4_t* in, double weight)
530{
531 for (int i = 0; i < 4; i++)
532 for (int j = 0; j < 4; j++)
533 out->m[i][j] += in->m[i][j] * weight;
534}
535
537{
538 /* scale rotation matrix vectors to a length of 1
539 * note: this is only designed to undo uniform scaling */
540 double scale = 1.0 / sqrt(in1->m[0][0] * in1->m[0][0] + in1->m[0][1] * in1->m[0][1] + in1->m[0][2] * in1->m[0][2]);
541 *out = *in1;
542 Matrix4x4_Scale(out, scale, 1);
543}
544
546{
547 /* scale each rotation matrix vector to a length of 1
548 * intended for use after Matrix4x4_Interpolate or Matrix4x4_Accumulate */
549 *out = *in1;
550 for (int i = 0; i < 3; i++) {
551 double scale;
552#ifdef MATRIX4x4_OPENGLORIENTATION
553 scale = sqrt(in1->m[i][0] * in1->m[i][0] + in1->m[i][1] * in1->m[i][1] + in1->m[i][2] * in1->m[i][2]);
554 if (scale)
555 scale = 1.0 / scale;
556 out->m[i][0] *= scale;
557 out->m[i][1] *= scale;
558 out->m[i][2] *= scale;
559#else
560 scale = sqrt(in1->m[0][i] * in1->m[0][i] + in1->m[1][i] * in1->m[1][i] + in1->m[2][i] * in1->m[2][i]);
561 if (scale)
562 scale = 1.0 / scale;
563 out->m[0][i] *= scale;
564 out->m[1][i] *= scale;
565 out->m[2][i] *= scale;
566#endif
567 }
568}
569
570void Matrix4x4_Reflect (matrix4x4_t* out, double normalx, double normaly, double normalz, double dist, double axisscale)
571{
572 double p[4], p2[4];
573 p[0] = normalx;
574 p[1] = normaly;
575 p[2] = normalz;
576 p[3] = -dist;
577 p2[0] = p[0] * axisscale;
578 p2[1] = p[1] * axisscale;
579 p2[2] = p[2] * axisscale;
580 p2[3] = 0;
581 for (int i = 0; i < 4; i++) {
582 double d;
583#ifdef MATRIX4x4_OPENGLORIENTATION
584 d = out->m[i][0] * p[0] + out->m[i][1] * p[1] + out->m[i][2] * p[2] + out->m[i][3] * p[3];
585 out->m[i][0] += p2[0] * d;
586 out->m[i][1] += p2[1] * d;
587 out->m[i][2] += p2[2] * d;
588#else
589 d = out->m[0][i] * p[0] + out->m[1][i] * p[1] + out->m[2][i] * p[2] + out->m[3][i] * p[3];
590 out->m[0][i] += p2[0] * d;
591 out->m[1][i] += p2[1] * d;
592 out->m[2][i] += p2[2] * d;
593#endif
594 }
595}
596
598{
599 out->m[0][0] = 1.0f;
600 out->m[0][1] = 0.0f;
601 out->m[0][2] = 0.0f;
602 out->m[0][3] = 0.0f;
603 out->m[1][0] = 0.0f;
604 out->m[1][1] = 1.0f;
605 out->m[1][2] = 0.0f;
606 out->m[1][3] = 0.0f;
607 out->m[2][0] = 0.0f;
608 out->m[2][1] = 0.0f;
609 out->m[2][2] = 1.0f;
610 out->m[2][3] = 0.0f;
611 out->m[3][0] = 0.0f;
612 out->m[3][1] = 0.0f;
613 out->m[3][2] = 0.0f;
614 out->m[3][3] = 1.0f;
615}
616
617void Matrix4x4_CreateTranslate (matrix4x4_t* out, double x, double y, double z)
618{
619#ifdef MATRIX4x4_OPENGLORIENTATION
620 out->m[0][0]=1.0f;
621 out->m[1][0]=0.0f;
622 out->m[2][0]=0.0f;
623 out->m[3][0]=x;
624 out->m[0][1]=0.0f;
625 out->m[1][1]=1.0f;
626 out->m[2][1]=0.0f;
627 out->m[3][1]=y;
628 out->m[0][2]=0.0f;
629 out->m[1][2]=0.0f;
630 out->m[2][2]=1.0f;
631 out->m[3][2]=z;
632 out->m[0][3]=0.0f;
633 out->m[1][3]=0.0f;
634 out->m[2][3]=0.0f;
635 out->m[3][3]=1.0f;
636#else
637 out->m[0][0] = 1.0f;
638 out->m[0][1] = 0.0f;
639 out->m[0][2] = 0.0f;
640 out->m[0][3] = x;
641 out->m[1][0] = 0.0f;
642 out->m[1][1] = 1.0f;
643 out->m[1][2] = 0.0f;
644 out->m[1][3] = y;
645 out->m[2][0] = 0.0f;
646 out->m[2][1] = 0.0f;
647 out->m[2][2] = 1.0f;
648 out->m[2][3] = z;
649 out->m[3][0] = 0.0f;
650 out->m[3][1] = 0.0f;
651 out->m[3][2] = 0.0f;
652 out->m[3][3] = 1.0f;
653#endif
654}
655
656void Matrix4x4_CreateRotate (matrix4x4_t* out, double angle, double x, double y, double z)
657{
658 double len, c, s;
659
660 len = x * x + y * y + z * z;
661 if (len != 0.0f)
662 len = 1.0f / sqrt(len);
663 x *= len;
664 y *= len;
665 z *= len;
666
667 angle *= -torad;
668 c = cos(angle);
669 s = sin(angle);
670
671#ifdef MATRIX4x4_OPENGLORIENTATION
672 out->m[0][0]=x * x + c * (1 - x * x);
673 out->m[1][0]=x * y * (1 - c) + z * s;
674 out->m[2][0]=z * x * (1 - c) - y * s;
675 out->m[3][0]=0.0f;
676 out->m[0][1]=x * y * (1 - c) - z * s;
677 out->m[1][1]=y * y + c * (1 - y * y);
678 out->m[2][1]=y * z * (1 - c) + x * s;
679 out->m[3][1]=0.0f;
680 out->m[0][2]=z * x * (1 - c) + y * s;
681 out->m[1][2]=y * z * (1 - c) - x * s;
682 out->m[2][2]=z * z + c * (1 - z * z);
683 out->m[3][2]=0.0f;
684 out->m[0][3]=0.0f;
685 out->m[1][3]=0.0f;
686 out->m[2][3]=0.0f;
687 out->m[3][3]=1.0f;
688#else
689 out->m[0][0] = x * x + c * (1 - x * x);
690 out->m[0][1] = x * y * (1 - c) + z * s;
691 out->m[0][2] = z * x * (1 - c) - y * s;
692 out->m[0][3] = 0.0f;
693 out->m[1][0] = x * y * (1 - c) - z * s;
694 out->m[1][1] = y * y + c * (1 - y * y);
695 out->m[1][2] = y * z * (1 - c) + x * s;
696 out->m[1][3] = 0.0f;
697 out->m[2][0] = z * x * (1 - c) + y * s;
698 out->m[2][1] = y * z * (1 - c) - x * s;
699 out->m[2][2] = z * z + c * (1 - z * z);
700 out->m[2][3] = 0.0f;
701 out->m[3][0] = 0.0f;
702 out->m[3][1] = 0.0f;
703 out->m[3][2] = 0.0f;
704 out->m[3][3] = 1.0f;
705#endif
706}
707
709{
710 out->m[0][0] = x;
711 out->m[0][1] = 0.0f;
712 out->m[0][2] = 0.0f;
713 out->m[0][3] = 0.0f;
714 out->m[1][0] = 0.0f;
715 out->m[1][1] = x;
716 out->m[1][2] = 0.0f;
717 out->m[1][3] = 0.0f;
718 out->m[2][0] = 0.0f;
719 out->m[2][1] = 0.0f;
720 out->m[2][2] = x;
721 out->m[2][3] = 0.0f;
722 out->m[3][0] = 0.0f;
723 out->m[3][1] = 0.0f;
724 out->m[3][2] = 0.0f;
725 out->m[3][3] = 1.0f;
726}
727
728void Matrix4x4_CreateScale3 (matrix4x4_t* out, double x, double y, double z)
729{
730 out->m[0][0] = x;
731 out->m[0][1] = 0.0f;
732 out->m[0][2] = 0.0f;
733 out->m[0][3] = 0.0f;
734 out->m[1][0] = 0.0f;
735 out->m[1][1] = y;
736 out->m[1][2] = 0.0f;
737 out->m[1][3] = 0.0f;
738 out->m[2][0] = 0.0f;
739 out->m[2][1] = 0.0f;
740 out->m[2][2] = z;
741 out->m[2][3] = 0.0f;
742 out->m[3][0] = 0.0f;
743 out->m[3][1] = 0.0f;
744 out->m[3][2] = 0.0f;
745 out->m[3][3] = 1.0f;
746}
747
748void Matrix4x4_CreateFromQuakeEntity (matrix4x4_t* out, double x, double y, double z, double pitch, double yaw,
749 double roll, double scale)
750{
751
752 if (roll) {
753 double sr, cr, sp, cp;
754 double angle = yaw * torad;
755 double sy = sin(angle);
756 double cy = cos(angle);
757 angle = pitch * torad;
758 sp = sin(angle);
759 cp = cos(angle);
760 angle = roll * torad;
761 sr = sin(angle);
762 cr = cos(angle);
763#ifdef MATRIX4x4_OPENGLORIENTATION
764 out->m[0][0] = (cp*cy) * scale;
765 out->m[1][0] = (sr*sp*cy+cr*-sy) * scale;
766 out->m[2][0] = (cr*sp*cy+-sr*-sy) * scale;
767 out->m[3][0] = x;
768 out->m[0][1] = (cp*sy) * scale;
769 out->m[1][1] = (sr*sp*sy+cr*cy) * scale;
770 out->m[2][1] = (cr*sp*sy+-sr*cy) * scale;
771 out->m[3][1] = y;
772 out->m[0][2] = (-sp) * scale;
773 out->m[1][2] = (sr*cp) * scale;
774 out->m[2][2] = (cr*cp) * scale;
775 out->m[3][2] = z;
776 out->m[0][3] = 0;
777 out->m[1][3] = 0;
778 out->m[2][3] = 0;
779 out->m[3][3] = 1;
780#else
781 out->m[0][0] = (cp * cy) * scale;
782 out->m[0][1] = (sr * sp * cy + cr * -sy) * scale;
783 out->m[0][2] = (cr * sp * cy + -sr * -sy) * scale;
784 out->m[0][3] = x;
785 out->m[1][0] = (cp * sy) * scale;
786 out->m[1][1] = (sr * sp * sy + cr * cy) * scale;
787 out->m[1][2] = (cr * sp * sy + -sr * cy) * scale;
788 out->m[1][3] = y;
789 out->m[2][0] = (-sp) * scale;
790 out->m[2][1] = (sr * cp) * scale;
791 out->m[2][2] = (cr * cp) * scale;
792 out->m[2][3] = z;
793 out->m[3][0] = 0;
794 out->m[3][1] = 0;
795 out->m[3][2] = 0;
796 out->m[3][3] = 1;
797#endif
798 } else if (pitch) {
799 double sp, cp;
800 double angle = yaw * torad;
801 double sy = sin(angle);
802 double cy = cos(angle);
803 angle = pitch * torad;
804 sp = sin(angle);
805 cp = cos(angle);
806#ifdef MATRIX4x4_OPENGLORIENTATION
807 out->m[0][0] = (cp*cy) * scale;
808 out->m[1][0] = (-sy) * scale;
809 out->m[2][0] = (sp*cy) * scale;
810 out->m[3][0] = x;
811 out->m[0][1] = (cp*sy) * scale;
812 out->m[1][1] = (cy) * scale;
813 out->m[2][1] = (sp*sy) * scale;
814 out->m[3][1] = y;
815 out->m[0][2] = (-sp) * scale;
816 out->m[1][2] = 0;
817 out->m[2][2] = (cp) * scale;
818 out->m[3][2] = z;
819 out->m[0][3] = 0;
820 out->m[1][3] = 0;
821 out->m[2][3] = 0;
822 out->m[3][3] = 1;
823#else
824 out->m[0][0] = (cp * cy) * scale;
825 out->m[0][1] = (-sy) * scale;
826 out->m[0][2] = (sp * cy) * scale;
827 out->m[0][3] = x;
828 out->m[1][0] = (cp * sy) * scale;
829 out->m[1][1] = (cy) * scale;
830 out->m[1][2] = (sp * sy) * scale;
831 out->m[1][3] = y;
832 out->m[2][0] = (-sp) * scale;
833 out->m[2][1] = 0;
834 out->m[2][2] = (cp) * scale;
835 out->m[2][3] = z;
836 out->m[3][0] = 0;
837 out->m[3][1] = 0;
838 out->m[3][2] = 0;
839 out->m[3][3] = 1;
840#endif
841 } else if (yaw) {
842 const double angle = yaw * torad;
843 const double sy = sin(angle);
844 const double cy = cos(angle);
845#ifdef MATRIX4x4_OPENGLORIENTATION
846 out->m[0][0] = (cy) * scale;
847 out->m[1][0] = (-sy) * scale;
848 out->m[2][0] = 0;
849 out->m[3][0] = x;
850 out->m[0][1] = (sy) * scale;
851 out->m[1][1] = (cy) * scale;
852 out->m[2][1] = 0;
853 out->m[3][1] = y;
854 out->m[0][2] = 0;
855 out->m[1][2] = 0;
856 out->m[2][2] = scale;
857 out->m[3][2] = z;
858 out->m[0][3] = 0;
859 out->m[1][3] = 0;
860 out->m[2][3] = 0;
861 out->m[3][3] = 1;
862#else
863 out->m[0][0] = (cy) * scale;
864 out->m[0][1] = (-sy) * scale;
865 out->m[0][2] = 0;
866 out->m[0][3] = x;
867 out->m[1][0] = (sy) * scale;
868 out->m[1][1] = (cy) * scale;
869 out->m[1][2] = 0;
870 out->m[1][3] = y;
871 out->m[2][0] = 0;
872 out->m[2][1] = 0;
873 out->m[2][2] = scale;
874 out->m[2][3] = z;
875 out->m[3][0] = 0;
876 out->m[3][1] = 0;
877 out->m[3][2] = 0;
878 out->m[3][3] = 1;
879#endif
880 } else {
881#ifdef MATRIX4x4_OPENGLORIENTATION
882 out->m[0][0] = scale;
883 out->m[1][0] = 0;
884 out->m[2][0] = 0;
885 out->m[3][0] = x;
886 out->m[0][1] = 0;
887 out->m[1][1] = scale;
888 out->m[2][1] = 0;
889 out->m[3][1] = y;
890 out->m[0][2] = 0;
891 out->m[1][2] = 0;
892 out->m[2][2] = scale;
893 out->m[3][2] = z;
894 out->m[0][3] = 0;
895 out->m[1][3] = 0;
896 out->m[2][3] = 0;
897 out->m[3][3] = 1;
898#else
899 out->m[0][0] = scale;
900 out->m[0][1] = 0;
901 out->m[0][2] = 0;
902 out->m[0][3] = x;
903 out->m[1][0] = 0;
904 out->m[1][1] = scale;
905 out->m[1][2] = 0;
906 out->m[1][3] = y;
907 out->m[2][0] = 0;
908 out->m[2][1] = 0;
909 out->m[2][2] = scale;
910 out->m[2][3] = z;
911 out->m[3][0] = 0;
912 out->m[3][1] = 0;
913 out->m[3][2] = 0;
914 out->m[3][3] = 1;
915#endif
916 }
917}
918
919void Matrix4x4_ToVectors (const matrix4x4_t* in, float vx[3], float vy[3], float vz[3], float t[3])
920{
921#ifdef MATRIX4x4_OPENGLORIENTATION
922 vx[0] = in->m[0][0];
923 vx[1] = in->m[0][1];
924 vx[2] = in->m[0][2];
925 vy[0] = in->m[1][0];
926 vy[1] = in->m[1][1];
927 vy[2] = in->m[1][2];
928 vz[0] = in->m[2][0];
929 vz[1] = in->m[2][1];
930 vz[2] = in->m[2][2];
931 t [0] = in->m[3][0];
932 t [1] = in->m[3][1];
933 t [2] = in->m[3][2];
934#else
935 vx[0] = in->m[0][0];
936 vx[1] = in->m[1][0];
937 vx[2] = in->m[2][0];
938 vy[0] = in->m[0][1];
939 vy[1] = in->m[1][1];
940 vy[2] = in->m[2][1];
941 vz[0] = in->m[0][2];
942 vz[1] = in->m[1][2];
943 vz[2] = in->m[2][2];
944 t[0] = in->m[0][3];
945 t[1] = in->m[1][3];
946 t[2] = in->m[2][3];
947#endif
948}
949
950void Matrix4x4_FromVectors (matrix4x4_t* out, const float vx[3], const float vy[3], const float vz[3], const float t[3])
951{
952#ifdef MATRIX4x4_OPENGLORIENTATION
953 out->m[0][0] = vx[0];
954 out->m[1][0] = vy[0];
955 out->m[2][0] = vz[0];
956 out->m[3][0] = t[0];
957 out->m[0][1] = vx[1];
958 out->m[1][1] = vy[1];
959 out->m[2][1] = vz[1];
960 out->m[3][1] = t[1];
961 out->m[0][2] = vx[2];
962 out->m[1][2] = vy[2];
963 out->m[2][2] = vz[2];
964 out->m[3][2] = t[2];
965 out->m[0][3] = 0.0f;
966 out->m[1][3] = 0.0f;
967 out->m[2][3] = 0.0f;
968 out->m[3][3] = 1.0f;
969#else
970 out->m[0][0] = vx[0];
971 out->m[0][1] = vy[0];
972 out->m[0][2] = vz[0];
973 out->m[0][3] = t[0];
974 out->m[1][0] = vx[1];
975 out->m[1][1] = vy[1];
976 out->m[1][2] = vz[1];
977 out->m[1][3] = t[1];
978 out->m[2][0] = vx[2];
979 out->m[2][1] = vy[2];
980 out->m[2][2] = vz[2];
981 out->m[2][3] = t[2];
982 out->m[3][0] = 0.0f;
983 out->m[3][1] = 0.0f;
984 out->m[3][2] = 0.0f;
985 out->m[3][3] = 1.0f;
986#endif
987}
988
989void Matrix4x4_ToArrayDoubleGL (const matrix4x4_t* in, double out[16])
990{
991#ifdef MATRIX4x4_OPENGLORIENTATION
992 out[ 0] = in->m[0][0];
993 out[ 1] = in->m[0][1];
994 out[ 2] = in->m[0][2];
995 out[ 3] = in->m[0][3];
996 out[ 4] = in->m[1][0];
997 out[ 5] = in->m[1][1];
998 out[ 6] = in->m[1][2];
999 out[ 7] = in->m[1][3];
1000 out[ 8] = in->m[2][0];
1001 out[ 9] = in->m[2][1];
1002 out[10] = in->m[2][2];
1003 out[11] = in->m[2][3];
1004 out[12] = in->m[3][0];
1005 out[13] = in->m[3][1];
1006 out[14] = in->m[3][2];
1007 out[15] = in->m[3][3];
1008#else
1009 out[0] = in->m[0][0];
1010 out[1] = in->m[1][0];
1011 out[2] = in->m[2][0];
1012 out[3] = in->m[3][0];
1013 out[4] = in->m[0][1];
1014 out[5] = in->m[1][1];
1015 out[6] = in->m[2][1];
1016 out[7] = in->m[3][1];
1017 out[8] = in->m[0][2];
1018 out[9] = in->m[1][2];
1019 out[10] = in->m[2][2];
1020 out[11] = in->m[3][2];
1021 out[12] = in->m[0][3];
1022 out[13] = in->m[1][3];
1023 out[14] = in->m[2][3];
1024 out[15] = in->m[3][3];
1025#endif
1026}
1027
1028void Matrix4x4_FromArrayDoubleGL (matrix4x4_t* out, const double in[16])
1029{
1030#ifdef MATRIX4x4_OPENGLORIENTATION
1031 out->m[0][0] = in[0];
1032 out->m[0][1] = in[1];
1033 out->m[0][2] = in[2];
1034 out->m[0][3] = in[3];
1035 out->m[1][0] = in[4];
1036 out->m[1][1] = in[5];
1037 out->m[1][2] = in[6];
1038 out->m[1][3] = in[7];
1039 out->m[2][0] = in[8];
1040 out->m[2][1] = in[9];
1041 out->m[2][2] = in[10];
1042 out->m[2][3] = in[11];
1043 out->m[3][0] = in[12];
1044 out->m[3][1] = in[13];
1045 out->m[3][2] = in[14];
1046 out->m[3][3] = in[15];
1047#else
1048 out->m[0][0] = in[0];
1049 out->m[1][0] = in[1];
1050 out->m[2][0] = in[2];
1051 out->m[3][0] = in[3];
1052 out->m[0][1] = in[4];
1053 out->m[1][1] = in[5];
1054 out->m[2][1] = in[6];
1055 out->m[3][1] = in[7];
1056 out->m[0][2] = in[8];
1057 out->m[1][2] = in[9];
1058 out->m[2][2] = in[10];
1059 out->m[3][2] = in[11];
1060 out->m[0][3] = in[12];
1061 out->m[1][3] = in[13];
1062 out->m[2][3] = in[14];
1063 out->m[3][3] = in[15];
1064#endif
1065}
1066
1067void Matrix4x4_ToArrayDoubleD3D (const matrix4x4_t* in, double out[16])
1068{
1069#ifdef MATRIX4x4_OPENGLORIENTATION
1070 out[ 0] = in->m[0][0];
1071 out[ 1] = in->m[1][0];
1072 out[ 2] = in->m[2][0];
1073 out[ 3] = in->m[3][0];
1074 out[ 4] = in->m[0][1];
1075 out[ 5] = in->m[1][1];
1076 out[ 6] = in->m[2][1];
1077 out[ 7] = in->m[3][1];
1078 out[ 8] = in->m[0][2];
1079 out[ 9] = in->m[1][2];
1080 out[10] = in->m[2][2];
1081 out[11] = in->m[3][2];
1082 out[12] = in->m[0][3];
1083 out[13] = in->m[1][3];
1084 out[14] = in->m[2][3];
1085 out[15] = in->m[3][3];
1086#else
1087 out[0] = in->m[0][0];
1088 out[1] = in->m[0][1];
1089 out[2] = in->m[0][2];
1090 out[3] = in->m[0][3];
1091 out[4] = in->m[1][0];
1092 out[5] = in->m[1][1];
1093 out[6] = in->m[1][2];
1094 out[7] = in->m[1][3];
1095 out[8] = in->m[2][0];
1096 out[9] = in->m[2][1];
1097 out[10] = in->m[2][2];
1098 out[11] = in->m[2][3];
1099 out[12] = in->m[3][0];
1100 out[13] = in->m[3][1];
1101 out[14] = in->m[3][2];
1102 out[15] = in->m[3][3];
1103#endif
1104}
1105
1106void Matrix4x4_FromArrayDoubleD3D (matrix4x4_t* out, const double in[16])
1107{
1108#ifdef MATRIX4x4_OPENGLORIENTATION
1109 out->m[0][0] = in[0];
1110 out->m[1][0] = in[1];
1111 out->m[2][0] = in[2];
1112 out->m[3][0] = in[3];
1113 out->m[0][1] = in[4];
1114 out->m[1][1] = in[5];
1115 out->m[2][1] = in[6];
1116 out->m[3][1] = in[7];
1117 out->m[0][2] = in[8];
1118 out->m[1][2] = in[9];
1119 out->m[2][2] = in[10];
1120 out->m[3][2] = in[11];
1121 out->m[0][3] = in[12];
1122 out->m[1][3] = in[13];
1123 out->m[2][3] = in[14];
1124 out->m[3][3] = in[15];
1125#else
1126 out->m[0][0] = in[0];
1127 out->m[0][1] = in[1];
1128 out->m[0][2] = in[2];
1129 out->m[0][3] = in[3];
1130 out->m[1][0] = in[4];
1131 out->m[1][1] = in[5];
1132 out->m[1][2] = in[6];
1133 out->m[1][3] = in[7];
1134 out->m[2][0] = in[8];
1135 out->m[2][1] = in[9];
1136 out->m[2][2] = in[10];
1137 out->m[2][3] = in[11];
1138 out->m[3][0] = in[12];
1139 out->m[3][1] = in[13];
1140 out->m[3][2] = in[14];
1141 out->m[3][3] = in[15];
1142#endif
1143}
1144
1145void Matrix4x4_ToArrayFloatGL (const matrix4x4_t* in, float out[16])
1146{
1147#ifdef MATRIX4x4_OPENGLORIENTATION
1148 out[ 0] = in->m[0][0];
1149 out[ 1] = in->m[0][1];
1150 out[ 2] = in->m[0][2];
1151 out[ 3] = in->m[0][3];
1152 out[ 4] = in->m[1][0];
1153 out[ 5] = in->m[1][1];
1154 out[ 6] = in->m[1][2];
1155 out[ 7] = in->m[1][3];
1156 out[ 8] = in->m[2][0];
1157 out[ 9] = in->m[2][1];
1158 out[10] = in->m[2][2];
1159 out[11] = in->m[2][3];
1160 out[12] = in->m[3][0];
1161 out[13] = in->m[3][1];
1162 out[14] = in->m[3][2];
1163 out[15] = in->m[3][3];
1164#else
1165 out[0] = in->m[0][0];
1166 out[1] = in->m[1][0];
1167 out[2] = in->m[2][0];
1168 out[3] = in->m[3][0];
1169 out[4] = in->m[0][1];
1170 out[5] = in->m[1][1];
1171 out[6] = in->m[2][1];
1172 out[7] = in->m[3][1];
1173 out[8] = in->m[0][2];
1174 out[9] = in->m[1][2];
1175 out[10] = in->m[2][2];
1176 out[11] = in->m[3][2];
1177 out[12] = in->m[0][3];
1178 out[13] = in->m[1][3];
1179 out[14] = in->m[2][3];
1180 out[15] = in->m[3][3];
1181#endif
1182}
1183
1184void Matrix4x4_FromArrayFloatGL (matrix4x4_t* out, const float in[16])
1185{
1186#ifdef MATRIX4x4_OPENGLORIENTATION
1187 out->m[0][0] = in[0];
1188 out->m[0][1] = in[1];
1189 out->m[0][2] = in[2];
1190 out->m[0][3] = in[3];
1191 out->m[1][0] = in[4];
1192 out->m[1][1] = in[5];
1193 out->m[1][2] = in[6];
1194 out->m[1][3] = in[7];
1195 out->m[2][0] = in[8];
1196 out->m[2][1] = in[9];
1197 out->m[2][2] = in[10];
1198 out->m[2][3] = in[11];
1199 out->m[3][0] = in[12];
1200 out->m[3][1] = in[13];
1201 out->m[3][2] = in[14];
1202 out->m[3][3] = in[15];
1203#else
1204 out->m[0][0] = in[0];
1205 out->m[1][0] = in[1];
1206 out->m[2][0] = in[2];
1207 out->m[3][0] = in[3];
1208 out->m[0][1] = in[4];
1209 out->m[1][1] = in[5];
1210 out->m[2][1] = in[6];
1211 out->m[3][1] = in[7];
1212 out->m[0][2] = in[8];
1213 out->m[1][2] = in[9];
1214 out->m[2][2] = in[10];
1215 out->m[3][2] = in[11];
1216 out->m[0][3] = in[12];
1217 out->m[1][3] = in[13];
1218 out->m[2][3] = in[14];
1219 out->m[3][3] = in[15];
1220#endif
1221}
1222
1223void Matrix4x4_ToArrayFloatD3D (const matrix4x4_t* in, float out[16])
1224{
1225#ifdef MATRIX4x4_OPENGLORIENTATION
1226 out[ 0] = in->m[0][0];
1227 out[ 1] = in->m[1][0];
1228 out[ 2] = in->m[2][0];
1229 out[ 3] = in->m[3][0];
1230 out[ 4] = in->m[0][1];
1231 out[ 5] = in->m[1][1];
1232 out[ 6] = in->m[2][1];
1233 out[ 7] = in->m[3][1];
1234 out[ 8] = in->m[0][2];
1235 out[ 9] = in->m[1][2];
1236 out[10] = in->m[2][2];
1237 out[11] = in->m[3][2];
1238 out[12] = in->m[0][3];
1239 out[13] = in->m[1][3];
1240 out[14] = in->m[2][3];
1241 out[15] = in->m[3][3];
1242#else
1243 out[0] = in->m[0][0];
1244 out[1] = in->m[0][1];
1245 out[2] = in->m[0][2];
1246 out[3] = in->m[0][3];
1247 out[4] = in->m[1][0];
1248 out[5] = in->m[1][1];
1249 out[6] = in->m[1][2];
1250 out[7] = in->m[1][3];
1251 out[8] = in->m[2][0];
1252 out[9] = in->m[2][1];
1253 out[10] = in->m[2][2];
1254 out[11] = in->m[2][3];
1255 out[12] = in->m[3][0];
1256 out[13] = in->m[3][1];
1257 out[14] = in->m[3][2];
1258 out[15] = in->m[3][3];
1259#endif
1260}
1261
1262void Matrix4x4_FromArrayFloatD3D (matrix4x4_t* out, const float in[16])
1263{
1264#ifdef MATRIX4x4_OPENGLORIENTATION
1265 out->m[0][0] = in[0];
1266 out->m[1][0] = in[1];
1267 out->m[2][0] = in[2];
1268 out->m[3][0] = in[3];
1269 out->m[0][1] = in[4];
1270 out->m[1][1] = in[5];
1271 out->m[2][1] = in[6];
1272 out->m[3][1] = in[7];
1273 out->m[0][2] = in[8];
1274 out->m[1][2] = in[9];
1275 out->m[2][2] = in[10];
1276 out->m[3][2] = in[11];
1277 out->m[0][3] = in[12];
1278 out->m[1][3] = in[13];
1279 out->m[2][3] = in[14];
1280 out->m[3][3] = in[15];
1281#else
1282 out->m[0][0] = in[0];
1283 out->m[0][1] = in[1];
1284 out->m[0][2] = in[2];
1285 out->m[0][3] = in[3];
1286 out->m[1][0] = in[4];
1287 out->m[1][1] = in[5];
1288 out->m[1][2] = in[6];
1289 out->m[1][3] = in[7];
1290 out->m[2][0] = in[8];
1291 out->m[2][1] = in[9];
1292 out->m[2][2] = in[10];
1293 out->m[2][3] = in[11];
1294 out->m[3][0] = in[12];
1295 out->m[3][1] = in[13];
1296 out->m[3][2] = in[14];
1297 out->m[3][3] = in[15];
1298#endif
1299}
1300
1301void Matrix4x4_ToArray12FloatGL (const matrix4x4_t* in, float out[12])
1302{
1303#ifdef MATRIX4x4_OPENGLORIENTATION
1304 out[ 0] = in->m[0][0];
1305 out[ 1] = in->m[0][1];
1306 out[ 2] = in->m[0][2];
1307 out[ 3] = in->m[1][0];
1308 out[ 4] = in->m[1][1];
1309 out[ 5] = in->m[1][2];
1310 out[ 6] = in->m[2][0];
1311 out[ 7] = in->m[2][1];
1312 out[ 8] = in->m[2][2];
1313 out[ 9] = in->m[3][0];
1314 out[10] = in->m[3][1];
1315 out[11] = in->m[3][2];
1316#else
1317 out[0] = in->m[0][0];
1318 out[1] = in->m[1][0];
1319 out[2] = in->m[2][0];
1320 out[3] = in->m[0][1];
1321 out[4] = in->m[1][1];
1322 out[5] = in->m[2][1];
1323 out[6] = in->m[0][2];
1324 out[7] = in->m[1][2];
1325 out[8] = in->m[2][2];
1326 out[9] = in->m[0][3];
1327 out[10] = in->m[1][3];
1328 out[11] = in->m[2][3];
1329#endif
1330}
1331
1332void Matrix4x4_FromArray12FloatGL (matrix4x4_t* out, const float in[12])
1333{
1334#ifdef MATRIX4x4_OPENGLORIENTATION
1335 out->m[0][0] = in[0];
1336 out->m[0][1] = in[1];
1337 out->m[0][2] = in[2];
1338 out->m[0][3] = 0;
1339 out->m[1][0] = in[3];
1340 out->m[1][1] = in[4];
1341 out->m[1][2] = in[5];
1342 out->m[1][3] = 0;
1343 out->m[2][0] = in[6];
1344 out->m[2][1] = in[7];
1345 out->m[2][2] = in[8];
1346 out->m[2][3] = 0;
1347 out->m[3][0] = in[9];
1348 out->m[3][1] = in[10];
1349 out->m[3][2] = in[11];
1350 out->m[3][3] = 1;
1351#else
1352 out->m[0][0] = in[0];
1353 out->m[1][0] = in[1];
1354 out->m[2][0] = in[2];
1355 out->m[3][0] = 0;
1356 out->m[0][1] = in[3];
1357 out->m[1][1] = in[4];
1358 out->m[2][1] = in[5];
1359 out->m[3][1] = 0;
1360 out->m[0][2] = in[6];
1361 out->m[1][2] = in[7];
1362 out->m[2][2] = in[8];
1363 out->m[3][2] = 0;
1364 out->m[0][3] = in[9];
1365 out->m[1][3] = in[10];
1366 out->m[2][3] = in[11];
1367 out->m[3][3] = 1;
1368#endif
1369}
1370
1371void Matrix4x4_ToArray12FloatD3D (const matrix4x4_t* in, float out[12])
1372{
1373#ifdef MATRIX4x4_OPENGLORIENTATION
1374 out[ 0] = in->m[0][0];
1375 out[ 1] = in->m[1][0];
1376 out[ 2] = in->m[2][0];
1377 out[ 3] = in->m[3][0];
1378 out[ 4] = in->m[0][1];
1379 out[ 5] = in->m[1][1];
1380 out[ 6] = in->m[2][1];
1381 out[ 7] = in->m[3][1];
1382 out[ 8] = in->m[0][2];
1383 out[ 9] = in->m[1][2];
1384 out[10] = in->m[2][2];
1385 out[11] = in->m[3][2];
1386#else
1387 out[0] = in->m[0][0];
1388 out[1] = in->m[0][1];
1389 out[2] = in->m[0][2];
1390 out[3] = in->m[0][3];
1391 out[4] = in->m[1][0];
1392 out[5] = in->m[1][1];
1393 out[6] = in->m[1][2];
1394 out[7] = in->m[1][3];
1395 out[8] = in->m[2][0];
1396 out[9] = in->m[2][1];
1397 out[10] = in->m[2][2];
1398 out[11] = in->m[2][3];
1399#endif
1400}
1401
1402void Matrix4x4_FromArray12FloatD3D (matrix4x4_t* out, const float in[12])
1403{
1404#ifdef MATRIX4x4_OPENGLORIENTATION
1405 out->m[0][0] = in[0];
1406 out->m[1][0] = in[1];
1407 out->m[2][0] = in[2];
1408 out->m[3][0] = in[3];
1409 out->m[0][1] = in[4];
1410 out->m[1][1] = in[5];
1411 out->m[2][1] = in[6];
1412 out->m[3][1] = in[7];
1413 out->m[0][2] = in[8];
1414 out->m[1][2] = in[9];
1415 out->m[2][2] = in[10];
1416 out->m[3][2] = in[11];
1417 out->m[0][3] = 0;
1418 out->m[1][3] = 0;
1419 out->m[2][3] = 0;
1420 out->m[3][3] = 1;
1421#else
1422 out->m[0][0] = in[0];
1423 out->m[0][1] = in[1];
1424 out->m[0][2] = in[2];
1425 out->m[0][3] = in[3];
1426 out->m[1][0] = in[4];
1427 out->m[1][1] = in[5];
1428 out->m[1][2] = in[6];
1429 out->m[1][3] = in[7];
1430 out->m[2][0] = in[8];
1431 out->m[2][1] = in[9];
1432 out->m[2][2] = in[10];
1433 out->m[2][3] = in[11];
1434 out->m[3][0] = 0;
1435 out->m[3][1] = 0;
1436 out->m[3][2] = 0;
1437 out->m[3][3] = 1;
1438#endif
1439}
1440
1441void Matrix4x4_FromOriginQuat (matrix4x4_t* m, double ox, double oy, double oz, double x, double y, double z, double w)
1442{
1443#ifdef MATRIX4x4_OPENGLORIENTATION
1444 m->m[0][0]=1-2*(y*y+z*z);m->m[1][0]= 2*(x*y-z*w);m->m[2][0]= 2*(x*z+y*w);m->m[3][0]=ox;
1445 m->m[0][1]= 2*(x*y+z*w);m->m[1][1]=1-2*(x*x+z*z);m->m[2][1]= 2*(y*z-x*w);m->m[3][1]=oy;
1446 m->m[0][2]= 2*(x*z-y*w);m->m[1][2]= 2*(y*z+x*w);m->m[2][2]=1-2*(x*x+y*y);m->m[3][2]=oz;
1447 m->m[0][3]= 0;m->m[1][3]= 0;m->m[2][3]= 0;m->m[3][3]=1;
1448#else
1449 m->m[0][0] = 1 - 2 * (y * y + z * z);
1450 m->m[0][1] = 2 * (x * y - z * w);
1451 m->m[0][2] = 2 * (x * z + y * w);
1452 m->m[0][3] = ox;
1453 m->m[1][0] = 2 * (x * y + z * w);
1454 m->m[1][1] = 1 - 2 * (x * x + z * z);
1455 m->m[1][2] = 2 * (y * z - x * w);
1456 m->m[1][3] = oy;
1457 m->m[2][0] = 2 * (x * z - y * w);
1458 m->m[2][1] = 2 * (y * z + x * w);
1459 m->m[2][2] = 1 - 2 * (x * x + y * y);
1460 m->m[2][3] = oz;
1461 m->m[3][0] = 0;
1462 m->m[3][1] = 0;
1463 m->m[3][2] = 0;
1464 m->m[3][3] = 1;
1465#endif
1466}
1467
1471void Matrix4x4_ToOrigin3Quat4Float (const matrix4x4_t* m, float* origin, float* quat)
1472{
1473 float s;
1474 quat[3] = sqrt(1.0f + m->m[0][0] + m->m[1][1] + m->m[2][2]) * 0.5f;
1475 s = 0.25f / quat[3];
1476#ifdef MATRIX4x4_OPENGLORIENTATION
1477 origin[0] = m->m[3][0];
1478 origin[1] = m->m[3][1];
1479 origin[2] = m->m[3][2];
1480 quat[0] = (m->m[1][2] - m->m[2][1]) * s;
1481 quat[1] = (m->m[2][0] - m->m[0][2]) * s;
1482 quat[2] = (m->m[0][1] - m->m[1][0]) * s;
1483#else
1484 origin[0] = m->m[0][3];
1485 origin[1] = m->m[1][3];
1486 origin[2] = m->m[2][3];
1487 quat[0] = (m->m[2][1] - m->m[1][2]) * s;
1488 quat[1] = (m->m[0][2] - m->m[2][0]) * s;
1489 quat[2] = (m->m[1][0] - m->m[0][1]) * s;
1490#endif
1491}
1492
1497void Matrix4x4_FromDoom3Joint (matrix4x4_t* m, double ox, double oy, double oz, double x, double y, double z)
1498{
1499 double w = 1.0f - (x * x + y * y + z * z);
1500 w = w > 0.0f ? -sqrt(w) : 0.0f;
1501#ifdef MATRIX4x4_OPENGLORIENTATION
1502 m->m[0][0]=1-2*(y*y+z*z);m->m[1][0]= 2*(x*y-z*w);m->m[2][0]= 2*(x*z+y*w);m->m[3][0]=ox;
1503 m->m[0][1]= 2*(x*y+z*w);m->m[1][1]=1-2*(x*x+z*z);m->m[2][1]= 2*(y*z-x*w);m->m[3][1]=oy;
1504 m->m[0][2]= 2*(x*z-y*w);m->m[1][2]= 2*(y*z+x*w);m->m[2][2]=1-2*(x*x+y*y);m->m[3][2]=oz;
1505 m->m[0][3]= 0;m->m[1][3]= 0;m->m[2][3]= 0;m->m[3][3]=1;
1506#else
1507 m->m[0][0] = 1 - 2 * (y * y + z * z);
1508 m->m[0][1] = 2 * (x * y - z * w);
1509 m->m[0][2] = 2 * (x * z + y * w);
1510 m->m[0][3] = ox;
1511 m->m[1][0] = 2 * (x * y + z * w);
1512 m->m[1][1] = 1 - 2 * (x * x + z * z);
1513 m->m[1][2] = 2 * (y * z - x * w);
1514 m->m[1][3] = oy;
1515 m->m[2][0] = 2 * (x * z - y * w);
1516 m->m[2][1] = 2 * (y * z + x * w);
1517 m->m[2][2] = 1 - 2 * (x * x + y * y);
1518 m->m[2][3] = oz;
1519 m->m[3][0] = 0;
1520 m->m[3][1] = 0;
1521 m->m[3][2] = 0;
1522 m->m[3][3] = 1;
1523#endif
1524}
1525
1526void Matrix4x4_FromBonePose6s (matrix4x4_t* m, float originscale, const short* pose6s)
1527{
1528 float origin[3];
1529 float quat[4];
1530 origin[0] = pose6s[0] * originscale;
1531 origin[1] = pose6s[1] * originscale;
1532 origin[2] = pose6s[2] * originscale;
1533 quat[0] = pose6s[3] * (1.0f / 32767.0f);
1534 quat[1] = pose6s[4] * (1.0f / 32767.0f);
1535 quat[2] = pose6s[5] * (1.0f / 32767.0f);
1536 quat[3] = 1.0f - (quat[0] * quat[0] + quat[1] * quat[1] + quat[2] * quat[2]);
1537 quat[3] = quat[3] > 0.0f ? -sqrt(quat[3]) : 0.0f;
1538 Matrix4x4_FromOriginQuat(m, origin[0], origin[1], origin[2], quat[0], quat[1], quat[2], quat[3]);
1539}
1540
1541void Matrix4x4_ToBonePose6s (const matrix4x4_t* m, float origininvscale, short* pose6s)
1542{
1543 float origin[3];
1544 float quat[4];
1545 float s;
1547 /* normalize quaternion so that it is unit length */
1548 s = quat[0] * quat[0] + quat[1] * quat[1] + quat[2] * quat[2] + quat[3] * quat[3];
1549 if (s) {
1550 s = 1.0f / sqrt(s);
1551 quat[0] *= s;
1552 quat[1] *= s;
1553 quat[2] *= s;
1554 quat[3] *= s;
1555 }
1556 /* use a negative scale on the quat because the above function produces a
1557 * positive quat[3] and canonical quaternions have negative quat[3] */
1558 pose6s[0] = origin[0] * origininvscale;
1559 pose6s[1] = origin[1] * origininvscale;
1560 pose6s[2] = origin[2] * origininvscale;
1561 pose6s[3] = quat[0] * -32767.0f;
1562 pose6s[4] = quat[1] * -32767.0f;
1563 pose6s[5] = quat[2] * -32767.0f;
1564}
1565
1566void Matrix4x4_Blend (matrix4x4_t* out, const matrix4x4_t* in1, const matrix4x4_t* in2, double blend)
1567{
1568 double iblend = 1 - blend;
1569 out->m[0][0] = in1->m[0][0] * iblend + in2->m[0][0] * blend;
1570 out->m[0][1] = in1->m[0][1] * iblend + in2->m[0][1] * blend;
1571 out->m[0][2] = in1->m[0][2] * iblend + in2->m[0][2] * blend;
1572 out->m[0][3] = in1->m[0][3] * iblend + in2->m[0][3] * blend;
1573 out->m[1][0] = in1->m[1][0] * iblend + in2->m[1][0] * blend;
1574 out->m[1][1] = in1->m[1][1] * iblend + in2->m[1][1] * blend;
1575 out->m[1][2] = in1->m[1][2] * iblend + in2->m[1][2] * blend;
1576 out->m[1][3] = in1->m[1][3] * iblend + in2->m[1][3] * blend;
1577 out->m[2][0] = in1->m[2][0] * iblend + in2->m[2][0] * blend;
1578 out->m[2][1] = in1->m[2][1] * iblend + in2->m[2][1] * blend;
1579 out->m[2][2] = in1->m[2][2] * iblend + in2->m[2][2] * blend;
1580 out->m[2][3] = in1->m[2][3] * iblend + in2->m[2][3] * blend;
1581 out->m[3][0] = in1->m[3][0] * iblend + in2->m[3][0] * blend;
1582 out->m[3][1] = in1->m[3][1] * iblend + in2->m[3][1] * blend;
1583 out->m[3][2] = in1->m[3][2] * iblend + in2->m[3][2] * blend;
1584 out->m[3][3] = in1->m[3][3] * iblend + in2->m[3][3] * blend;
1585}
1586
1587void Matrix4x4_Transform (const matrix4x4_t* in, const float v[3], float out[3])
1588{
1589#ifdef MATRIX4x4_OPENGLORIENTATION
1590 out[0] = v[0] * in->m[0][0] + v[1] * in->m[1][0] + v[2] * in->m[2][0] + in->m[3][0];
1591 out[1] = v[0] * in->m[0][1] + v[1] * in->m[1][1] + v[2] * in->m[2][1] + in->m[3][1];
1592 out[2] = v[0] * in->m[0][2] + v[1] * in->m[1][2] + v[2] * in->m[2][2] + in->m[3][2];
1593#else
1594 out[0] = v[0] * in->m[0][0] + v[1] * in->m[0][1] + v[2] * in->m[0][2] + in->m[0][3];
1595 out[1] = v[0] * in->m[1][0] + v[1] * in->m[1][1] + v[2] * in->m[1][2] + in->m[1][3];
1596 out[2] = v[0] * in->m[2][0] + v[1] * in->m[2][1] + v[2] * in->m[2][2] + in->m[2][3];
1597#endif
1598}
1599
1600void Matrix4x4_Transform4 (const matrix4x4_t* in, const float v[4], float out[4])
1601{
1602#ifdef MATRIX4x4_OPENGLORIENTATION
1603 out[0] = v[0] * in->m[0][0] + v[1] * in->m[1][0] + v[2] * in->m[2][0] + v[3] * in->m[3][0];
1604 out[1] = v[0] * in->m[0][1] + v[1] * in->m[1][1] + v[2] * in->m[2][1] + v[3] * in->m[3][1];
1605 out[2] = v[0] * in->m[0][2] + v[1] * in->m[1][2] + v[2] * in->m[2][2] + v[3] * in->m[3][2];
1606 out[3] = v[0] * in->m[0][3] + v[1] * in->m[1][3] + v[2] * in->m[2][3] + v[3] * in->m[3][3];
1607#else
1608 out[0] = v[0] * in->m[0][0] + v[1] * in->m[0][1] + v[2] * in->m[0][2] + v[3] * in->m[0][3];
1609 out[1] = v[0] * in->m[1][0] + v[1] * in->m[1][1] + v[2] * in->m[1][2] + v[3] * in->m[1][3];
1610 out[2] = v[0] * in->m[2][0] + v[1] * in->m[2][1] + v[2] * in->m[2][2] + v[3] * in->m[2][3];
1611 out[3] = v[0] * in->m[3][0] + v[1] * in->m[3][1] + v[2] * in->m[3][2] + v[3] * in->m[3][3];
1612#endif
1613}
1614
1615void Matrix4x4_Transform3x3 (const matrix4x4_t* in, const float v[3], float out[3])
1616{
1617#ifdef MATRIX4x4_OPENGLORIENTATION
1618 out[0] = v[0] * in->m[0][0] + v[1] * in->m[1][0] + v[2] * in->m[2][0];
1619 out[1] = v[0] * in->m[0][1] + v[1] * in->m[1][1] + v[2] * in->m[2][1];
1620 out[2] = v[0] * in->m[0][2] + v[1] * in->m[1][2] + v[2] * in->m[2][2];
1621#else
1622 out[0] = v[0] * in->m[0][0] + v[1] * in->m[0][1] + v[2] * in->m[0][2];
1623 out[1] = v[0] * in->m[1][0] + v[1] * in->m[1][1] + v[2] * in->m[1][2];
1624 out[2] = v[0] * in->m[2][0] + v[1] * in->m[2][1] + v[2] * in->m[2][2];
1625#endif
1626}
1627
1628void Matrix4x4_TransformPositivePlane (const matrix4x4_t* in, float x, float y, float z, float d, float* o)
1629{
1630 float scale = sqrt(in->m[0][0] * in->m[0][0] + in->m[0][1] * in->m[0][1] + in->m[0][2] * in->m[0][2]);
1631 float iscale = 1.0f / scale;
1632#ifdef MATRIX4x4_OPENGLORIENTATION
1633 o[0] = (x * in->m[0][0] + y * in->m[1][0] + z * in->m[2][0]) * iscale;
1634 o[1] = (x * in->m[0][1] + y * in->m[1][1] + z * in->m[2][1]) * iscale;
1635 o[2] = (x * in->m[0][2] + y * in->m[1][2] + z * in->m[2][2]) * iscale;
1636 o[3] = d * scale + (o[0] * in->m[3][0] + o[1] * in->m[3][1] + o[2] * in->m[3][2]);
1637#else
1638 o[0] = (x * in->m[0][0] + y * in->m[0][1] + z * in->m[0][2]) * iscale;
1639 o[1] = (x * in->m[1][0] + y * in->m[1][1] + z * in->m[1][2]) * iscale;
1640 o[2] = (x * in->m[2][0] + y * in->m[2][1] + z * in->m[2][2]) * iscale;
1641 o[3] = d * scale + (o[0] * in->m[0][3] + o[1] * in->m[1][3] + o[2] * in->m[2][3]);
1642#endif
1643}
1644
1645void Matrix4x4_TransformStandardPlane (const matrix4x4_t* in, float x, float y, float z, float d, float* o)
1646{
1647 float scale = sqrt(in->m[0][0] * in->m[0][0] + in->m[0][1] * in->m[0][1] + in->m[0][2] * in->m[0][2]);
1648 float iscale = 1.0f / scale;
1649#ifdef MATRIX4x4_OPENGLORIENTATION
1650 o[0] = (x * in->m[0][0] + y * in->m[1][0] + z * in->m[2][0]) * iscale;
1651 o[1] = (x * in->m[0][1] + y * in->m[1][1] + z * in->m[2][1]) * iscale;
1652 o[2] = (x * in->m[0][2] + y * in->m[1][2] + z * in->m[2][2]) * iscale;
1653 o[3] = d * scale - (o[0] * in->m[3][0] + o[1] * in->m[3][1] + o[2] * in->m[3][2]);
1654#else
1655 o[0] = (x * in->m[0][0] + y * in->m[0][1] + z * in->m[0][2]) * iscale;
1656 o[1] = (x * in->m[1][0] + y * in->m[1][1] + z * in->m[1][2]) * iscale;
1657 o[2] = (x * in->m[2][0] + y * in->m[2][1] + z * in->m[2][2]) * iscale;
1658 o[3] = d * scale - (o[0] * in->m[0][3] + o[1] * in->m[1][3] + o[2] * in->m[2][3]);
1659#endif
1660}
1661
1662/*
1663 void Matrix4x4_SimpleUntransform (const matrix4x4_t* in, const float v[3], float out[3])
1664 {
1665 double t[3];
1666 #ifdef MATRIX4x4_OPENGLORIENTATION
1667 t[0] = v[0] - in->m[3][0];
1668 t[1] = v[1] - in->m[3][1];
1669 t[2] = v[2] - in->m[3][2];
1670 out[0] = t[0] * in->m[0][0] + t[1] * in->m[0][1] + t[2] * in->m[0][2];
1671 out[1] = t[0] * in->m[1][0] + t[1] * in->m[1][1] + t[2] * in->m[1][2];
1672 out[2] = t[0] * in->m[2][0] + t[1] * in->m[2][1] + t[2] * in->m[2][2];
1673 #else
1674 t[0] = v[0] - in->m[0][3];
1675 t[1] = v[1] - in->m[1][3];
1676 t[2] = v[2] - in->m[2][3];
1677 out[0] = t[0] * in->m[0][0] + t[1] * in->m[1][0] + t[2] * in->m[2][0];
1678 out[1] = t[0] * in->m[0][1] + t[1] * in->m[1][1] + t[2] * in->m[2][1];
1679 out[2] = t[0] * in->m[0][2] + t[1] * in->m[1][2] + t[2] * in->m[2][2];
1680 #endif
1681 }
1682 */
1683
1684/* FIXME: optimize */
1685void Matrix4x4_ConcatTranslate (matrix4x4_t* out, double x, double y, double z)
1686{
1687 matrix4x4_t base, temp;
1688 base = *out;
1689 Matrix4x4_CreateTranslate(&temp, x, y, z);
1690 Matrix4x4_Concat(out, &base, &temp);
1691}
1692
1693/* FIXME: optimize */
1694void Matrix4x4_ConcatRotate (matrix4x4_t* out, double angle, double x, double y, double z)
1695{
1696 matrix4x4_t base, temp;
1697 base = *out;
1698 Matrix4x4_CreateRotate(&temp, angle, x, y, z);
1699 Matrix4x4_Concat(out, &base, &temp);
1700}
1701
1702/* FIXME: optimize */
1704{
1705 matrix4x4_t base, temp;
1706 base = *out;
1707 Matrix4x4_CreateScale(&temp, x);
1708 Matrix4x4_Concat(out, &base, &temp);
1709}
1710
1711/* FIXME: optimize */
1712void Matrix4x4_ConcatScale3 (matrix4x4_t* out, double x, double y, double z)
1713{
1714 matrix4x4_t base, temp;
1715 base = *out;
1716 Matrix4x4_CreateScale3(&temp, x, y, z);
1717 Matrix4x4_Concat(out, &base, &temp);
1718}
1719
1720void Matrix4x4_OriginFromMatrix (const matrix4x4_t* in, float* out)
1721{
1722#ifdef MATRIX4x4_OPENGLORIENTATION
1723 out[0] = in->m[3][0];
1724 out[1] = in->m[3][1];
1725 out[2] = in->m[3][2];
1726#else
1727 out[0] = in->m[0][3];
1728 out[1] = in->m[1][3];
1729 out[2] = in->m[2][3];
1730#endif
1731}
1732
1734{
1735 /* we only support uniform scaling, so assume the first row is enough */
1736 return sqrt(in->m[0][0] * in->m[0][0] + in->m[0][1] * in->m[0][1] + in->m[0][2] * in->m[0][2]);
1737}
1738
1739void Matrix4x4_SetOrigin (matrix4x4_t* out, double x, double y, double z)
1740{
1741#ifdef MATRIX4x4_OPENGLORIENTATION
1742 out->m[3][0] = x;
1743 out->m[3][1] = y;
1744 out->m[3][2] = z;
1745#else
1746 out->m[0][3] = x;
1747 out->m[1][3] = y;
1748 out->m[2][3] = z;
1749#endif
1750}
1751
1752void Matrix4x4_AdjustOrigin (matrix4x4_t* out, double x, double y, double z)
1753{
1754#ifdef MATRIX4x4_OPENGLORIENTATION
1755 out->m[3][0] += x;
1756 out->m[3][1] += y;
1757 out->m[3][2] += z;
1758#else
1759 out->m[0][3] += x;
1760 out->m[1][3] += y;
1761 out->m[2][3] += z;
1762#endif
1763}
1764
1765void Matrix4x4_Scale (matrix4x4_t* out, double rotatescale, double originscale)
1766{
1767 out->m[0][0] *= rotatescale;
1768 out->m[0][1] *= rotatescale;
1769 out->m[0][2] *= rotatescale;
1770 out->m[1][0] *= rotatescale;
1771 out->m[1][1] *= rotatescale;
1772 out->m[1][2] *= rotatescale;
1773 out->m[2][0] *= rotatescale;
1774 out->m[2][1] *= rotatescale;
1775 out->m[2][2] *= rotatescale;
1776#ifdef MATRIX4x4_OPENGLORIENTATION
1777 out->m[3][0] *= originscale;
1778 out->m[3][1] *= originscale;
1779 out->m[3][2] *= originscale;
1780#else
1781 out->m[0][3] *= originscale;
1782 out->m[1][3] *= originscale;
1783 out->m[2][3] *= originscale;
1784#endif
1785}
1786
1788{
1789 out->m[0][0] = fabs(out->m[0][0]);
1790 out->m[0][1] = fabs(out->m[0][1]);
1791 out->m[0][2] = fabs(out->m[0][2]);
1792 out->m[1][0] = fabs(out->m[1][0]);
1793 out->m[1][1] = fabs(out->m[1][1]);
1794 out->m[1][2] = fabs(out->m[1][2]);
1795 out->m[2][0] = fabs(out->m[2][0]);
1796 out->m[2][1] = fabs(out->m[2][1]);
1797 out->m[2][2] = fabs(out->m[2][2]);
1798}
voidpf uLong int origin
Definition ioapi.h:45
#define torad
Definition mathlib.h:50
static struct mdfour * m
Definition md4.cpp:35
QGL_EXTERN GLuint GLchar GLuint * len
Definition r_gl.h:99
QGL_EXTERN int GLboolean GLfloat * v
Definition r_gl.h:120
QGL_EXTERN GLint i
Definition r_gl.h:113
local graphics definitions
void Matrix4x4_AdjustOrigin(matrix4x4_t *out, double x, double y, double z)
void Matrix4x4_Concat(matrix4x4_t *out, const matrix4x4_t *in1, const matrix4x4_t *in2)
Definition r_matrix.cpp:90
void Matrix4x4_CreateIdentity(matrix4x4_t *out)
Definition r_matrix.cpp:597
void Matrix4x4_FromBonePose6s(matrix4x4_t *m, float originscale, const short *pose6s)
void Matrix4x4_ToBonePose6s(const matrix4x4_t *m, float origininvscale, short *pose6s)
void Matrix4x4_Clear(matrix4x4_t *out)
Definition r_matrix.cpp:522
void Matrix4x4_TransformStandardPlane(const matrix4x4_t *in, float x, float y, float z, float d, float *o)
void Matrix4x4_TransformPositivePlane(const matrix4x4_t *in, float x, float y, float z, float d, float *o)
void Matrix4x4_FromArray12FloatGL(matrix4x4_t *out, const float in[12])
void Matrix4x4_Transform(const matrix4x4_t *in, const float v[3], float out[3])
void Matrix4x4_Transform4(const matrix4x4_t *in, const float v[4], float out[4])
void Matrix4x4_FromOriginQuat(matrix4x4_t *m, double ox, double oy, double oz, double x, double y, double z, double w)
void Matrix4x4_ToArrayDoubleGL(const matrix4x4_t *in, double out[16])
Definition r_matrix.cpp:989
void Matrix4x4_Blend(matrix4x4_t *out, const matrix4x4_t *in1, const matrix4x4_t *in2, double blend)
void Matrix4x4_FromArrayFloatD3D(matrix4x4_t *out, const float in[16])
void Matrix4x4_ToArrayFloatGL(const matrix4x4_t *in, float out[16])
void Matrix4x4_CreateTranslate(matrix4x4_t *out, double x, double y, double z)
Definition r_matrix.cpp:617
void Matrix4x4_ToArray12FloatD3D(const matrix4x4_t *in, float out[12])
void Matrix4x4_ToArray12FloatGL(const matrix4x4_t *in, float out[12])
void Matrix4x4_Transpose(matrix4x4_t *out, const matrix4x4_t *in1)
Definition r_matrix.cpp:145
void Matrix4x4_Transform3x3(const matrix4x4_t *in, const float v[3], float out[3])
void Matrix4x4_FromArrayFloatGL(matrix4x4_t *out, const float in[16])
void Matrix4x4_FromArrayDoubleGL(matrix4x4_t *out, const double in[16])
void Matrix4x4_CreateFromQuakeEntity(matrix4x4_t *out, double x, double y, double z, double pitch, double yaw, double roll, double scale)
Definition r_matrix.cpp:748
void Matrix4x4_CopyTranslateOnly(matrix4x4_t *out, const matrix4x4_t *in)
Definition r_matrix.cpp:51
void Matrix4x4_FromArrayDoubleD3D(matrix4x4_t *out, const double in[16])
int Matrix4x4_Invert_Full(matrix4x4_t *out, const matrix4x4_t *in1)
Definition r_matrix.cpp:170
void Matrix4x4_CreateScale3(matrix4x4_t *out, double x, double y, double z)
Definition r_matrix.cpp:728
void Matrix4x4_ConcatScale3(matrix4x4_t *out, double x, double y, double z)
void Matrix4x4_ToArrayDoubleD3D(const matrix4x4_t *in, double out[16])
void Matrix4x4_SetOrigin(matrix4x4_t *out, double x, double y, double z)
void Matrix4x4_ConcatScale(matrix4x4_t *out, double x)
void Matrix4x4_Normalize3(matrix4x4_t *out, matrix4x4_t *in1)
Definition r_matrix.cpp:545
void Matrix4x4_ToOrigin3Quat4Float(const matrix4x4_t *m, float *origin, float *quat)
void Matrix4x4_FromArray12FloatD3D(matrix4x4_t *out, const float in[12])
void Matrix4x4_ToArrayFloatD3D(const matrix4x4_t *in, float out[16])
void Matrix4x4_Reflect(matrix4x4_t *out, double normalx, double normaly, double normalz, double dist, double axisscale)
Definition r_matrix.cpp:570
void Matrix4x4_CreateScale(matrix4x4_t *out, double x)
Definition r_matrix.cpp:708
void Matrix4x4_Interpolate(matrix4x4_t *out, matrix4x4_t *in1, matrix4x4_t *in2, double frac)
Definition r_matrix.cpp:515
void Matrix4x4_Invert_Simple(matrix4x4_t *out, const matrix4x4_t *in1)
Definition r_matrix.cpp:462
void Matrix4x4_Abs(matrix4x4_t *out)
void Matrix4x4_ConcatTranslate(matrix4x4_t *out, double x, double y, double z)
double Matrix4x4_ScaleFromMatrix(const matrix4x4_t *in)
void Matrix4x4_FromVectors(matrix4x4_t *out, const float vx[3], const float vy[3], const float vz[3], const float t[3])
Definition r_matrix.cpp:950
void Matrix4x4_Normalize(matrix4x4_t *out, matrix4x4_t *in1)
Definition r_matrix.cpp:536
void Matrix4x4_Accumulate(matrix4x4_t *out, matrix4x4_t *in, double weight)
Definition r_matrix.cpp:529
void Matrix4x4_ToVectors(const matrix4x4_t *in, float vx[3], float vy[3], float vz[3], float t[3])
Definition r_matrix.cpp:919
const matrix4x4_t identitymatrix
Definition r_matrix.cpp:24
void Matrix4x4_Copy(matrix4x4_t *out, const matrix4x4_t *in)
Definition r_matrix.cpp:26
void Matrix4x4_CreateRotate(matrix4x4_t *out, double angle, double x, double y, double z)
Definition r_matrix.cpp:656
void Matrix4x4_ConcatRotate(matrix4x4_t *out, double angle, double x, double y, double z)
void Matrix4x4_FromDoom3Joint(matrix4x4_t *m, double ox, double oy, double oz, double x, double y, double z)
void Matrix4x4_Scale(matrix4x4_t *out, double rotatescale, double originscale)
void Matrix4x4_OriginFromMatrix(const matrix4x4_t *in, float *out)
void Matrix4x4_CopyRotateOnly(matrix4x4_t *out, const matrix4x4_t *in)
Definition r_matrix.cpp:31
float m[4][4]
Definition r_matrix.h:27
static const vec3_t scale