1// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "Matrix.hpp"
16
17#include "Point.hpp"
18#include "Math.hpp"
19
20namespace sw
21{
22	Matrix Matrix::diag(float m11, float m22, float m33, float m44)
23	{
24		return Matrix(m11, 0,   0,   0,
25		              0,   m22, 0,   0,
26		              0,   0,   m33, 0,
27		              0,   0,   0,   m44);
28	}
29
30	Matrix::operator float*()
31	{
32		return &(*this)(1, 1);
33	}
34
35	Matrix Matrix::operator+() const
36	{
37		return *this;
38	}
39
40	Matrix Matrix::operator-() const
41	{
42		const Matrix &M = *this;
43
44		return Matrix(-M(1, 1), -M(1, 2), -M(1, 3), -M(1, 4),
45		              -M(2, 1), -M(2, 2), -M(2, 3), -M(2, 4),
46		              -M(3, 1), -M(3, 2), -M(3, 3), -M(3, 4),
47		              -M(4, 1), -M(4, 2), -M(4, 3), -M(4, 4));
48	}
49
50	Matrix Matrix::operator!() const
51	{
52		const Matrix &M = *this;
53		Matrix I;
54
55		float M3344 = M(3, 3) * M(4, 4) - M(4, 3) * M(3, 4);
56		float M2344 = M(2, 3) * M(4, 4) - M(4, 3) * M(2, 4);
57		float M2334 = M(2, 3) * M(3, 4) - M(3, 3) * M(2, 4);
58		float M3244 = M(3, 2) * M(4, 4) - M(4, 2) * M(3, 4);
59		float M2244 = M(2, 2) * M(4, 4) - M(4, 2) * M(2, 4);
60		float M2234 = M(2, 2) * M(3, 4) - M(3, 2) * M(2, 4);
61		float M3243 = M(3, 2) * M(4, 3) - M(4, 2) * M(3, 3);
62		float M2243 = M(2, 2) * M(4, 3) - M(4, 2) * M(2, 3);
63		float M2233 = M(2, 2) * M(3, 3) - M(3, 2) * M(2, 3);
64		float M1344 = M(1, 3) * M(4, 4) - M(4, 3) * M(1, 4);
65		float M1334 = M(1, 3) * M(3, 4) - M(3, 3) * M(1, 4);
66		float M1244 = M(1, 2) * M(4, 4) - M(4, 2) * M(1, 4);
67		float M1234 = M(1, 2) * M(3, 4) - M(3, 2) * M(1, 4);
68		float M1243 = M(1, 2) * M(4, 3) - M(4, 2) * M(1, 3);
69		float M1233 = M(1, 2) * M(3, 3) - M(3, 2) * M(1, 3);
70		float M1324 = M(1, 3) * M(2, 4) - M(2, 3) * M(1, 4);
71		float M1224 = M(1, 2) * M(2, 4) - M(2, 2) * M(1, 4);
72		float M1223 = M(1, 2) * M(2, 3) - M(2, 2) * M(1, 3);
73
74		// Adjoint Matrix
75		I(1, 1) =  M(2, 2) * M3344 - M(3, 2) * M2344 + M(4, 2) * M2334;
76		I(2, 1) = -M(2, 1) * M3344 + M(3, 1) * M2344 - M(4, 1) * M2334;
77		I(3, 1) =  M(2, 1) * M3244 - M(3, 1) * M2244 + M(4, 1) * M2234;
78		I(4, 1) = -M(2, 1) * M3243 + M(3, 1) * M2243 - M(4, 1) * M2233;
79
80		I(1, 2) = -M(1, 2) * M3344 + M(3, 2) * M1344 - M(4, 2) * M1334;
81		I(2, 2) =  M(1, 1) * M3344 - M(3, 1) * M1344 + M(4, 1) * M1334;
82		I(3, 2) = -M(1, 1) * M3244 + M(3, 1) * M1244 - M(4, 1) * M1234;
83		I(4, 2) =  M(1, 1) * M3243 - M(3, 1) * M1243 + M(4, 1) * M1233;
84
85		I(1, 3) =  M(1, 2) * M2344 - M(2, 2) * M1344 + M(4, 2) * M1324;
86		I(2, 3) = -M(1, 1) * M2344 + M(2, 1) * M1344 - M(4, 1) * M1324;
87		I(3, 3) =  M(1, 1) * M2244 - M(2, 1) * M1244 + M(4, 1) * M1224;
88		I(4, 3) = -M(1, 1) * M2243 + M(2, 1) * M1243 - M(4, 1) * M1223;
89
90		I(1, 4) = -M(1, 2) * M2334 + M(2, 2) * M1334 - M(3, 2) * M1324;
91		I(2, 4) =  M(1, 1) * M2334 - M(2, 1) * M1334 + M(3, 1) * M1324;
92		I(3, 4) = -M(1, 1) * M2234 + M(2, 1) * M1234 - M(3, 1) * M1224;
93		I(4, 4) =  M(1, 1) * M2233 - M(2, 1) * M1233 + M(3, 1) * M1223;
94
95		// Division by determinant
96		I /= M(1, 1) * I(1, 1) +
97		     M(2, 1) * I(1, 2) +
98		     M(3, 1) * I(1, 3) +
99		     M(4, 1) * I(1, 4);
100
101		return I;
102	}
103
104	Matrix Matrix::operator~() const
105	{
106		const Matrix &M = *this;
107
108		return Matrix(M(1, 1), M(2, 1), M(3, 1), M(4, 1),
109		              M(1, 2), M(2, 2), M(3, 2), M(4, 2),
110		              M(1, 3), M(2, 3), M(3, 3), M(4, 3),
111		              M(1, 4), M(2, 4), M(3, 4), M(4, 4));
112	}
113
114	Matrix &Matrix::operator+=(const Matrix &N)
115	{
116		Matrix &M = *this;
117
118		M(1, 1) += N(1, 1); M(1, 2) += N(1, 2); M(1, 3) += N(1, 3); M(1, 4) += N(1, 4);
119		M(2, 1) += N(2, 1); M(2, 2) += N(2, 2); M(2, 3) += N(2, 3); M(2, 4) += N(2, 4);
120		M(3, 1) += N(3, 1); M(3, 2) += N(3, 2); M(3, 3) += N(3, 3); M(3, 4) += N(3, 4);
121		M(4, 1) += N(4, 1); M(4, 2) += N(4, 2); M(4, 3) += N(4, 3); M(4, 4) += N(4, 4);
122
123		return M;
124	}
125
126	Matrix &Matrix::operator-=(const Matrix &N)
127	{
128		Matrix &M = *this;
129
130		M(1, 1) -= N(1, 1); M(1, 2) -= N(1, 2); M(1, 3) -= N(1, 3); M(1, 4) -= N(1, 4);
131		M(2, 1) -= N(2, 1); M(2, 2) -= N(2, 2); M(2, 3) -= N(2, 3); M(2, 4) -= N(2, 4);
132		M(3, 1) -= N(3, 1); M(3, 2) -= N(3, 2); M(3, 3) -= N(3, 3); M(3, 4) -= N(3, 4);
133		M(4, 1) -= N(4, 1); M(4, 2) -= N(4, 2); M(4, 3) -= N(4, 3); M(4, 4) -= N(4, 4);
134
135		return M;
136	}
137
138	Matrix &Matrix::operator*=(float s)
139	{
140		Matrix &M = *this;
141
142		M(1, 1) *= s; M(1, 2) *= s; M(1, 3) *= s; M(1, 4) *= s;
143		M(2, 1) *= s; M(2, 2) *= s; M(2, 3) *= s; M(2, 4) *= s;
144		M(3, 1) *= s; M(3, 2) *= s; M(3, 3) *= s; M(3, 4) *= s;
145		M(4, 1) *= s; M(4, 2) *= s; M(4, 3) *= s; M(4, 4) *= s;
146
147		return M;
148	}
149
150	Matrix &Matrix::operator*=(const Matrix &M)
151	{
152		return *this = *this * M;
153	}
154
155	Matrix &Matrix::operator/=(float s)
156	{
157		float r = 1.0f / s;
158
159		return *this *= r;
160	}
161
162	bool operator==(const Matrix &M, const Matrix &N)
163	{
164		if(M(1, 1) == N(1, 1) && M(1, 2) == N(1, 2) && M(1, 3) == N(1, 3) && M(1, 4) == N(1, 4) &&
165		   M(2, 1) == N(2, 1) && M(2, 2) == N(2, 2) && M(2, 3) == N(2, 3) && M(2, 4) == N(2, 4) &&
166		   M(3, 1) == N(3, 1) && M(3, 2) == N(3, 2) && M(3, 3) == N(3, 3) && M(3, 4) == N(3, 4) &&
167		   M(4, 1) == N(4, 1) && M(4, 2) == N(4, 2) && M(4, 3) == N(4, 3) && M(4, 4) == N(4, 4))
168			return true;
169		else
170			return false;
171	}
172
173	bool operator!=(const Matrix &M, const Matrix &N)
174	{
175		if(M(1, 1) != N(1, 1) || M(1, 2) != N(1, 2) || M(1, 3) != N(1, 3) || M(1, 4) != N(1, 4) ||
176		   M(2, 1) != N(2, 1) || M(2, 2) != N(2, 2) || M(2, 3) != N(2, 3) || M(2, 4) != N(2, 4) ||
177		   M(3, 1) != N(3, 1) || M(3, 2) != N(3, 2) || M(3, 3) != N(3, 3) || M(3, 4) != N(3, 4) ||
178		   M(4, 1) != N(4, 1) || M(4, 2) != N(4, 2) || M(4, 3) != N(4, 3) || M(4, 4) != N(4, 4))
179			return true;
180		else
181			return false;
182	}
183
184	Matrix operator+(const Matrix &M, const Matrix &N)
185	{
186		return Matrix(M(1, 1) + N(1, 1), M(1, 2) + N(1, 2), M(1, 3) + N(1, 3), M(1, 4) + N(1, 4),
187		              M(2, 1) + N(2, 1), M(2, 2) + N(2, 2), M(2, 3) + N(2, 3), M(2, 4) + N(2, 4),
188		              M(3, 1) + N(3, 1), M(3, 2) + N(3, 2), M(3, 3) + N(3, 3), M(3, 4) + N(3, 4),
189		              M(4, 1) + N(4, 1), M(4, 2) + N(4, 2), M(4, 3) + N(4, 3), M(4, 4) + N(4, 4));
190	}
191
192	Matrix operator-(const Matrix &M, const Matrix &N)
193	{
194		return Matrix(M(1, 1) - N(1, 1), M(1, 2) - N(1, 2), M(1, 3) - N(1, 3), M(1, 4) - N(1, 4),
195		              M(2, 1) - N(2, 1), M(2, 2) - N(2, 2), M(2, 3) - N(2, 3), M(2, 4) - N(2, 4),
196		              M(3, 1) - N(3, 1), M(3, 2) - N(3, 2), M(3, 3) - N(3, 3), M(3, 4) - N(3, 4),
197		              M(4, 1) - N(4, 1), M(4, 2) - N(4, 2), M(4, 3) - N(4, 3), M(4, 4) - N(4, 4));
198	}
199
200	Matrix operator*(float s, const Matrix &M)
201	{
202		return Matrix(s * M(1, 1), s * M(1, 2), s * M(1, 3), s * M(1, 4),
203		              s * M(2, 1), s * M(2, 2), s * M(2, 3), s * M(2, 4),
204		              s * M(3, 1), s * M(3, 2), s * M(3, 3), s * M(3, 4),
205		              s * M(4, 1), s * M(4, 2), s * M(4, 3), s * M(4, 4));
206	}
207
208	Matrix operator*(const Matrix &M, float s)
209	{
210		return Matrix(M(1, 1) * s, M(1, 2) * s, M(1, 3) * s, M(1, 4) * s,
211		              M(2, 1) * s, M(2, 2) * s, M(2, 3) * s, M(2, 4) * s,
212		              M(3, 1) * s, M(3, 2) * s, M(3, 3) * s, M(3, 4) * s,
213		              M(4, 1) * s, M(4, 2) * s, M(4, 3) * s, M(4, 4) * s);
214	}
215
216	Matrix operator*(const Matrix &M, const Matrix &N)
217	{
218		return Matrix(M(1, 1) * N(1, 1) + M(1, 2) * N(2, 1) + M(1, 3) * N(3, 1) + M(1, 4) * N(4, 1), M(1, 1) * N(1, 2) + M(1, 2) * N(2, 2) + M(1, 3) * N(3, 2) + M(1, 4) * N(4, 2), M(1, 1) * N(1, 3) + M(1, 2) * N(2, 3) + M(1, 3) * N(3, 3) + M(1, 4) * N(4, 3), M(1, 1) * N(1, 4) + M(1, 2) * N(2, 4) + M(1, 3) * N(3, 4) + M(1, 4) * N(4, 4),
219		              M(2, 1) * N(1, 1) + M(2, 2) * N(2, 1) + M(2, 3) * N(3, 1) + M(2, 4) * N(4, 1), M(2, 1) * N(1, 2) + M(2, 2) * N(2, 2) + M(2, 3) * N(3, 2) + M(2, 4) * N(4, 2), M(2, 1) * N(1, 3) + M(2, 2) * N(2, 3) + M(2, 3) * N(3, 3) + M(2, 4) * N(4, 3), M(2, 1) * N(1, 4) + M(2, 2) * N(2, 4) + M(2, 3) * N(3, 4) + M(2, 4) * N(4, 4),
220		              M(3, 1) * N(1, 1) + M(3, 2) * N(2, 1) + M(3, 3) * N(3, 1) + M(3, 4) * N(4, 1), M(3, 1) * N(1, 2) + M(3, 2) * N(2, 2) + M(3, 3) * N(3, 2) + M(3, 4) * N(4, 2), M(3, 1) * N(1, 3) + M(3, 2) * N(2, 3) + M(3, 3) * N(3, 3) + M(3, 4) * N(4, 3), M(3, 1) * N(1, 4) + M(3, 2) * N(2, 4) + M(3, 3) * N(3, 4) + M(3, 4) * N(4, 4),
221		              M(4, 1) * N(1, 1) + M(4, 2) * N(2, 1) + M(4, 3) * N(3, 1) + M(4, 4) * N(4, 1), M(4, 1) * N(1, 2) + M(4, 2) * N(2, 2) + M(4, 3) * N(3, 2) + M(4, 4) * N(4, 2), M(4, 1) * N(1, 3) + M(4, 2) * N(2, 3) + M(4, 3) * N(3, 3) + M(4, 4) * N(4, 3), M(4, 1) * N(1, 4) + M(4, 2) * N(2, 4) + M(4, 3) * N(3, 4) + M(4, 4) * N(4, 4));
222	}
223
224	Matrix operator/(const Matrix &M, float s)
225	{
226		float r = 1.0f / s;
227
228		return M * r;
229	}
230
231	float4 Matrix::operator*(const float4 &v) const
232	{
233		const Matrix &M = *this;
234		float Mx = M(1, 1) * v.x + M(1, 2) * v.y + M(1, 3) * v.z + M(1, 4) * v.w;
235		float My = M(2, 1) * v.x + M(2, 2) * v.y + M(2, 3) * v.z + M(2, 4) * v.w;
236		float Mz = M(3, 1) * v.x + M(3, 2) * v.y + M(3, 3) * v.z + M(3, 4) * v.w;
237		float Mw = M(4, 1) * v.x + M(4, 2) * v.y + M(4, 3) * v.z + M(4, 4) * v.w;
238
239		return {Mx, My, Mz, Mw};
240	}
241
242	float Matrix::det(const Matrix &M)
243	{
244		float M3344 = M(3, 3) * M(4, 4) - M(4, 3) * M(3, 4);
245		float M2344 = M(2, 3) * M(4, 4) - M(4, 3) * M(2, 4);
246		float M2334 = M(2, 3) * M(3, 4) - M(3, 3) * M(2, 4);
247		float M1344 = M(1, 3) * M(4, 4) - M(4, 3) * M(1, 4);
248		float M1334 = M(1, 3) * M(3, 4) - M(3, 3) * M(1, 4);
249		float M1324 = M(1, 3) * M(2, 4) - M(2, 3) * M(1, 4);
250
251		return M(1, 1) * (M(2, 2) * M3344 - M(3, 2) * M2344 + M(4, 2) * M2334) -
252		       M(2, 1) * (M(1, 2) * M3344 - M(3, 2) * M1344 + M(4, 2) * M1334) +
253		       M(3, 1) * (M(1, 2) * M2344 - M(2, 2) * M1344 + M(4, 2) * M1324) -
254		       M(4, 1) * (M(1, 2) * M2334 - M(2, 2) * M1334 + M(3, 2) * M1324);
255	}
256
257	float Matrix::det(float m11)
258	{
259		return m11;
260	}
261
262	float Matrix::det(float m11, float m12,
263	                  float m21, float m22)
264	{
265		return m11 * m22 - m12 * m21;
266	}
267
268	float Matrix::det(float m11, float m12, float m13,
269	                  float m21, float m22, float m23,
270	                  float m31, float m32, float m33)
271	{
272		return m11 * (m22 * m33 - m32 * m23) -
273		       m21 * (m12 * m33 - m32 * m13) +
274		       m31 * (m12 * m23 - m22 * m13);
275	}
276
277	float Matrix::det(float m11, float m12, float m13, float m14,
278	                  float m21, float m22, float m23, float m24,
279	                  float m31, float m32, float m33, float m34,
280	                  float m41, float m42, float m43, float m44)
281	{
282		float M3344 = m33 * m44 - m43 * m34;
283		float M2344 = m23 * m44 - m43 * m24;
284		float M2334 = m23 * m34 - m33 * m24;
285		float M1344 = m13 * m44 - m43 * m14;
286		float M1334 = m13 * m34 - m33 * m14;
287		float M1324 = m13 * m24 - m23 * m14;
288
289		return m11 * (m22 * M3344 - m32 * M2344 + m42 * M2334) -
290		       m21 * (m12 * M3344 - m32 * M1344 + m42 * M1334) +
291		       m31 * (m12 * M2344 - m22 * M1344 + m42 * M1324) -
292		       m41 * (m12 * M2334 - m22 * M1334 + m32 * M1324);
293	}
294
295	float Matrix::det(const Vector &v1, const Vector &v2, const Vector &v3)
296	{
297		return v1 * (v2 % v3);
298	}
299
300	float Matrix::det3(const Matrix &M)
301	{
302		return M(1, 1) * (M(2, 2) * M(3, 3) - M(3, 2) * M(2, 3)) -
303		       M(2, 1) * (M(1, 2) * M(3, 3) - M(3, 2) * M(1, 3)) +
304		       M(3, 1) * (M(1, 2) * M(2, 3) - M(2, 2) * M(1, 3));
305	}
306
307	float Matrix::tr(const Matrix &M)
308	{
309		return M(1, 1) + M(2, 2) + M(3, 3) + M(4, 4);
310	}
311
312	Matrix &Matrix::orthogonalise()
313	{
314		// NOTE: Numnerically instable, won't return exact the same result when already orhtogonal
315
316		Matrix &M = *this;
317
318		Vector v1(M(1, 1), M(2, 1), M(3, 1));
319		Vector v2(M(1, 2), M(2, 2), M(3, 2));
320		Vector v3(M(1, 3), M(2, 3), M(3, 3));
321
322		v2 -= v1 * (v1 * v2) / (v1 * v1);
323		v3 -= v1 * (v1 * v3) / (v1 * v1);
324		v3 -= v2 * (v2 * v3) / (v2 * v2);
325
326		v1 /= Vector::N(v1);
327		v2 /= Vector::N(v2);
328		v3 /= Vector::N(v3);
329
330		M(1, 1) = v1.x;  M(1, 2) = v2.x;  M(1, 3) = v3.x;
331		M(2, 1) = v1.y;  M(2, 2) = v2.y;  M(2, 3) = v3.y;
332		M(3, 1) = v1.z;  M(3, 2) = v2.z;  M(3, 3) = v3.z;
333
334		return *this;
335	}
336
337	Matrix Matrix::eulerRotate(const Vector &v)
338	{
339		float cz = cos(v.z);
340		float sz = sin(v.z);
341		float cx = cos(v.x);
342		float sx = sin(v.x);
343		float cy = cos(v.y);
344		float sy = sin(v.y);
345
346		float sxsy = sx * sy;
347		float sxcy = sx * cy;
348
349		return Matrix(cy * cz - sxsy * sz, -cy * sz - sxsy * cz, -sy * cx,
350		              cx * sz,              cx * cz,             -sx,
351		              sy * cz + sxcy * sz, -sy * sz + sxcy * cz,  cy * cx);
352	}
353
354	Matrix Matrix::eulerRotate(float x, float y, float z)
355	{
356		return eulerRotate(Vector(x, y, z));
357	}
358
359	Matrix Matrix::translate(const Vector &v)
360	{
361		return Matrix(1, 0, 0, v.x,
362		              0, 1, 0, v.y,
363		              0, 0, 1, v.z,
364		              0, 0, 0, 1);
365	}
366
367	Matrix Matrix::translate(float x, float y, float z)
368	{
369		return translate(Vector(x, y, z));
370	}
371
372	Matrix Matrix::scale(const Vector &v)
373	{
374		return Matrix(v.x, 0,   0,
375		              0,   v.y, 0,
376		              0,   0,   v.z);
377	}
378
379	Matrix Matrix::scale(float x, float y, float z)
380	{
381		return scale(Vector(x, y, z));
382	}
383
384	Matrix Matrix::lookAt(const Vector &v)
385	{
386		Vector y = v;
387		y /= Vector::N(y);
388
389		Vector x = y % Vector(0, 0, 1);
390		x /= Vector::N(x);
391
392		Vector z = x % y;
393		z /= Vector::N(z);
394
395		return ~Matrix(x, y, z);
396	}
397
398	Matrix Matrix::lookAt(float x, float y, float z)
399	{
400		return translate(Vector(x, y, z));
401	}
402}
403