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