Tiberian Technologies Scripts Reference Revision: 9000
Loading...
Searching...
No Matches
matrix4.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__MATRIX4_H
13#define TT_INCLUDE__MATRIX4_H
14#include "Vector4.h"
15#include "Vector3.h"
16#include "Matrix3D.h"
17#include "Matrix3.h"
18#include "plane.h"
19class SCRIPTS_API Matrix4 {
20public:
21 static const Matrix4 IDENTITY;
22 TT_INLINE Matrix4(void)
23 {
24 }
25 TT_INLINE Matrix4(const Matrix4 & m)
26 {
27 Row[0] = m.Row[0]; Row[1] = m.Row[1]; Row[2] = m.Row[2]; Row[3] = m.Row[3];
28 }
29 TT_INLINE explicit Matrix4(bool identity)
30 {
31 if (identity)
32 {
33 Make_Identity();
34 }
35 }
36 TT_INLINE explicit Matrix4(const Matrix3D & m)
37 {
38 Init(m);
39 }
40 TT_INLINE explicit Matrix4(const Vector4 & v0, const Vector4 & v1, const Vector4 & v2, const Vector4 & v3) {
41 Init(v0,v1,v2,v3);
42 }
43 TT_INLINE void Make_Identity(void)
44 {
45 Row[0].Set(1.0,0.0,0.0,0.0);
46 Row[1].Set(0.0,1.0,0.0,0.0);
47 Row[2].Set(0.0,0.0,1.0,0.0);
48 Row[3].Set(0.0,0.0,0.0,1.0);
49 }
50 TT_INLINE void Init(const Matrix3D & m)
51 {
52 Row[0] = m[0]; Row[1] = m[1]; Row[2] = m[2]; Row[3] = Vector4(0.0,0.0,0.0,1.0);
53 }
54 TT_INLINE void Init(const Vector4 & v0, const Vector4 & v1, const Vector4 & v2, const Vector4 & v3)
55 {
56 Row[0] = v0; Row[1] = v1; Row[2] = v2; Row[3] = v3;
57 }
58 TT_INLINE void Init_Ortho_OGL(float left,float right,float bottom,float top,float znear,float zfar)
59 {
60 Make_Identity();
61 Row[0][0] = 2.0f / (right - left);
62 Row[0][3] = -(right + left) / (right - left);
63 Row[1][1] = 2.0f / (top - bottom);
64 Row[1][3] = -(top + bottom) / (top - bottom);
65 Row[2][2] = -2.0f / (zfar - znear);
66 Row[2][3] = -(zfar + znear) / (zfar - znear);
67
68 }
69 TT_INLINE void Init_Perspective_OGL(float hfov,float vfov,float znear,float zfar)
70 {
71 Make_Identity();
72 Row[0][0] = static_cast<float>(1.0 / tan(hfov*0.5));
73 Row[1][1] = static_cast<float>(1.0 / tan(vfov*0.5));
74 Row[2][2] = -(zfar + znear) / (zfar - znear);
75 Row[2][3] = static_cast<float>(-(2.0*zfar*znear) / (zfar - znear));
76 Row[3][2] = -1.0f;
77 Row[3][3] = 0.0f;
78 }
79 TT_INLINE void Init_Perspective_OGL(float left,float right,float bottom,float top,float znear,float zfar)
80 {
81 Make_Identity();
82 Row[0][0] = static_cast<float>(2.0*znear / (right - left));
83 Row[0][2] = (right + left) / (right - left);
84 Row[1][1] = static_cast<float>(2.0*znear / (top - bottom));
85 Row[1][2] = (top + bottom) / (top - bottom);
86 Row[2][2] = -(zfar + znear) / (zfar - znear);
87 Row[2][3] = static_cast<float>(-(2.0*zfar*znear) / (zfar - znear));
88 Row[3][2] = -1.0f;
89 Row[3][3] = 0.0f;
90 }
91 TT_INLINE void Init_Ortho(float left,float right,float bottom,float top,float znear,float zfar)
92 {
93 Make_Identity();
94 Row[0][0] = 2.0f / (right - left);
95 Row[0][3] = (left + right) / (left - right);
96 Row[1][1] = 2.0f / (top - bottom);
97 Row[1][3] = (top + bottom) / (bottom - top);
98 Row[2][2] = 1.0f / (znear - zfar);
99 Row[2][3] = znear / (znear - zfar);
100
101 }
102 TT_INLINE void Init_Perspective(float left,float right,float bottom,float top,float znear,float zfar)
103 {
104 Make_Identity();
105 Row[0][0] = static_cast<float>(2.0*znear / (right - left));
106 Row[0][2] = (right + left) / (right - left);
107 Row[1][1] = static_cast<float>(2.0*znear / (top - bottom));
108 Row[1][2] = (top + bottom) / (top - bottom);
109 Row[2][2] = zfar / (znear - zfar);
110 Row[2][3] = (znear * zfar) / (znear - zfar);
111 Row[3][2] = -1.0f;
112 Row[3][3] = 0.0f;
113 }
114
115 TT_INLINE Vector4 & operator [] (int i) { return Row[i]; }
116 TT_INLINE const Vector4 & operator [] (int i) const { return Row[i]; }
117 TT_INLINE Matrix4 Transpose(void) const
118 {
119 return Matrix4(Vector4(Row[0][0], Row[1][0], Row[2][0], Row[3][0]),Vector4(Row[0][1], Row[1][1], Row[2][1], Row[3][1]),Vector4(Row[0][2], Row[1][2], Row[2][2], Row[3][2]),Vector4(Row[0][3], Row[1][3], Row[2][3], Row[3][3]));
120 }
121 TT_INLINE float Determinant() const
122 {
123 float det;
124 det = (Row[0].X * Row[1].Y - Row[0].Y * Row[1].X) * (Row[2].Z * Row[3].W - Row[2].W * Row[3].Z);
125 det -= (Row[0].X * Row[1].Z - Row[0].Z * Row[1].X) * (Row[2].Y * Row[3].W - Row[2].W * Row[3].Y);
126 det += (Row[0].X * Row[1].W - Row[0].W * Row[1].X) * (Row[2].Y * Row[3].Z - Row[2].Z * Row[3].Y);
127 det += (Row[0].Y * Row[1].Z - Row[0].Z * Row[1].Y) * (Row[2].X * Row[3].W - Row[2].W * Row[3].X);
128 det -= (Row[0].Y * Row[1].W - Row[0].W * Row[1].Y) * (Row[2].X * Row[3].Z - Row[2].Z * Row[3].X);
129 det += (Row[0].Z * Row[1].W - Row[0].W * Row[1].Z) * (Row[2].X * Row[3].Y - Row[2].Y * Row[3].X);
130 return det;
131 };
132 TT_INLINE Matrix4 Inverse(void) const
133 {
134 float s = Determinant();
135 if (s == 0.0) return Matrix4();
136 s = 1/s;
137 Matrix4 t;
138 t.Row[0].X = s*(Row[1].Y*(Row[2].Z*Row[3].W - Row[2].W*Row[3].Z) + Row[1].Z*(Row[2].W*Row[3].Y - Row[2].Y*Row[3].W) + Row[1].W*(Row[2].Y*Row[3].Z - Row[2].Z*Row[3].Y));
139 t.Row[0].Y = s*(Row[2].Y*(Row[0].Z*Row[3].W - Row[0].W*Row[3].Z) + Row[2].Z*(Row[0].W*Row[3].Y - Row[0].Y*Row[3].W) + Row[2].W*(Row[0].Y*Row[3].Z - Row[0].Z*Row[3].Y));
140 t.Row[0].Z = s*(Row[3].Y*(Row[0].Z*Row[1].W - Row[0].W*Row[1].Z) + Row[3].Z*(Row[0].W*Row[1].Y - Row[0].Y*Row[1].W) + Row[3].W*(Row[0].Y*Row[1].Z - Row[0].Z*Row[1].Y));
141 t.Row[0].W = s*(Row[0].Y*(Row[1].W*Row[2].Z - Row[1].Z*Row[2].W) + Row[0].Z*(Row[1].Y*Row[2].W - Row[1].W*Row[2].Y) + Row[0].W*(Row[1].Z*Row[2].Y - Row[1].Y*Row[2].Z));
142 t.Row[1].X = s*(Row[1].Z*(Row[2].X*Row[3].W - Row[2].W*Row[3].X) + Row[1].W*(Row[2].Z*Row[3].X - Row[2].X*Row[3].Z) + Row[1].X*(Row[2].W*Row[3].Z - Row[2].Z*Row[3].W));
143 t.Row[1].Y = s*(Row[2].Z*(Row[0].X*Row[3].W - Row[0].W*Row[3].X) + Row[2].W*(Row[0].Z*Row[3].X - Row[0].X*Row[3].Z) + Row[2].X*(Row[0].W*Row[3].Z - Row[0].Z*Row[3].W));
144 t.Row[1].Z = s*(Row[3].Z*(Row[0].X*Row[1].W - Row[0].W*Row[1].X) + Row[3].W*(Row[0].Z*Row[1].X - Row[0].X*Row[1].Z) + Row[3].X*(Row[0].W*Row[1].Z - Row[0].Z*Row[1].W));
145 t.Row[1].W = s*(Row[0].Z*(Row[1].W*Row[2].X - Row[1].X*Row[2].W) + Row[0].W*(Row[1].X*Row[2].Z - Row[1].Z*Row[2].X) + Row[0].X*(Row[1].Z*Row[2].W - Row[1].W*Row[2].Z));
146 t.Row[2].X = s*(Row[1].W*(Row[2].X*Row[3].Y - Row[2].Y*Row[3].X) + Row[1].X*(Row[2].Y*Row[3].W - Row[2].W*Row[3].Y) + Row[1].Y*(Row[2].W*Row[3].X - Row[2].X*Row[3].W));
147 t.Row[2].Y = s*(Row[2].W*(Row[0].X*Row[3].Y - Row[0].Y*Row[3].X) + Row[2].X*(Row[0].Y*Row[3].W - Row[0].W*Row[3].Y) + Row[2].Y*(Row[0].W*Row[3].X - Row[0].X*Row[3].W));
148 t.Row[2].Z = s*(Row[3].W*(Row[0].X*Row[1].Y - Row[0].Y*Row[1].X) + Row[3].X*(Row[0].Y*Row[1].W - Row[0].W*Row[1].Y) + Row[3].Y*(Row[0].W*Row[1].X - Row[0].X*Row[1].W));
149 t.Row[2].W = s*(Row[0].W*(Row[1].Y*Row[2].X - Row[1].X*Row[2].Y) + Row[0].X*(Row[1].W*Row[2].Y - Row[1].Y*Row[2].W) + Row[0].Y*(Row[1].X*Row[2].W - Row[1].W*Row[2].X));
150 t.Row[3].X = s*(Row[1].X*(Row[2].Z*Row[3].Y - Row[2].Y*Row[3].Z) + Row[1].Y*(Row[2].X*Row[3].Z - Row[2].Z*Row[3].X) + Row[1].Z*(Row[2].Y*Row[3].X - Row[2].X*Row[3].Y));
151 t.Row[3].Y = s*(Row[2].X*(Row[0].Z*Row[3].Y - Row[0].Y*Row[3].Z) + Row[2].Y*(Row[0].X*Row[3].Z - Row[0].Z*Row[3].X) + Row[2].Z*(Row[0].Y*Row[3].X - Row[0].X*Row[3].Y));
152 t.Row[3].Z = s*(Row[3].X*(Row[0].Z*Row[1].Y - Row[0].Y*Row[1].Z) + Row[3].Y*(Row[0].X*Row[1].Z - Row[0].Z*Row[1].X) + Row[3].Z*(Row[0].Y*Row[1].X - Row[0].X*Row[1].Y));
153 t.Row[3].W = s*(Row[0].X*(Row[1].Y*Row[2].Z - Row[1].Z*Row[2].Y) + Row[0].Y*(Row[1].Z*Row[2].X - Row[1].X*Row[2].Z) + Row[0].Z*(Row[1].X*Row[2].Y - Row[1].Y*Row[2].X));
154 return t;
155 }
156 TT_INLINE Matrix4 & operator = (const Matrix4 & m)
157 {
158 Row[0] = m.Row[0]; Row[1] = m.Row[1]; Row[2] = m.Row[2]; Row[3] = m.Row[3];
159 return *this;
160 }
161 TT_INLINE Matrix4 & operator += (const Matrix4 & m)
162 {
163 Row[0] += m.Row[0]; Row[1] += m.Row[1]; Row[2] += m.Row[2]; Row[3] += m.Row[3];
164 return *this;
165 }
166 TT_INLINE Matrix4 & operator -= (const Matrix4 & m)
167 {
168 Row[0] -= m.Row[0]; Row[1] -= m.Row[1]; Row[2] -= m.Row[2]; Row[3] -= m.Row[3];
169 return *this;
170 }
171 TT_INLINE Matrix4 & operator *= (float d)
172 {
173 Row[0] *= d; Row[1] *= d; Row[2] *= d; Row[3] *= d;
174 return *this;
175 }
176 TT_INLINE Matrix4 & operator /= (float d)
177 {
178 float ood = d;
179 Row[0] *= ood; Row[1] *= ood; Row[2] *= ood; Row[3] *= ood;
180 return *this;
181 }
182 friend Matrix4 operator - (const Matrix4& a);
183 friend Matrix4 operator * (const Matrix4& a,float d);
184 friend Matrix4 operator * (float d,const Matrix4& a);
185 friend Matrix4 operator / (const Matrix4& a,float d);
186 friend Matrix4 operator + (const Matrix4& a, const Matrix4& b);
187 friend Matrix4 Add(const Matrix4& a);
188 friend Matrix4 operator - (const Matrix4 & a, const Matrix4 & b);
189 friend Matrix4 Subtract(const Matrix4 & a, const Matrix4 & b);
190 friend Matrix4 operator * (const Matrix4 & a, const Matrix4 & b);
191 friend Matrix4 Multiply(const Matrix4 & a, const Matrix4 & b);
192 friend Matrix4 operator * (const Matrix4 & a, const Matrix3D & b);
193 friend Matrix4 operator * (const Matrix3D & a, const Matrix4 & b);
194 friend int operator == (const Matrix4 & a, const Matrix4 & b);
195 friend int operator != (const Matrix4 & a, const Matrix4 & b);
196 friend void Swap(Matrix4 & a,Matrix4 & b);
197 friend Vector4 operator * (const Matrix4 & a, const Vector4 & v);
198 friend Vector4 operator * (const Matrix4 & a, const Vector3 & v);
199 static void Multiply(const Matrix4 &A,const Matrix4 &B,Matrix4 * set_result);
200 static void Multiply(const Matrix3D &A,const Matrix4 &B,Matrix4 * set_result);
201 static void Multiply(const Matrix4 &A,const Matrix3D &B,Matrix4 * set_result);
202 TT_INLINE static void Transform_Vector(const Matrix4 &A,const Vector3 & in,Vector3 * out)
203 {
204 Vector3 tmp;
205 Vector3 *v;
206 if (out == &in)
207 {
208 tmp = in;
209 v = &tmp;
210 }
211 else
212 {
213 v = (Vector3 *)&in;
214 }
215 out->X = (A[0][0] * v->X + A[0][1] * v->Y + A[0][2] * v->Z + A[0][3]);
216 out->Y = (A[1][0] * v->X + A[1][1] * v->Y + A[1][2] * v->Z + A[1][3]);
217 out->Z = (A[2][0] * v->X + A[2][1] * v->Y + A[2][2] * v->Z + A[2][3]);
218 }
219 TT_INLINE static void Transform_Vector(const Matrix4 &A,const Vector3 & in,Vector4 * out)
220 {
221 out->X = (A[0][0] * in.X + A[0][1] * in.Y + A[0][2] * in.Z + A[0][3]);
222 out->Y = (A[1][0] * in.X + A[1][1] * in.Y + A[1][2] * in.Z + A[1][3]);
223 out->Z = (A[2][0] * in.X + A[2][1] * in.Y + A[2][2] * in.Z + A[2][3]);
224 out->W = 1.0f;
225 }
226 TT_INLINE static void Transform_Vector(const Matrix4 &A,const Vector4 & in,Vector4 * out)
227 {
228 Vector4 tmp;
229 Vector4 * v;
230 if (out == &in)
231 {
232 tmp = in;
233 v = &tmp;
234 }
235 else
236 {
237 v = (Vector4 *)&in;
238 }
239 out->X = (A[0][0] * v->X + A[0][1] * v->Y + A[0][2] * v->Z + A[0][3] * v->W);
240 out->Y = (A[1][0] * v->X + A[1][1] * v->Y + A[1][2] * v->Z + A[1][3] * v->W);
241 out->Z = (A[2][0] * v->X + A[2][1] * v->Y + A[2][2] * v->Z + A[2][3] * v->W);
242 out->W = (A[3][0] * v->X + A[3][1] * v->Y + A[3][2] * v->Z + A[3][3] * v->W);
243 }
244 static Matrix4 ReflectPlane(const PlaneClass& plane); // Expects Ax + By + Cz + D = 0, not WW convention
245protected:
246 Vector4 Row[4];
247};
248TT_INLINE Matrix4 operator - (const Matrix4 & a)
249{
250 return Matrix4(-a.Row[0], -a.Row[1], -a.Row[2], -a.Row[3]);
251}
252
253TT_INLINE Matrix4 operator * (const Matrix4 & a, float d)
254{
255 return Matrix4(a.Row[0] * d, a.Row[1] * d, a.Row[2] * d, a.Row[3] * d);
256}
257
258TT_INLINE Matrix4 operator * (float d, const Matrix4 & a)
259{
260 return a*d;
261}
262
263TT_INLINE Matrix4 operator / (const Matrix4 & a, float d)
264{
265 float ood = 1.0f / d;
266 return Matrix4(a.Row[0] * ood, a.Row[1] * ood, a.Row[2] * ood, a.Row[3] * ood);
267}
268TT_INLINE Matrix4 operator + (const Matrix4 & a, const Matrix4 & b)
269{
270 return Matrix4(a.Row[0] + b.Row[0],a.Row[1] + b.Row[1],a.Row[2] + b.Row[2],a.Row[3] + b.Row[3]);
271}
272TT_INLINE Matrix4 Add(const Matrix4 & a, const Matrix4 & b)
273{
274 return a+b;
275}
276TT_INLINE Matrix4 operator - (const Matrix4 & a, const Matrix4 & b)
277{
278 return Matrix4(a.Row[0] - b.Row[0],a.Row[1] - b.Row[1],a.Row[2] - b.Row[2],a.Row[3] - b.Row[3]);
279}
280TT_INLINE Matrix4 Subtract(const Matrix4 & a, const Matrix4 & b)
281{
282 return a-b;
283}
284TT_INLINE Matrix4 operator * (const Matrix4 & a, const Matrix4 & b)
285{
286 #define ROWCOL(i, j) a[i][0]*b[0][j] + a[i][1]*b[1][j] + a[i][2]*b[2][j] + a[i][3]*b[3][j]
287 return Matrix4(Vector4(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2), ROWCOL(0,3)),Vector4(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2), ROWCOL(1,3)),Vector4(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2), ROWCOL(2,3)),Vector4(ROWCOL(3,0), ROWCOL(3,1), ROWCOL(3,2), ROWCOL(3,3)));
288 #undef ROWCOL
289}
290TT_INLINE Matrix4 Multiply(const Matrix4 & a, const Matrix4 & b)
291{
292 return a*b;
293}
294TT_INLINE Matrix4 operator * (const Matrix4 & a, const Matrix3D & b)
295{
296 #define ROWCOL(i,j) a[i][0]*b[0][j] + a[i][1]*b[1][j] + a[i][2]*b[2][j]
297 #define ROWCOL_LAST(i,j) a[i][0]*b[0][j] + a[i][1]*b[1][j] + a[i][2]*b[2][j] + a[i][3]
298 return Matrix4(Vector4(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2), ROWCOL_LAST(0,3)),Vector4(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2), ROWCOL_LAST(1,3)),Vector4(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2), ROWCOL_LAST(2,3)),Vector4(ROWCOL(3,0), ROWCOL(3,1), ROWCOL(3,2), ROWCOL_LAST(3,3)));
299 #undef ROWCOL
300 #undef ROWCOL_LAST
301}
302TT_INLINE Matrix4 operator * (const Matrix3D & a, const Matrix4 & b)
303{
304 #define ROWCOL(i,j) a[i][0]*b[0][j] + a[i][1]*b[1][j] + a[i][2]*b[2][j] + a[i][3]*b[3][j]
305 return Matrix4(Vector4(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2), ROWCOL(0,3)),Vector4(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2), ROWCOL(1,3)),Vector4(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2), ROWCOL(2,3)),Vector4(b[3][0], b[3][1], b[3][2], b[3][3]));
306 #undef ROWCOL
307}
308TT_INLINE Vector4 operator * (const Matrix4 & a, const Vector3 & v)
309{
310 return Vector4(a[0][0] * v[0] + a[0][1] * v[1] + a[0][2] * v[2] + a[0][3] * 1.0f,a[1][0] * v[0] + a[1][1] * v[1] + a[1][2] * v[2] + a[1][3] * 1.0f,a[2][0] * v[0] + a[2][1] * v[1] + a[2][2] * v[2] + a[2][3] * 1.0f,a[3][0] * v[0] + a[3][1] * v[1] + a[3][2] * v[2] + a[3][3] * 1.0f);
311}
312TT_INLINE Vector4 operator * (const Matrix4 & a, const Vector4 & v)
313{
314 return Vector4(a[0][0] * v[0] + a[0][1] * v[1] + a[0][2] * v[2] + a[0][3] * v[3],a[1][0] * v[0] + a[1][1] * v[1] + a[1][2] * v[2] + a[1][3] * v[3],a[2][0] * v[0] + a[2][1] * v[1] + a[2][2] * v[2] + a[2][3] * v[3],a[3][0] * v[0] + a[3][1] * v[1] + a[3][2] * v[2] + a[3][3] * v[3]);
315}
316#endif