12#ifndef TT_INCLUDE__MATRIX4_H
13#define TT_INCLUDE__MATRIX4_H
19class SCRIPTS_API Matrix4 {
21 static const Matrix4 IDENTITY;
22 TT_INLINE Matrix4(
void)
25 TT_INLINE Matrix4(
const Matrix4 & m)
27 Row[0] = m.Row[0]; Row[1] = m.Row[1]; Row[2] = m.Row[2]; Row[3] = m.Row[3];
29 TT_INLINE
explicit Matrix4(
bool identity)
36 TT_INLINE
explicit Matrix4(
const Matrix3D & m)
40 TT_INLINE
explicit Matrix4(
const Vector4 & v0,
const Vector4 & v1,
const Vector4 & v2,
const Vector4 & v3) {
43 TT_INLINE
void Make_Identity(
void)
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);
50 TT_INLINE
void Init(
const Matrix3D & m)
52 Row[0] = m[0]; Row[1] = m[1]; Row[2] = m[2]; Row[3] = Vector4(0.0,0.0,0.0,1.0);
54 TT_INLINE
void Init(
const Vector4 & v0,
const Vector4 & v1,
const Vector4 & v2,
const Vector4 & v3)
56 Row[0] = v0; Row[1] = v1; Row[2] = v2; Row[3] = v3;
58 TT_INLINE
void Init_Ortho_OGL(
float left,
float right,
float bottom,
float top,
float znear,
float zfar)
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);
69 TT_INLINE
void Init_Perspective_OGL(
float hfov,
float vfov,
float znear,
float zfar)
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));
79 TT_INLINE
void Init_Perspective_OGL(
float left,
float right,
float bottom,
float top,
float znear,
float zfar)
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));
91 TT_INLINE
void Init_Ortho(
float left,
float right,
float bottom,
float top,
float znear,
float zfar)
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);
102 TT_INLINE
void Init_Perspective(
float left,
float right,
float bottom,
float top,
float znear,
float zfar)
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);
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
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]));
121 TT_INLINE
float Determinant()
const
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);
132 TT_INLINE Matrix4 Inverse(
void)
const
134 float s = Determinant();
135 if (s == 0.0)
return Matrix4();
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));
156 TT_INLINE Matrix4 & operator = (
const Matrix4 & m)
158 Row[0] = m.Row[0]; Row[1] = m.Row[1]; Row[2] = m.Row[2]; Row[3] = m.Row[3];
161 TT_INLINE Matrix4 & operator += (
const Matrix4 & m)
163 Row[0] += m.Row[0]; Row[1] += m.Row[1]; Row[2] += m.Row[2]; Row[3] += m.Row[3];
166 TT_INLINE Matrix4 & operator -= (
const Matrix4 & m)
168 Row[0] -= m.Row[0]; Row[1] -= m.Row[1]; Row[2] -= m.Row[2]; Row[3] -= m.Row[3];
171 TT_INLINE Matrix4 & operator *= (
float d)
173 Row[0] *= d; Row[1] *= d; Row[2] *= d; Row[3] *= d;
176 TT_INLINE Matrix4 & operator /= (
float d)
179 Row[0] *= ood; Row[1] *= ood; Row[2] *= ood; Row[3] *= ood;
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)
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]);
219 TT_INLINE
static void Transform_Vector(
const Matrix4 &A,
const Vector3 & in,Vector4 * out)
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]);
226 TT_INLINE
static void Transform_Vector(
const Matrix4 &A,
const Vector4 & in,Vector4 * out)
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);
244 static Matrix4 ReflectPlane(
const PlaneClass& plane);
248TT_INLINE Matrix4 operator - (
const Matrix4 & a)
250 return Matrix4(-a.Row[0], -a.Row[1], -a.Row[2], -a.Row[3]);
253TT_INLINE Matrix4 operator * (
const Matrix4 & a,
float d)
255 return Matrix4(a.Row[0] * d, a.Row[1] * d, a.Row[2] * d, a.Row[3] * d);
258TT_INLINE Matrix4 operator * (
float d,
const Matrix4 & a)
263TT_INLINE Matrix4 operator / (
const Matrix4 & a,
float d)
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);
268TT_INLINE Matrix4 operator + (
const Matrix4 & a,
const Matrix4 & b)
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]);
272TT_INLINE Matrix4 Add(
const Matrix4 & a,
const Matrix4 & b)
276TT_INLINE Matrix4 operator - (
const Matrix4 & a,
const Matrix4 & b)
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]);
280TT_INLINE Matrix4 Subtract(
const Matrix4 & a,
const Matrix4 & b)
284TT_INLINE Matrix4 operator * (
const Matrix4 & a,
const Matrix4 & b)
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)));
290TT_INLINE Matrix4 Multiply(
const Matrix4 & a,
const Matrix4 & b)
294TT_INLINE Matrix4 operator * (
const Matrix4 & a,
const Matrix3D & b)
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)));
302TT_INLINE Matrix4 operator * (
const Matrix3D & a,
const Matrix4 & b)
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]));
308TT_INLINE Vector4 operator * (
const Matrix4 & a,
const Vector3 & v)
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);
312TT_INLINE Vector4 operator * (
const Matrix4 & a,
const Vector4 & v)
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]);