UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 
24 const matrix4x4_t identitymatrix = { { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } } };
25 
26 void Matrix4x4_Copy (matrix4x4_t* out, const matrix4x4_t* in)
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 
90 void 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
166 
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
235 
238 int 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
293 int 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 
515 void 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 
529 void 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 
570 void 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 
617 void 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 
656 void 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 
708 void Matrix4x4_CreateScale (matrix4x4_t* out, double x)
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 
728 void 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 
748 void 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 
919 void 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 
950 void 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 
989 void 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 
1028 void 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 
1067 void 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 
1106 void 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 
1145 void 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 
1184 void 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 
1223 void 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 
1262 void 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 
1301 void 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 
1332 void 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 
1371 void 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 
1402 void 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 
1441 void 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 
1471 void 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 
1497 void 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 
1526 void 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 
1541 void Matrix4x4_ToBonePose6s (const matrix4x4_t* m, float origininvscale, short* pose6s)
1542 {
1543  float origin[3];
1544  float quat[4];
1545  float s;
1546  Matrix4x4_ToOrigin3Quat4Float(m, origin, quat);
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 
1566 void 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 
1587 void 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 
1600 void 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 
1615 void 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 
1628 void 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 
1645 void 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 */
1685 void 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 */
1694 void 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 */
1703 void Matrix4x4_ConcatScale (matrix4x4_t* out, double x)
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 */
1712 void 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 
1720 void 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 
1739 void 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 
1752 void 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 
1765 void 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 }
void Matrix4x4_FromArrayDoubleGL(matrix4x4_t *out, const double in[16])
Definition: r_matrix.cpp:1028
void Matrix4x4_ConcatTranslate(matrix4x4_t *out, double x, double y, double z)
Definition: r_matrix.cpp:1685
void Matrix4x4_ToArrayDoubleGL(const matrix4x4_t *in, double out[16])
Definition: r_matrix.cpp:989
void Matrix4x4_Invert_Simple(matrix4x4_t *out, const matrix4x4_t *in1)
Definition: r_matrix.cpp:462
void Matrix4x4_Blend(matrix4x4_t *out, const matrix4x4_t *in1, const matrix4x4_t *in2, double blend)
Definition: r_matrix.cpp:1566
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_CreateIdentity(matrix4x4_t *out)
Definition: r_matrix.cpp:597
double Matrix4x4_ScaleFromMatrix(const matrix4x4_t *in)
Definition: r_matrix.cpp:1733
void Matrix4x4_ConcatRotate(matrix4x4_t *out, double angle, double x, double y, double z)
Definition: r_matrix.cpp:1694
static const vec3_t scale
void Matrix4x4_ConcatScale(matrix4x4_t *out, double x)
Definition: r_matrix.cpp:1703
void Matrix4x4_FromArrayFloatGL(matrix4x4_t *out, const float in[16])
Definition: r_matrix.cpp:1184
void Matrix4x4_Scale(matrix4x4_t *out, double rotatescale, double originscale)
Definition: r_matrix.cpp:1765
void Matrix4x4_Transform4(const matrix4x4_t *in, const float v[4], float out[4])
Definition: r_matrix.cpp:1600
voidpf uLong int origin
Definition: ioapi.h:45
void Matrix4x4_FromArray12FloatGL(matrix4x4_t *out, const float in[12])
Definition: r_matrix.cpp:1332
void Matrix4x4_FromArray12FloatD3D(matrix4x4_t *out, const float in[12])
Definition: r_matrix.cpp:1402
void Matrix4x4_Clear(matrix4x4_t *out)
Definition: r_matrix.cpp:522
void Matrix4x4_Normalize(matrix4x4_t *out, matrix4x4_t *in1)
Definition: r_matrix.cpp:536
void Matrix4x4_FromOriginQuat(matrix4x4_t *m, double ox, double oy, double oz, double x, double y, double z, double w)
Definition: r_matrix.cpp:1441
local graphics definitions
float m[4][4]
Definition: r_matrix.h:27
void Matrix4x4_FromBonePose6s(matrix4x4_t *m, float originscale, const short *pose6s)
Definition: r_matrix.cpp:1526
const matrix4x4_t identitymatrix
Definition: r_matrix.cpp:24
void Matrix4x4_Transform(const matrix4x4_t *in, const float v[3], float out[3])
Definition: r_matrix.cpp:1587
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_ToVectors(const matrix4x4_t *in, float vx[3], float vy[3], float vz[3], float t[3])
Definition: r_matrix.cpp:919
void Matrix4x4_CreateScale3(matrix4x4_t *out, double x, double y, double z)
Definition: r_matrix.cpp:728
void Matrix4x4_ToBonePose6s(const matrix4x4_t *m, float origininvscale, short *pose6s)
Definition: r_matrix.cpp:1541
void Matrix4x4_TransformStandardPlane(const matrix4x4_t *in, float x, float y, float z, float d, float *o)
Definition: r_matrix.cpp:1645
void Matrix4x4_CopyRotateOnly(matrix4x4_t *out, const matrix4x4_t *in)
Definition: r_matrix.cpp:31
void Matrix4x4_FromDoom3Joint(matrix4x4_t *m, double ox, double oy, double oz, double x, double y, double z)
Definition: r_matrix.cpp:1497
void Matrix4x4_ConcatScale3(matrix4x4_t *out, double x, double y, double z)
Definition: r_matrix.cpp:1712
void Matrix4x4_TransformPositivePlane(const matrix4x4_t *in, float x, float y, float z, float d, float *o)
Definition: r_matrix.cpp:1628
void Matrix4x4_Interpolate(matrix4x4_t *out, matrix4x4_t *in1, matrix4x4_t *in2, double frac)
Definition: r_matrix.cpp:515
void Matrix4x4_Reflect(matrix4x4_t *out, double normalx, double normaly, double normalz, double dist, double axisscale)
Definition: r_matrix.cpp:570
QGL_EXTERN GLfloat f
Definition: r_gl.h:114
void Matrix4x4_ToArray12FloatD3D(const matrix4x4_t *in, float out[12])
Definition: r_matrix.cpp:1371
void Matrix4x4_Accumulate(matrix4x4_t *out, matrix4x4_t *in, double weight)
Definition: r_matrix.cpp:529
void Matrix4x4_CreateTranslate(matrix4x4_t *out, double x, double y, double z)
Definition: r_matrix.cpp:617
QGL_EXTERN GLint i
Definition: r_gl.h:113
QGL_EXTERN GLuint GLchar GLuint * len
Definition: r_gl.h:99
int Matrix4x4_Invert_Full(matrix4x4_t *out, const matrix4x4_t *in1)
Definition: r_matrix.cpp:170
void Matrix4x4_Concat(matrix4x4_t *out, const matrix4x4_t *in1, const matrix4x4_t *in2)
Definition: r_matrix.cpp:90
void Matrix4x4_ToArrayFloatD3D(const matrix4x4_t *in, float out[16])
Definition: r_matrix.cpp:1223
void Matrix4x4_Abs(matrix4x4_t *out)
Definition: r_matrix.cpp:1787
void Matrix4x4_AdjustOrigin(matrix4x4_t *out, double x, double y, double z)
Definition: r_matrix.cpp:1752
void Matrix4x4_CreateRotate(matrix4x4_t *out, double angle, double x, double y, double z)
Definition: r_matrix.cpp:656
void Matrix4x4_ToOrigin3Quat4Float(const matrix4x4_t *m, float *origin, float *quat)
Definition: r_matrix.cpp:1471
#define torad
Definition: mathlib.h:50
void Matrix4x4_ToArrayFloatGL(const matrix4x4_t *in, float out[16])
Definition: r_matrix.cpp:1145
void Matrix4x4_Transform3x3(const matrix4x4_t *in, const float v[3], float out[3])
Definition: r_matrix.cpp:1615
void Matrix4x4_Transpose(matrix4x4_t *out, const matrix4x4_t *in1)
Definition: r_matrix.cpp:145
void Matrix4x4_ToArray12FloatGL(const matrix4x4_t *in, float out[12])
Definition: r_matrix.cpp:1301
void Matrix4x4_CopyTranslateOnly(matrix4x4_t *out, const matrix4x4_t *in)
Definition: r_matrix.cpp:51
void Matrix4x4_FromArrayFloatD3D(matrix4x4_t *out, const float in[16])
Definition: r_matrix.cpp:1262
void Matrix4x4_ToArrayDoubleD3D(const matrix4x4_t *in, double out[16])
Definition: r_matrix.cpp:1067
void Matrix4x4_Copy(matrix4x4_t *out, const matrix4x4_t *in)
Definition: r_matrix.cpp:26
QGL_EXTERN int GLboolean GLfloat * v
Definition: r_gl.h:120
void Matrix4x4_CreateScale(matrix4x4_t *out, double x)
Definition: r_matrix.cpp:708
static struct mdfour * m
Definition: md4.cpp:35
void Matrix4x4_Normalize3(matrix4x4_t *out, matrix4x4_t *in1)
Definition: r_matrix.cpp:545
void Matrix4x4_OriginFromMatrix(const matrix4x4_t *in, float *out)
Definition: r_matrix.cpp:1720
void Matrix4x4_FromArrayDoubleD3D(matrix4x4_t *out, const double in[16])
Definition: r_matrix.cpp:1106
void Matrix4x4_SetOrigin(matrix4x4_t *out, double x, double y, double z)
Definition: r_matrix.cpp:1739