Line data Source code
1 0 : /*
2 :
3 : OOMatrix.h
4 :
5 : Mathematical framework for Oolite.
6 :
7 : Oolite
8 : Copyright (C) 2004-2013 Giles C Williams and contributors
9 :
10 : This program is free software; you can redistribute it and/or
11 : modify it under the terms of the GNU General Public License
12 : as published by the Free Software Foundation; either version 2
13 : of the License, or (at your option) any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program; if not, write to the Free Software
22 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 : MA 02110-1301, USA.
24 :
25 : */
26 :
27 :
28 : #ifndef INCLUDED_OOMATHS_h
29 : #error Do not include OOMatrix.h directly; include OOMaths.h.
30 : #else
31 :
32 : typedef struct OOMatrix
33 : {
34 : OOScalar m[4][4];
35 : } OOMatrix;
36 :
37 :
38 : extern const OOMatrix kIdentityMatrix; /* {1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1} */
39 : extern const OOMatrix kZeroMatrix; /* {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0} */
40 :
41 :
42 : /* Matrix construction and standard primitive matrices */
43 : OOINLINE OOMatrix OOMatrixConstruct(OOScalar aa, OOScalar ab, OOScalar ac, OOScalar ad,
44 : OOScalar ba, OOScalar bb, OOScalar bc, OOScalar bd,
45 : OOScalar ca, OOScalar cb, OOScalar cc, OOScalar cd,
46 : OOScalar da, OOScalar db, OOScalar dc, OOScalar dd) INLINE_CONST_FUNC;
47 :
48 : OOINLINE OOMatrix OOMatrixFromOrientationAndPosition(Quaternion orientation, Vector position) INLINE_CONST_FUNC;
49 :
50 : OOINLINE OOMatrix OOMatrixFromBasisVectorsAndPosition(Vector i, Vector j, Vector k, Vector position) INLINE_CONST_FUNC;
51 : OOINLINE OOMatrix OOMatrixFromBasisVectors(Vector i, Vector j, Vector k) INLINE_CONST_FUNC;
52 :
53 : OOINLINE OOMatrix OOMatrixForScale(OOScalar sx, OOScalar sy, OOScalar sz) INLINE_CONST_FUNC;
54 : OOINLINE OOMatrix OOMatrixForScaleUniform(OOScalar s) INLINE_CONST_FUNC;
55 :
56 : OOINLINE OOMatrix OOMatrixForRotationX(OOScalar angle) INLINE_CONST_FUNC;
57 : OOINLINE OOMatrix OOMatrixForRotationY(OOScalar angle) INLINE_CONST_FUNC;
58 : OOINLINE OOMatrix OOMatrixForRotationZ(OOScalar angle) INLINE_CONST_FUNC;
59 : OOMatrix OOMatrixForRotation(Vector axis, OOScalar angle) CONST_FUNC;
60 : OOMatrix OOMatrixForQuaternionRotation(Quaternion orientation);
61 :
62 : OOINLINE OOMatrix OOMatrixForTranslation(Vector v) INLINE_CONST_FUNC;
63 : OOINLINE OOMatrix OOMatrixForTranslationComponents(OOScalar dx, OOScalar dy, OOScalar dz) INLINE_CONST_FUNC;
64 :
65 : OOMatrix OOMatrixForBillboard(HPVector bbPos, HPVector eyePos) CONST_FUNC;
66 :
67 :
68 : /* Matrix transformations */
69 : OOINLINE OOMatrix OOMatrixTranslate(OOMatrix m, Vector offset) INLINE_CONST_FUNC;
70 : OOINLINE OOMatrix OOMatrixHPTranslate(OOMatrix m, HPVector offset) INLINE_CONST_FUNC;
71 : OOINLINE OOMatrix OOMatrixTranslateComponents(OOMatrix m, OOScalar dx, OOScalar dy, OOScalar dz) INLINE_CONST_FUNC;
72 :
73 : OOINLINE OOMatrix OOMatrixScale(OOMatrix m, OOScalar sx, OOScalar sy, OOScalar sz) INLINE_CONST_FUNC;
74 : OOINLINE OOMatrix OOMatrixScaleUniform(OOMatrix m, OOScalar s) INLINE_CONST_FUNC;
75 :
76 : OOINLINE OOMatrix OOMatrixRotateX(OOMatrix m, OOScalar angle) INLINE_CONST_FUNC;
77 : OOINLINE OOMatrix OOMatrixRotateY(OOMatrix m, OOScalar angle) INLINE_CONST_FUNC;
78 : OOINLINE OOMatrix OOMatrixRotateZ(OOMatrix m, OOScalar angle) INLINE_CONST_FUNC;
79 : OOINLINE OOMatrix OOMatrixRotate(OOMatrix m, Vector axis, OOScalar angle) INLINE_CONST_FUNC;
80 : OOINLINE OOMatrix OOMatrixRotateQuaternion(OOMatrix m, Quaternion quat) INLINE_CONST_FUNC;
81 : OOINLINE OOMatrix OOMatrixTranspose(OOMatrix m) INLINE_CONST_FUNC;
82 :
83 : bool OOMatrixEqual(OOMatrix a, OOMatrix b) CONST_FUNC;
84 : OOINLINE bool OOMatrixIsIdentity(OOMatrix m) INLINE_CONST_FUNC;
85 :
86 :
87 : /* Matrix multiplication */
88 : OOMatrix OOMatrixMultiply(OOMatrix a, OOMatrix b) CONST_FUNC;
89 : Vector OOVectorMultiplyMatrix(Vector v, OOMatrix m) CONST_FUNC;
90 : HPVector OOHPVectorMultiplyMatrix(HPVector v, OOMatrix m) CONST_FUNC;
91 :
92 :
93 : /* Extraction */
94 : OOINLINE void OOMatrixGetBasisVectors(OOMatrix m, Vector *outRight, Vector *outUp, Vector *outForward) NONNULL_FUNC ALWAYS_INLINE_FUNC;
95 :
96 :
97 : /* Orthogonalizion - avoidance of distortions due to numerical inaccuracy. */
98 : OOMatrix OOMatrixOrthogonalize(OOMatrix m) CONST_FUNC;
99 :
100 :
101 : #if OOMATHS_OPENGL_INTEGRATION
102 : /* OpenGL conveniences. Need to be macros to work with OOMacroOpenGL. */
103 : #define OOMatrixValuesForOpenGL(M) (&(M).m[0][0])
104 : #define GLMultOOMatrix(M) do { OOMatrix m_ = M; OOGL(glMultMatrixf(OOMatrixValuesForOpenGL(m_))); } while (0)
105 : #define GLLoadOOMatrix(M) do { OOMatrix m_ = M; OOGL(glLoadMatrixf(OOMatrixValuesForOpenGL(m_))); } while (0)
106 : #define GLMultTransposeOOMatrix(M) do { OOMatrix m_ = M; OOGL(glMultTransposeMatrixf(OOMatrixValuesForOpenGL(m_))); } while (0)
107 : #define GLLoadTransposeOOMatrix(M) do { OOMatrix m_ = M; OOGL(glLoadTransposeMatrixf(OOMatrixValuesForOpenGL(m_))); } while (0)
108 : #define GLUniformMatrix(location, M) do { OOGL(glUniformMatrix4fvARB(location, 1, NO, OOMatrixValuesForOpenGL(M))); } while (0)
109 : void GLUniformMatrix3(GLint location, OOMatrix M);
110 :
111 : OOINLINE OOMatrix OOMatrixLoadGLMatrix(GLenum matrixID) ALWAYS_INLINE_FUNC;
112 : #endif
113 :
114 :
115 : #if __OBJC__
116 : NSString *OOMatrixDescription(OOMatrix matrix); // @"{{#, #, #, #}, {#, #, #, #}, {#, #, #, #}, {#, #, #, #}}"
117 : #endif
118 :
119 : // Row operations
120 :
121 : // swap row1 and row2 of M
122 : void OOMatrixRowSwap(OOMatrix *M, int row1, int row2);
123 : // scale row of M by factor
124 : void OOMatrixRowScale(OOMatrix *m, int row, OOScalar factor);
125 : // replace row 1 of M with factor1 * row1 + factor2 * row2
126 : void OOMatrixRowOperation(OOMatrix *M, int row1, OOScalar factor1, int row2, OOScalar factor2 );
127 :
128 : // Column operations
129 :
130 : // swap column1 and column2 of M
131 : void OOMatrixColumnSwap(OOMatrix *M, int column1, int column2);
132 : // scale column of M by factor
133 : void OOMatrixColumnScale(OOMatrix *M, int column, OOScalar factor);
134 : //replace column1 of M with factor1 * column1 + factor2 + row2
135 : void OOMatrixColumnOperation(OOMatrix *M, int column1, OOScalar factor1, int column2, OOScalar factor2);
136 :
137 : // Transforms between square matrices
138 :
139 : // return matrix X such that XA = B, or zero matrix if X doesn't exist.
140 : OOMatrix OOMatrixLeftTransform(OOMatrix A, OOMatrix B);
141 : // return matrix X such that AX = B, or zero matrix if X doesn't exist.
142 : OOMatrix OOMatrixRightTransform(OOMatrix A, OOMatrix B);
143 :
144 : // Matrix inversion
145 :
146 : OOMatrix OOMatrixInverse(OOMatrix M);
147 : // Inverts matrix returning determinant of inverse in
148 : OOMatrix OOMatrixInverseWithDeterminant(OOMatrix M, OOScalar *determinant);
149 :
150 : /*** Only inline definitions beyond this point ***/
151 :
152 : OOINLINE OOMatrix OOMatrixConstruct(OOScalar aa, OOScalar ab, OOScalar ac, OOScalar ad,
153 : OOScalar ba, OOScalar bb, OOScalar bc, OOScalar bd,
154 : OOScalar ca, OOScalar cb, OOScalar cc, OOScalar cd,
155 : OOScalar da, OOScalar db, OOScalar dc, OOScalar dd)
156 : {
157 : OOMatrix r =
158 : {{
159 : { aa, ab, ac, ad },
160 : { ba, bb, bc, bd },
161 : { ca, cb, cc, cd },
162 : { da, db, dc, dd }
163 : }};
164 : return r;
165 : }
166 :
167 : OOINLINE OOMatrix OOMatrixFromOrientationAndPosition(Quaternion orientation, Vector position)
168 : {
169 : OOMatrix m = OOMatrixForQuaternionRotation(orientation);
170 : return OOMatrixTranslate(m, position);
171 : }
172 :
173 :
174 : OOINLINE OOMatrix OOMatrixFromBasisVectorsAndPosition(Vector i, Vector j, Vector k, Vector p)
175 : {
176 : return OOMatrixConstruct
177 : (
178 : i.x, i.y, i.z, 0.0f,
179 : j.x, j.y, j.z, 0.0f,
180 : k.x, k.y, k.z, 0.0f,
181 : p.x, p.y, p.z, 1.0f
182 : );
183 : }
184 :
185 :
186 : OOINLINE OOMatrix OOMatrixFromBasisVectors(Vector i, Vector j, Vector k)
187 : {
188 : return OOMatrixFromBasisVectorsAndPosition(i, j, k, kZeroVector);
189 : }
190 :
191 :
192 : /* Standard primitive transformation matrices: */
193 : OOMatrix OOMatrixForRotationX(OOScalar angle)
194 : {
195 : OOScalar s, c;
196 :
197 : s = sin(angle);
198 : c = cos(angle);
199 :
200 : return OOMatrixConstruct
201 : (
202 : 1, 0, 0, 0,
203 : 0, c, s, 0,
204 : 0, -s, c, 0,
205 : 0, 0, 0, 1
206 : );
207 : }
208 :
209 :
210 : OOMatrix OOMatrixForRotationY(OOScalar angle)
211 : {
212 : OOScalar s, c;
213 :
214 : s = sin(angle);
215 : c = cos(angle);
216 :
217 : return OOMatrixConstruct
218 : (
219 : c, 0, -s, 0,
220 : 0, 1, 0, 0,
221 : s, 0, c, 0,
222 : 0, 0, 0, 1
223 : );
224 : }
225 :
226 :
227 : OOMatrix OOMatrixForRotationZ(OOScalar angle)
228 : {
229 : OOScalar s, c;
230 :
231 : s = sin(angle);
232 : c = cos(angle);
233 :
234 : return OOMatrixConstruct
235 : (
236 : c, s, 0, 0,
237 : -s, c, 0, 0,
238 : 0, 0, 1, 0,
239 : 0, 0, 0, 1
240 : );
241 : }
242 : OOINLINE OOMatrix OOMatrixForTranslationComponents(OOScalar dx, OOScalar dy, OOScalar dz)
243 : {
244 : return OOMatrixConstruct
245 : (
246 : 1, 0, 0, 0,
247 : 0, 1, 0, 0,
248 : 0, 0, 1, 0,
249 : dx, dy, dz, 1
250 : );
251 : }
252 :
253 :
254 : OOINLINE OOMatrix OOMatrixForTranslation(Vector v)
255 : {
256 : return OOMatrixForTranslationComponents(v.x, v.y, v.z);
257 : }
258 :
259 :
260 : OOINLINE OOMatrix OOMatrixTranslateComponents(OOMatrix m, OOScalar dx, OOScalar dy, OOScalar dz)
261 : {
262 : m.m[3][0] += dx;
263 : m.m[3][1] += dy;
264 : m.m[3][2] += dz;
265 : return m;
266 : }
267 :
268 :
269 : OOINLINE OOMatrix OOMatrixTranslate(OOMatrix m, Vector offset)
270 : {
271 : return OOMatrixTranslateComponents(m, offset.x, offset.y, offset.z);
272 : }
273 :
274 : OOINLINE OOMatrix OOMatrixHPTranslate(OOMatrix m, HPVector offset)
275 : {
276 : return OOMatrixTranslateComponents(m, (OOScalar)offset.x, (OOScalar)offset.y, (OOScalar)offset.z);
277 : }
278 :
279 :
280 : OOINLINE OOMatrix OOMatrixForScale(OOScalar sx, OOScalar sy, OOScalar sz)
281 : {
282 : return OOMatrixConstruct
283 : (
284 : sx, 0, 0, 0,
285 : 0, sy, 0, 0,
286 : 0, 0, sz, 0,
287 : 0, 0, 0, 1
288 : );
289 : }
290 :
291 :
292 : OOINLINE OOMatrix OOMatrixForScaleUniform(OOScalar s)
293 : {
294 : return OOMatrixForScale(s, s, s);
295 : }
296 :
297 :
298 : OOINLINE OOMatrix OOMatrixScale(OOMatrix m, OOScalar sx, OOScalar sy, OOScalar sz)
299 : {
300 : return OOMatrixMultiply(m, OOMatrixForScale(sx, sy, sz));
301 : }
302 :
303 :
304 : OOINLINE OOMatrix OOMatrixScaleUniform(OOMatrix m, OOScalar s)
305 : {
306 : return OOMatrixScale(m, s, s, s);
307 : }
308 :
309 :
310 : OOINLINE OOMatrix OOMatrixRotateX(OOMatrix m, OOScalar angle)
311 : {
312 : return OOMatrixMultiply(m, OOMatrixForRotationX(angle));
313 : }
314 :
315 :
316 : OOINLINE OOMatrix OOMatrixRotateY(OOMatrix m, OOScalar angle)
317 : {
318 : return OOMatrixMultiply(m, OOMatrixForRotationY(angle));
319 : }
320 :
321 :
322 : OOINLINE OOMatrix OOMatrixRotateZ(OOMatrix m, OOScalar angle)
323 : {
324 : return OOMatrixMultiply(m, OOMatrixForRotationZ(angle));
325 : }
326 :
327 :
328 : OOINLINE OOMatrix OOMatrixRotate(OOMatrix m, Vector axis, OOScalar angle)
329 : {
330 : return OOMatrixMultiply(m, OOMatrixForRotation(axis, angle));
331 : }
332 :
333 :
334 : OOINLINE OOMatrix OOMatrixRotateQuaternion(OOMatrix m, Quaternion quat)
335 : {
336 : return OOMatrixMultiply(m, OOMatrixForQuaternionRotation(quat));
337 : }
338 :
339 :
340 : OOINLINE bool OOMatrixIsIdentity(OOMatrix m)
341 : {
342 : return OOMatrixEqual(m, kIdentityMatrix);
343 : }
344 :
345 :
346 : OOINLINE void OOMatrixGetBasisVectors(OOMatrix m, Vector *outRight, Vector *outUp, Vector *outForward)
347 : {
348 : assert(outRight != NULL && outUp != NULL && outForward != NULL);
349 :
350 : *outRight = make_vector(m.m[0][0], m.m[1][0], m.m[2][0]);
351 : *outUp = make_vector(m.m[0][1], m.m[1][1], m.m[2][1]);
352 : *outForward = make_vector(m.m[0][2], m.m[1][2], m.m[2][2]);
353 : }
354 :
355 : OOINLINE OOMatrix OOMatrixTranspose(OOMatrix m)
356 : {
357 : return OOMatrixConstruct
358 : (
359 : m.m[0][0], m.m[1][0], m.m[2][0], m.m[3][0],
360 : m.m[0][1], m.m[1][1], m.m[2][1], m.m[3][1],
361 : m.m[0][2], m.m[1][2], m.m[2][2], m.m[3][2],
362 : m.m[0][3], m.m[1][3], m.m[2][3], m.m[3][3]
363 : );
364 : }
365 :
366 :
367 : #if OOMATHS_OPENGL_INTEGRATION
368 : OOINLINE OOMatrix OOMatrixLoadGLMatrix(GLenum matrixID)
369 : {
370 : OOMatrix m;
371 : glGetFloatv(matrixID, OOMatrixValuesForOpenGL(m));
372 : return m;
373 : }
374 : #endif
375 :
376 : #endif /* INCLUDED_OOMATHS_h */
|