Tiberian Technologies Scripts Reference Revision: 9000
Loading...
Searching...
No Matches
Matrix3.h
1/* Renegade Scripts.dll
2 Copyright 2013 Tiberian Technologies
3
4 This file is part of the Renegade scripts.dll
5 The Renegade scripts.dll is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 2, or (at your option) any later
8 version. See the file COPYING for more details.
9 In addition, an exemption is given to allow Run Time Dynamic Linking of this code with any closed source module that does not contain code covered by this licence.
10 Only the source code to the module(s) containing the licenced code has to be released.
11*/
12#ifndef TT_INCLUDE__MATRIX3_H
13#define TT_INCLUDE__MATRIX3_H
14#include "Vector3.h"
15#include "Matrix3D.h"
16#include "Matrix4.h"
17class Matrix4;
18class SCRIPTS_API Matrix3
19{
20public:
21 TT_INLINE Matrix3(void) {};
22 TT_INLINE Matrix3(const Matrix3 & m)
23 {
24 Row[0] = m.Row[0]; Row[1] = m.Row[1]; Row[2] = m.Row[2];
25 }
26 TT_INLINE explicit Matrix3(bool identity)
27 {
28 if (identity)
29 {
30 Row[0].Set(1.0,0.0,0.0);
31 Row[1].Set(0.0,1.0,0.0);
32 Row[2].Set(0.0,0.0,1.0);
33 }
34 }
35 TT_INLINE explicit Matrix3(const Vector3 & v0, const Vector3 & v1, const Vector3 & v2)
36 {
37 Row[0] = v0;
38 Row[1] = v1;
39 Row[2] = v2;
40 }
41 explicit Matrix3(const Matrix3D & m);
42 explicit Matrix3(const Matrix4 & m);
43 TT_INLINE explicit Matrix3(float m11,float m12,float m13,float m21,float m22,float m23,float m31,float m32,float m33)
44 {
45 Row[0].Set(m11,m12,m13);
46 Row[1].Set(m21,m22,m23);
47 Row[2].Set(m31,m32,m33);
48 }
49 TT_INLINE explicit Matrix3(const Vector3 & axis,float angle)
50 {
51 Set(axis,angle);
52 }
53 TT_INLINE explicit Matrix3(const Vector3 & axis,float s_angle,float c_angle)
54 {
55 Set(axis,s_angle,c_angle);
56 }
57 TT_INLINE Matrix3(const Quaternion & q)
58 {
59 this->Set(q);
60 }
61 void Set(const Matrix3D & m);
62 void Set(const Matrix4 & m);
63 TT_INLINE void Set(const Vector3 & v0, const Vector3 & v1, const Vector3 & v2)
64 {
65 Row[0] = v0;
66 Row[1] = v1;
67 Row[2] = v2;
68 }
69 TT_INLINE void Set(float m11,float m12,float m13,float m21,float m22,float m23,float m31,float m32,float m33)
70 {
71 Row[0].Set(m11,m12,m13);
72 Row[1].Set(m21,m22,m23);
73 Row[2].Set(m31,m32,m33);
74 }
75 TT_INLINE void Set(const Vector3 & axis,float angle)
76 {
77 Set(axis,sinf(angle),cosf(angle));
78 }
79 TT_INLINE void Set(const Vector3 & axis,float s,float c)
80 {
81 Row[0].Set(
82 (float)(axis[0]*axis[0] + c*(1.0f - axis[0]*axis[0])),
83 (float)(axis[0]*axis[1]*(1.0f - c) - axis[2]*s),
84 (float)(axis[2]*axis[0]*(1.0f - c) + axis[1]*s)
85 );
86 Row[1].Set(
87 (float)(axis[0]*axis[1]*(1.0f - c) + axis[2]*s),
88 (float)(axis[1]*axis[1] + c*(1.0f - axis[1]*axis[1])),
89 (float)(axis[1]*axis[2]*(1.0f - c) - axis[0]*s)
90 );
91 Row[2].Set(
92 (float)(axis[2]*axis[0]*(1.0f - c) - axis[1]*s),
93 (float)(axis[1]*axis[2]*(1.0f - c) + axis[0]*s),
94 (float)(axis[2]*axis[2] + c*(1 - axis[2]*axis[2]))
95 );
96 }
97 void Set(const Quaternion & q);
98 TT_INLINE Vector3 & operator [] (int i) { return Row[i]; }
99 TT_INLINE const Vector3 & operator [] (int i) const { return Row[i]; }
100 TT_INLINE Matrix3 Transpose (void) const
101 {
102 return Matrix3(
103 Vector3(Row[0][0], Row[1][0], Row[2][0]),
104 Vector3(Row[0][1], Row[1][1], Row[2][1]),
105 Vector3(Row[0][2], Row[1][2], Row[2][2])
106 );
107 }
108 TT_INLINE float Determinant (void) const
109 {
110 return Row[0][0] * (Row[1][1] * Row[2][2] - Row[1][2] * Row[2][1])
111 - Row[0][1] * (Row[1][0] * Row[2][2] - Row[1][2] * Row[2][0])
112 - Row[0][2] * (Row[1][0] * Row[2][1] - Row[1][1] * Row[2][0]);
113 }
114 TT_INLINE Matrix3 & operator = (const Matrix3 & m)
115 {
116 Row[0] = m.Row[0]; Row[1] = m.Row[1]; Row[2] = m.Row[2];
117 return *this;
118 }
119 Matrix3 & operator = (const Matrix3D & m);
120 Matrix3 & operator = (const Matrix4 & m);
121 TT_INLINE Matrix3 & operator += (const Matrix3 & m)
122 {
123 Row[0] += m.Row[0]; Row[1] += m.Row[1]; Row[2] += m.Row[2];
124 return *this;
125 }
126 TT_INLINE Matrix3 & operator -= (const Matrix3 & m)
127 {
128 Row[0] -= m.Row[0]; Row[1] -= m.Row[1]; Row[2] -= m.Row[2];
129 return *this;
130 }
131 TT_INLINE Matrix3 & operator *= (float d)
132 {
133 Row[0] *= d; Row[1] *= d; Row[2] *= d;
134 return *this;
135 }
136 TT_INLINE Matrix3 & operator /= (float d)
137 {
138 Row[0] /= d; Row[1] /= d; Row[2] /= d;
139 return *this;
140 }
141 TT_INLINE void Make_Identity(void)
142 {
143 Row[0].Set(1.0f,0.0f,0.0f);
144 Row[1].Set(0.0f,1.0f,0.0f);
145 Row[2].Set(0.0f,0.0f,1.0f);
146 }
147 TT_INLINE void Rotate_X(float theta)
148 {
149 Rotate_X(sinf(theta),cosf(theta));
150 }
151 TT_INLINE void Rotate_X(float s,float c)
152 {
153 float tmp1,tmp2;
154 tmp1 = Row[0][1]; tmp2 = Row[0][2];
155 Row[0][1] = (float)( c*tmp1 + s*tmp2);
156 Row[0][2] = (float)(-s*tmp1 + c*tmp2);
157 tmp1 = Row[1][1]; tmp2 = Row[1][2];
158 Row[1][1] = (float)( c*tmp1 + s*tmp2);
159 Row[1][2] = (float)(-s*tmp1 + c*tmp2);
160 tmp1 = Row[2][1]; tmp2 = Row[2][2];
161 Row[2][1] = (float)( c*tmp1 + s*tmp2);
162 Row[2][2] = (float)(-s*tmp1 + c*tmp2);
163 }
164 TT_INLINE void Rotate_Y(float theta)
165 {
166 Rotate_Y(sinf(theta),cosf(theta));
167 }
168 TT_INLINE void Rotate_Y(float s,float c)
169 {
170 float tmp1,tmp2;
171 tmp1 = Row[0][0]; tmp2 = Row[0][2];
172 Row[0][0] = (float)(c*tmp1 - s*tmp2);
173 Row[0][2] = (float)(s*tmp1 + c*tmp2);
174 tmp1 = Row[1][0]; tmp2 = Row[1][2];
175 Row[1][0] = (float)(c*tmp1 - s*tmp2);
176 Row[1][2] = (float)(s*tmp1 + c*tmp2);
177 tmp1 = Row[2][0]; tmp2 = Row[2][2];
178 Row[2][0] = (float)(c*tmp1 - s*tmp2);
179 Row[2][2] = (float)(s*tmp1 + c*tmp2);
180 }
181 TT_INLINE void Rotate_Z(float theta)
182 {
183 Rotate_Z(sinf(theta),cosf(theta));
184 }
185 TT_INLINE void Rotate_Z(float s,float c)
186 {
187 float tmp1,tmp2;
188 tmp1 = Row[0][0]; tmp2 = Row[0][1];
189 Row[0][0] = (float)( c*tmp1 + s*tmp2);
190 Row[0][1] = (float)(-s*tmp1 + c*tmp2);
191 tmp1 = Row[1][0]; tmp2 = Row[1][1];
192 Row[1][0] = (float)( c*tmp1 + s*tmp2);
193 Row[1][1] = (float)(-s*tmp1 + c*tmp2);
194 tmp1 = Row[2][0]; tmp2 = Row[2][1];
195 Row[2][0] = (float)( c*tmp1 + s*tmp2);
196 Row[2][1] = (float)(-s*tmp1 + c*tmp2);
197 }
198 TT_INLINE float Get_X_Rotation(void) const
199 {
200 Vector3 v = (*this) * Vector3(0.0,1.0,0.0);
201 return atan2(v[2], v[1]);
202 }
203 TT_INLINE float Get_Y_Rotation(void) const
204 {
205 Vector3 v = (*this) * Vector3(0.0,0.0,1.0);
206 return atan2(v[0],v[2]);
207 }
208 TT_INLINE float Get_Z_Rotation(void) const
209 {
210 Vector3 v = (*this) * Vector3(1.0,0.0,0.0);
211 return atan2(v[1],v[0]);
212 }
213 TT_INLINE Vector3 Get_X_Vector(void) const
214 {
215 return Vector3(Row[0][0], Row[1][0], Row[2][0]);
216 }
217 TT_INLINE Vector3 Get_Y_Vector(void) const
218 {
219 return Vector3(Row[0][1], Row[1][1], Row[2][1]);
220 }
221 TT_INLINE Vector3 Get_Z_Vector(void) const
222 {
223 return Vector3(Row[0][2], Row[1][2], Row[2][2]);
224 }
225 TT_INLINE void Get_X_Vector(Vector3 * set_x) const
226 {
227 set_x->Set(Row[0][0], Row[1][0], Row[2][0]);
228 }
229 TT_INLINE void Get_Y_Vector(Vector3 * set_y) const
230 {
231 set_y->Set(Row[0][1], Row[1][1], Row[2][1]);
232 }
233 TT_INLINE void Get_Z_Vector(Vector3 * set_z) const
234 {
235 set_z->Set(Row[0][2], Row[1][2], Row[2][2]);
236 }
237 friend Matrix3 operator - (const Matrix3& a);
238 friend Matrix3 operator * (const Matrix3& a,float d);
239 friend Matrix3 operator * (float d,const Matrix3& a);
240 friend Matrix3 operator / (const Matrix3& a,float d);
241 friend Matrix3 operator + (const Matrix3& a, const Matrix3& b);
242 friend Matrix3 operator - (const Matrix3 & a, const Matrix3 & b);
243 friend Matrix3 operator * (const Matrix3 & a, const Matrix3 & b);
244 friend Matrix3 operator * (const Matrix3D & a, const Matrix3 & b);
245 friend Matrix3 operator * (const Matrix3 & a, const Matrix3D & b);
246 friend int operator == (const Matrix3 & a, const Matrix3 & b);
247 friend int operator != (const Matrix3 & a, const Matrix3 & b);
248 friend void Swap(Matrix3 & a,Matrix3 & b);
249 friend Vector3 operator * (const Matrix3 & a, const Vector3 & v);
250 TT_INLINE static void Add(const Matrix3 & a, const Matrix3 & b,Matrix3 * res)
251 {
252 Vector3::Add(a.Row[0],b.Row[0],&(res->Row[0]));
253 Vector3::Add(a.Row[1],b.Row[1],&(res->Row[1]));
254 Vector3::Add(a.Row[2],b.Row[2],&(res->Row[2]));
255 }
256 TT_INLINE static void Subtract(const Matrix3 & a, const Matrix3 & b,Matrix3 * res)
257 {
258 Vector3::Subtract(a.Row[0],b.Row[0],&(res->Row[0]));
259 Vector3::Subtract(a.Row[1],b.Row[1],&(res->Row[1]));
260 Vector3::Subtract(a.Row[2],b.Row[2],&(res->Row[2]));
261 }
262 static void Multiply(const Matrix3 & a, const Matrix3 & b,Matrix3 * res);
263 static void Multiply(const Matrix3D & a, const Matrix3 & b,Matrix3 * res);
264 static void Multiply(const Matrix3 & a, const Matrix3D & b,Matrix3 * res);
265 TT_INLINE static void Rotate_Vector(const Matrix3 & A,const Vector3 & in,Vector3 * out)
266 {
267 Vector3 tmp;
268 Vector3 * v;
269 if (out == &in)
270 {
271 tmp = in;
272 v = &tmp;
273 }
274 else
275 {
276 v = (Vector3 *)∈
277 }
278 out->X = (A[0][0] * v->X + A[0][1] * v->Y + A[0][2] * v->Z);
279 out->Y = (A[1][0] * v->X + A[1][1] * v->Y + A[1][2] * v->Z);
280 out->Z = (A[2][0] * v->X + A[2][1] * v->Y + A[2][2] * v->Z);
281 }
282 TT_INLINE static void Transpose_Rotate_Vector(const Matrix3 & A,const Vector3 & in,Vector3 * out)
283 {
284 Vector3 tmp;
285 Vector3 * v;
286 if (out == &in)
287 {
288 tmp = in;
289 v = &tmp;
290 } else {
291 v = (Vector3 *)∈
292 }
293 out->X = (A[0][0] * v->X + A[1][0] * v->Y + A[2][0] * v->Z);
294 out->Y = (A[0][1] * v->X + A[1][1] * v->Y + A[2][1] * v->Z);
295 out->Z = (A[0][2] * v->X + A[1][2] * v->Y + A[2][2] * v->Z);
296 }
297 TT_INLINE void Rotate_AABox_Extent(const Vector3 & extent,Vector3 * new_extent)
298 {
299 for (int i=0; i<3; i++)
300 {
301 (*new_extent)[i] = 0.0f;
302 for (int j=0; j<3; j++)
303 {
304 (*new_extent)[i] += WWMath::Fabs(Row[i][j] * extent[j]);
305 }
306 }
307 }
308 TT_INLINE Matrix3 Inverse (void) const
309 {
310 Matrix3 a(*this); // As a evolves from original mat into identity
311 Matrix3 b(true); // b evolves from identity into inverse(a)
312 int i, j, i1;
313
314 // Loop over cols of a from left to right, eliminating above and below diagonal
315 for (j=0; j<3; j++) {
316
317 // Find largest pivot in column j among rows j..3
318 i1 = j;
319 for (i=j+1; i<3; i++) {
320 if (WWMath::Fabs(a[i][j]) > WWMath::Fabs(a[i1][j])) {
321 i1 = i;
322 }
323 }
324
325 // Swap rows i1 and j in a and b to put pivot on diagonal
326 Swap(a.Row[i1], a.Row[j]);
327 Swap(b.Row[i1], b.Row[j]);
328
329 // Scale row j to have a unit diagonal
330 if (a[j][j]==0.) {
331 //Matrix3::inverse: singular matrix; can't invert
332 }
333 b.Row[j] /= a.Row[j][j];
334 a.Row[j] /= a.Row[j][j];
335
336 // Eliminate off-diagonal elems in col j of a, doing identical ops to b
337 for (i=0; i<3; i++) {
338 if (i != j) {
339 b.Row[i] -= a[i][j] * b.Row[j];
340 a.Row[i] -= a[i][j] * a.Row[j];
341 }
342 }
343 }
344 return b;
345 }
346 static const Matrix3 Identity;
347protected:
348 Vector3 Row[3];
349};
350TT_INLINE Matrix3 operator - (const Matrix3 & a)
351{
352 return Matrix3(-a.Row[0], -a.Row[1], -a.Row[2]);
353}
354
355TT_INLINE Matrix3 operator * (const Matrix3 & a, float d)
356{
357 return Matrix3(a.Row[0] * d, a.Row[1] * d, a.Row[2] * d);
358}
359
360TT_INLINE Matrix3 operator * (float d, const Matrix3 & a)
361{
362 return a*d;
363}
364
365TT_INLINE Matrix3 operator / (const Matrix3 & a, float d)
366{
367 float ood = 1.0f / d;
368 return Matrix3(a.Row[0] * ood, a.Row[1] * ood, a.Row[2] * ood);
369}
370TT_INLINE Matrix3 operator + (const Matrix3 & a, const Matrix3 & b)
371{
372 return Matrix3(
373 a.Row[0] + b.Row[0],
374 a.Row[1] + b.Row[1],
375 a.Row[2] + b.Row[2]
376 );
377}
378TT_INLINE Matrix3 operator - (const Matrix3 & a, const Matrix3 & b)
379{
380 return Matrix3(
381 a.Row[0] - b.Row[0],
382 a.Row[1] - b.Row[1],
383 a.Row[2] - b.Row[2]
384 );
385}
386TT_INLINE Matrix3 operator * (const Matrix3 & a, const Matrix3 & b)
387{
388 #define ROWCOL(i,j) a[i][0]*b[0][j] + a[i][1]*b[1][j] + a[i][2]*b[2][j]
389 return Matrix3(
390 Vector3(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2) ),
391 Vector3(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2) ),
392 Vector3(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2) )
393 );
394 #undef ROWCOL
395}
396
397TT_INLINE Vector3 operator * (const Matrix3 & a, const Vector3 & v)
398{
399 return Vector3(
400 a[0][0] * v[0] + a[0][1] * v[1] + a[0][2] * v[2],
401 a[1][0] * v[0] + a[1][1] * v[1] + a[1][2] * v[2],
402 a[2][0] * v[0] + a[2][1] * v[1] + a[2][2] * v[2]
403 );
404}
405
406TT_INLINE int operator == (const Matrix3 & a, const Matrix3 & b)
407{
408 return ((a [0] == b [0]) && (a [1] == b [1]) && (a [2] == b [2]));
409}
410
411TT_INLINE int operator != (const Matrix3 & a, const Matrix3 & b)
412{
413 return (!(a == b));
414}
415TT_INLINE Matrix3 Create_X_Rotation_Matrix3(float s,float c)
416{
417 Matrix3 mat;
418 mat[0][0] = 1.0f;
419 mat[0][1] = 0.0f;
420 mat[0][2] = 0.0f;
421 mat[1][0] = 0.0f;
422 mat[1][1] = c;
423 mat[1][2] = -s;
424 mat[2][0] = 0.0f;
425 mat[2][1] = s;
426 mat[2][2] = c;
427 return mat;
428}
429TT_INLINE Matrix3 Create_X_Rotation_Matrix3(float rad)
430{
431 return Create_X_Rotation_Matrix3(sinf(rad),cosf(rad));
432}
433TT_INLINE Matrix3 Create_Y_Rotation_Matrix3(float s,float c)
434{
435 Matrix3 mat;
436 mat[0][0] = c;
437 mat[0][1] = 0.0f;
438 mat[0][2] = s;
439 mat[1][0] = 0.0f;
440 mat[1][1] = 1.0f;
441 mat[1][2] = 0.0f;
442 mat[2][0] = -s;
443 mat[2][1] = 0.0f;
444 mat[2][2] = c;
445 return mat;
446}
447TT_INLINE Matrix3 Create_Y_Rotation_Matrix3(float rad)
448{
449 return Create_Y_Rotation_Matrix3(sinf(rad),cosf(rad));
450}
451TT_INLINE Matrix3 Create_Z_Rotation_Matrix3(float s,float c)
452{
453 Matrix3 mat;
454 mat[0][0] = c;
455 mat[0][1] = -s;
456 mat[0][2] = 0.0f;
457 mat[1][0] = s;
458 mat[1][1] = c;
459 mat[1][2] = 0.0f;
460 mat[2][0] = 0.0f;
461 mat[2][1] = 0.0f;
462 mat[2][2] = 1.0f;
463 return mat;
464}
465TT_INLINE Matrix3 Create_Z_Rotation_Matrix3(float rad)
466{
467 return Create_Z_Rotation_Matrix3(sinf(rad),cosf(rad));
468}
469#endif