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