1// tMatrix4.h 
2// 
3// A 4x4 matrix class with the expected member functions and overloads. Backs off of the tMat4 POD type and the 
4// tLinearAlgebra library functions. 
5// 
6// Copyright (c) 2004-2006, 2015, 2017 Tristan Grimmer. 
7// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby 
8// granted, provided that the above copyright notice and this permission notice appear in all copies. 
9// 
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 
11// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 
12// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
13// AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
14// PERFORMANCE OF THIS SOFTWARE. 
15 
16#pragma once 
17#include "Math/tLinearAlgebra.h" 
18#include "Math/tVector4.h" 
19namespace tMath 
20
21 
22 
23struct tMatrix4 : public tMat4 
24
25 tMatrix4() { } 
26 tMatrix4(const tMat4& m) { tSet(*this, m); } 
27 tMatrix4(const tVec4& c1, const tVec4& c2, const tVec4& c3, const tVec4& c4) { tSet(*this, c1, c2, c3, c4); } 
28 tMatrix4(const tVec3& c1, const tVec3& c2, const tVec3& c3, const tVec3& c4) { tSet(*this, c1, c2, c3, c4); } 
29 tMatrix4(const float* a) { tSet(*this, a); } 
30 tMatrix4(const tQuat& q) /* Creates a rotation matrix from the quaternion. */ { tSet(*this, q); } 
31 tMatrix4 /* Subscript is row# followed by col# for each element. */ 
32
33 float a11, float a21, float a31, float a41
34 float a12, float a22, float a32, float a42
35 float a13, float a23, float a33, float a43
36 float a14, float a24, float a34, float a44 
37 ) { tSet(*this, a11, a21, a31, a41, a12, a22, a32, a42, a13, a23, a33, a43, a14, a24, a34, a44); } 
38 const tMat4& Pod() const { return *this; } 
39 
40 void Set(const tMat4& m) { tSet(*this, m); } 
41 void Set(const tVec4& c1, const tVec4& c2, const tVec4& c3, const tVec4& c4) { tSet(*this, c1, c2, c3, c4); } 
42 void Set(const tVec3& c1, const tVec3& c2, const tVec3& c3, const tVec3& c4) { tSet(*this, c1, c2, c3, c4); } 
43 void Set(const float* a) { tSet(*this, a); } 
44 void Set(const tQuat& q) /* Creates a rotation matrix from the quaternion. */ { tSet(*this, q); } 
45 void Set 
46
47 float a11, float a21, float a31, float a41
48 float a12, float a22, float a32, float a42
49 float a13, float a23, float a33, float a43
50 float a14, float a24, float a34, float a44 
51 ) { tSet(*this, a11, a21, a31, a41, a12, a22, a32, a42, a13, a23, a33, a43, a14, a24, a34, a44); } 
52 void Get(float* a) const { tStd::tMemcpy(a, this, 64); } 
53 tVector4& Col1() { return *((tVector4*)&C1); } 
54 tVector4& Col2() { return *((tVector4*)&C2); } 
55 tVector4& Col3() { return *((tVector4*)&C3); } 
56 tVector4& Col4() { return *((tVector4*)&C4); } 
57 
58 void Zero() { tZero(*this); } 
59 void Zero(tComponents c) { tZero(*this, c); } 
60 bool IsZero() const { return tIsZero(*this); } 
61 bool IsZero(tComponents c) const { return tIsZero(*this, c); } 
62 bool ApproxEqual(const tMat4& m, float e = Epsilon) const { return tApproxEqual(*this, m, e); } 
63 bool ApproxEqual(const tMat4& m, tComponents c, float e = Epsilon) const { return tApproxEqual(*this, m, c, e); } 
64 
65 void Identity() { tIdentity(*this); } 
66 void Transpose() /* Will invert a purely orthogonal matrix. */ { tTranspose(*this); } 
67 float Determinant() const { return tDeterminant(*this); } 
68 float Trace() const { return tTrace(*this); } 
69 void Invert() { tInvert(*this); } 
70 void InvertAffine() { tInvertAffine(*this); } 
71 
72 // Look in LinearAlgebra for function descriptions of all the composition functions below. 
73 void MakeTranslate(float x, float y, float z) { tMakeTranslate(*this, x, y, z); } 
74 void MakeTranslate(const tVec3& t) { tMakeTranslate(*this, t); } 
75 void MakeRotateX(float angle) { tMakeRotateX(*this, angle); } 
76 void MakeRotateY(float angle) { tMakeRotateY(*this, angle); } 
77 void MakeRotateZ(float angle) { tMakeRotateZ(*this, angle); } 
78 void MakeRotate(const tVec3& axis, float angle) { tMakeRotate(*this, axis, angle); } 
79 void MakeRotate(const tVec3& a, const tVec3& b) { tMakeRotate(*this, a, b); } 
80 void MakeRotateXYZ(float eulerX, float eulerY, float eulerZ) { tMakeRotateXYZ(*this, eulerX, eulerY, eulerZ); } 
81 void MakeScale(float scale) { tMakeScale(*this, scale); } 
82 void MakeScale(float scaleX, float scaleY, float scaleZ) { tMakeScale(*this, scaleX, scaleY, scaleZ); } 
83 void MakeScale(const tVec3& scale) { tMakeScale(*this, scale); } 
84 void MakeReflectXY() { tMakeReflectXY(*this); } 
85 void MakeReflectXZ() { tMakeReflectXZ(*this); } 
86 void MakeReflectYZ() { tMakeReflectYZ(*this); } 
87 void MakeLookAt(const tVec3& eye, const tVec3& look, const tVec3& up) { tMakeLookAt(*this, eye, look, up); } 
88 void MakeProjPersp(float left, float right, float bottom, float top, float nearPlane, float farPlane) { tMakeProjPersp(*this, left, right, bottom, top, nearPlane, farPlane); } 
89 void MakeProjPersp(const tVec3& boxMin, const tVec3& boxMax) { tMakeProjPersp(*this, boxMin, boxMax); } 
90 void MakeProjPerspSym(float right, float top, float nearPlane, float farPlane) { tMakeProjPerspSym(*this, right, top, nearPlane, farPlane); } 
91 void MakeProjPerspSymFovV(float fovX, float aspect, float nearPlane, float farPlane) { tMakeProjPerspSymFovV(*this, fovX, aspect, nearPlane, farPlane); } 
92 void MakeProjPerspSymFovH(float fovY, float aspect, float nearPlane, float farPlane) { tMakeProjPerspSymFovH(*this, fovY, aspect, nearPlane, farPlane); } 
93 void MakeProjPerspOffset(float right, float top, float nearPlane, float farPlane, float offX, float offY) { tMakeProjPerspOffset(*this, right, top, nearPlane, farPlane, offX, offY); } 
94 void MakeProjPerspFovVOffset(float fovX, float aspect, float nearPlane, float farPlane, float offX, float offY) { tMakeProjPerspFovVOffset(*this, fovX, aspect, nearPlane, farPlane, offX, offY); } 
95 void MakeProjPerspFovHOffset(float fovY, float aspect, float nearPlane, float farPlane, float offX, float offY) { tMakeProjPerspFovHOffset(*this, fovY, aspect, nearPlane, farPlane, offX, offY); } 
96 void MakeProjParallel(const tVec3& boxMin, const tVec3& boxMax) { tMakeProjParallel(*this, boxMin, boxMax); } 
97 void MakeOrthoNormal() { tMakeOrthoNormal(*this); } 
98 void MakeOrthoUniform() { tMakeOrthoUniform(*this); } 
99 void MakeOrthoNonUniform() { tMakeOrthoNonUniform(*this); } 
100 void MakeOrtho() { tMakeOrthoNonUniform(*this); } 
101 
102 // Look in LinearAlgebra for function descriptions of all the decomposition functions below. 
103 void ExtractAffineScale(tVec3& scale) const { tExtractAffineScale(scale, *this); } 
104 void ExtractProjectionPlanes(tVec4 planes[6], bool outwardNormals = false, bool normalizePlanes = true) const { tExtractProjectionPlanes(planes, *this, outwardNormals, normalizePlanes); } 
105 float ExtractProjectionNear() const { return tExtractProjectionNear(*this); } 
106 float ExtractProjectionFar() const { return tExtractProjectionFar(*this); } 
107 float ExtractProjectionAspect() const { return tExtractProjectionAspect(*this); } 
108 float ExtractProjectionOffsetX() const { return tExtractProjectionOffsetX(*this); } 
109 float ExtractProjectionOffsetY() const { return tExtractProjectionOffsetY(*this); } 
110 float ExtractPerspectiveFovV() const { return tExtractPerspectiveFovV(*this); } 
111 float ExtractPerspectiveFovH() const { return tExtractPerspectiveFovH(*this); } 
112 void ExtractPerspective(float& fovV, float& fovH, float& aspect, float& nearPlane, float& farPlane) const { tExtractPerspective(fovV, fovH, aspect, nearPlane, farPlane, *this); } 
113 void ExtractPerspective 
114
115 float& fovV, float& fovH, float& aspect
116 float& nearPlane, float& farPlane
117 float& offsetX, float& offsetY 
118 ) const { return tExtractPerspective(fovV, fovH, aspect, nearPlane, farPlane, offsetX, offsetY, *this); } 
119 
120 bool ExtractRotationEulerXYZ 
121
122 tVec3& sol1, tVec3& sol2
123 float gimbalZValue = 0.0f, tIntervalBias bias = tIntervalBias::Low 
124 ) const { return tExtractRotationEulerXYZ(sol1, sol2, *this, gimbalZValue, bias); } 
125 
126 bool ExtractAffineEulerXYZ 
127
128 tVec3& sol1, tVec3& sol2
129 float gimbalZValue = 0.0f, tIntervalBias bias = tIntervalBias::Low 
130 ) const { return tExtractAffineEulerXYZ(sol1, sol2, *this, gimbalZValue, bias); }  
131 
132 tMatrix4& operator=(const tMat4& m) { tSet(*this, m); return *this; } 
133 tMatrix4& operator+=(const tMat4& a) { tAdd(*this, a); return *this; } 
134 const tMatrix4 operator+(const tMat4& a) const { tMatrix4 d; tAdd(d, *this, a); return d; } 
135 tMatrix4& operator-=(const tMat4& a) { tSub(*this, a); return *this; } 
136 const tMatrix4 operator-(const tMat4& a) const { tMatrix4 d; tSub(d, *this, a); return d; } 
137 const tMatrix4 operator-() const { tMatrix4 d; tNeg(d, *this); return d; } 
138 
139 // The multiplication by a vector is not declared as a friend since we treat vectors as column vectors only, 
140 // therefore the vector multiplication is not commutable. 
141 tMatrix4& operator*=(float a) { tMul(*this, a); return *this; } 
142 tMatrix4& operator*=(const tMat4& a) { tMul(*this, a); return *this; } 
143 const tMatrix4 operator*(const tMat4& a) const { tMatrix4 d; tMul(d, *this, a); return d; } 
144 const tVector3 operator*(const tVec3& a) const { tVec3 d; tMul(d, *this, a); return d; } 
145 const tVector4 operator*(const tVec4& a) const { tVec4 d; tMul(d, *this, a); return d; } 
146 inline friend const tMatrix4 operator*(float a, const tMat4& b) { tMatrix4 d; tMul(d, a, b); return d; } 
147 inline friend const tMatrix4 operator*(const tMat4& a, float b) { tMatrix4 d; tMul(d, a, b); return d; } 
148 tMatrix4& operator/=(float a) { tDiv(*this, a); return *this; } 
149 const tMatrix4 operator/(float a) const { tMatrix4 d; tDiv(d, *this, a); return d; } 
150 
151 bool operator==(const tMat4& a) const { return tEqual(*this, a); } 
152 bool operator!=(const tMat4& a) const { return tNotEqual(*this, a); } 
153 operator const float*() { return E; } 
154 operator const float*() const { return E; } 
155 float& operator[](int i) { return E[i]; } 
156 float operator[](int i) const { return E[i]; } 
157 
158 const static tMatrix4 zero; // Zero matrix. 
159 const static tMatrix4 identity; // Identity matrix. 
160}; 
161 
162 
163
164