1//
2// Copyright 2018 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// matrix_utils.cpp: Contains implementations for Mat4 methods.
8
9#include "common/matrix_utils.h"
10
11namespace angle
12{
13
14Mat4::Mat4() : Mat4(1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f)
15{}
16
17Mat4::Mat4(const Matrix<float> generalMatrix) : Matrix(std::vector<float>(16, 0), 4, 4)
18{
19 unsigned int minCols = std::min((unsigned int)4, generalMatrix.columns());
20 unsigned int minRows = std::min((unsigned int)4, generalMatrix.rows());
21 for (unsigned int i = 0; i < minCols; i++)
22 {
23 for (unsigned int j = 0; j < minRows; j++)
24 {
25 mElements[j * minCols + i] = generalMatrix.at(j, i);
26 }
27 }
28}
29
30Mat4::Mat4(const std::vector<float> &elements) : Matrix(elements, 4) {}
31
32Mat4::Mat4(const float *elements) : Matrix(elements, 4) {}
33
34Mat4::Mat4(float m00,
35 float m01,
36 float m02,
37 float m03,
38 float m10,
39 float m11,
40 float m12,
41 float m13,
42 float m20,
43 float m21,
44 float m22,
45 float m23,
46 float m30,
47 float m31,
48 float m32,
49 float m33)
50 : Matrix(std::vector<float>(16, 0), 4, 4)
51{
52 mElements[0] = m00;
53 mElements[1] = m01;
54 mElements[2] = m02;
55 mElements[3] = m03;
56 mElements[4] = m10;
57 mElements[5] = m11;
58 mElements[6] = m12;
59 mElements[7] = m13;
60 mElements[8] = m20;
61 mElements[9] = m21;
62 mElements[10] = m22;
63 mElements[11] = m23;
64 mElements[12] = m30;
65 mElements[13] = m31;
66 mElements[14] = m32;
67 mElements[15] = m33;
68}
69
70// static
71Mat4 Mat4::Rotate(float angle, const Vector3 &axis)
72{
73 auto axis_normalized = axis.normalized();
74 float angle_radians = angle * (3.14159265358979323f / 180.0f);
75 float c = cos(angle_radians);
76 float ci = 1.f - c;
77 float s = sin(angle_radians);
78
79 float x = axis_normalized.x();
80 float y = axis_normalized.y();
81 float z = axis_normalized.z();
82
83 float x2 = x * x;
84 float y2 = y * y;
85 float z2 = z * z;
86
87 float xy = x * y;
88 float yz = y * z;
89 float zx = z * x;
90
91 float r00 = c + ci * x2;
92 float r01 = ci * xy + s * z;
93 float r02 = ci * zx - s * y;
94 float r03 = 0.f;
95
96 float r10 = ci * xy - s * z;
97 float r11 = c + ci * y2;
98 float r12 = ci * yz + s * x;
99 float r13 = 0.f;
100
101 float r20 = ci * zx + s * y;
102 float r21 = ci * yz - s * x;
103 float r22 = c + ci * z2;
104 float r23 = 0.f;
105
106 float r30 = 0.f;
107 float r31 = 0.f;
108 float r32 = 0.f;
109 float r33 = 1.f;
110
111 return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33);
112}
113
114// static
115Mat4 Mat4::Translate(const Vector3 &t)
116{
117 float r00 = 1.f;
118 float r01 = 0.f;
119 float r02 = 0.f;
120 float r03 = 0.f;
121
122 float r10 = 0.f;
123 float r11 = 1.f;
124 float r12 = 0.f;
125 float r13 = 0.f;
126
127 float r20 = 0.f;
128 float r21 = 0.f;
129 float r22 = 1.f;
130 float r23 = 0.f;
131
132 float r30 = t.x();
133 float r31 = t.y();
134 float r32 = t.z();
135 float r33 = 1.f;
136
137 return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33);
138}
139
140// static
141Mat4 Mat4::Scale(const Vector3 &s)
142{
143 float r00 = s.x();
144 float r01 = 0.f;
145 float r02 = 0.f;
146 float r03 = 0.f;
147
148 float r10 = 0.f;
149 float r11 = s.y();
150 float r12 = 0.f;
151 float r13 = 0.f;
152
153 float r20 = 0.f;
154 float r21 = 0.f;
155 float r22 = s.z();
156 float r23 = 0.f;
157
158 float r30 = 0.f;
159 float r31 = 0.f;
160 float r32 = 0.f;
161 float r33 = 1.f;
162
163 return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33);
164}
165
166// static
167Mat4 Mat4::Frustum(float l, float r, float b, float t, float n, float f)
168{
169 float nn = 2.f * n;
170 float fpn = f + n;
171 float fmn = f - n;
172 float tpb = t + b;
173 float tmb = t - b;
174 float rpl = r + l;
175 float rml = r - l;
176
177 float r00 = nn / rml;
178 float r01 = 0.f;
179 float r02 = 0.f;
180 float r03 = 0.f;
181
182 float r10 = 0.f;
183 float r11 = nn / tmb;
184 float r12 = 0.f;
185 float r13 = 0.f;
186
187 float r20 = rpl / rml;
188 float r21 = tpb / tmb;
189 float r22 = -fpn / fmn;
190 float r23 = -1.f;
191
192 float r30 = 0.f;
193 float r31 = 0.f;
194 float r32 = -nn * f / fmn;
195 float r33 = 0.f;
196
197 return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33);
198}
199
200// static
201Mat4 Mat4::Perspective(float fov, float aspectRatio, float n, float f)
202{
203 const float frustumHeight = tanf(static_cast<float>(fov / 360.0f * 3.14159265358979323)) * n;
204 const float frustumWidth = frustumHeight * aspectRatio;
205 return Frustum(-frustumWidth, frustumWidth, -frustumHeight, frustumHeight, n, f);
206}
207
208// static
209Mat4 Mat4::Ortho(float l, float r, float b, float t, float n, float f)
210{
211 float fpn = f + n;
212 float fmn = f - n;
213 float tpb = t + b;
214 float tmb = t - b;
215 float rpl = r + l;
216 float rml = r - l;
217
218 float r00 = 2.f / rml;
219 float r01 = 0.f;
220 float r02 = 0.f;
221 float r03 = 0.f;
222
223 float r10 = 0.f;
224 float r11 = 2.f / tmb;
225 float r12 = 0.f;
226 float r13 = 0.f;
227
228 float r20 = 0.f;
229 float r21 = 0.f;
230 float r22 = -2.f / fmn;
231 float r23 = 0.f;
232
233 float r30 = -rpl / rml;
234 float r31 = -tpb / tmb;
235 float r32 = -fpn / fmn;
236 float r33 = 1.f;
237
238 return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33);
239}
240
241Mat4 Mat4::product(const Mat4 &m)
242{
243 const float *a = mElements.data();
244 const float *b = m.mElements.data();
245
246 return Mat4(a[0] * b[0] + a[4] * b[1] + a[8] * b[2] + a[12] * b[3],
247 a[1] * b[0] + a[5] * b[1] + a[9] * b[2] + a[13] * b[3],
248 a[2] * b[0] + a[6] * b[1] + a[10] * b[2] + a[14] * b[3],
249 a[3] * b[0] + a[7] * b[1] + a[11] * b[2] + a[15] * b[3],
250
251 a[0] * b[4] + a[4] * b[5] + a[8] * b[6] + a[12] * b[7],
252 a[1] * b[4] + a[5] * b[5] + a[9] * b[6] + a[13] * b[7],
253 a[2] * b[4] + a[6] * b[5] + a[10] * b[6] + a[14] * b[7],
254 a[3] * b[4] + a[7] * b[5] + a[11] * b[6] + a[15] * b[7],
255
256 a[0] * b[8] + a[4] * b[9] + a[8] * b[10] + a[12] * b[11],
257 a[1] * b[8] + a[5] * b[9] + a[9] * b[10] + a[13] * b[11],
258 a[2] * b[8] + a[6] * b[9] + a[10] * b[10] + a[14] * b[11],
259 a[3] * b[8] + a[7] * b[9] + a[11] * b[10] + a[15] * b[11],
260
261 a[0] * b[12] + a[4] * b[13] + a[8] * b[14] + a[12] * b[15],
262 a[1] * b[12] + a[5] * b[13] + a[9] * b[14] + a[13] * b[15],
263 a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14] * b[15],
264 a[3] * b[12] + a[7] * b[13] + a[11] * b[14] + a[15] * b[15]);
265}
266
267Vector4 Mat4::product(const Vector4 &b)
268{
269 return Vector4(
270 mElements[0] * b.x() + mElements[4] * b.y() + mElements[8] * b.z() + mElements[12] * b.w(),
271 mElements[1] * b.x() + mElements[5] * b.y() + mElements[9] * b.z() + mElements[13] * b.w(),
272 mElements[2] * b.x() + mElements[6] * b.y() + mElements[10] * b.z() + mElements[14] * b.w(),
273 mElements[3] * b.x() + mElements[7] * b.y() + mElements[11] * b.z() +
274 mElements[15] * b.w());
275}
276
277void Mat4::dump()
278{
279 printf("[ %f %f %f %f ]\n", mElements[0], mElements[4], mElements[8], mElements[12]);
280 printf("[ %f %f %f %f ]\n", mElements[1], mElements[5], mElements[9], mElements[13]);
281 printf("[ %f %f %f %f ]\n", mElements[2], mElements[6], mElements[10], mElements[14]);
282 printf("[ %f %f %f %f ]\n", mElements[3], mElements[7], mElements[11], mElements[15]);
283}
284
285} // namespace angle
286