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) : 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 
Mat4(const std::vector<float> & elements)30 Mat4::Mat4(const std::vector<float> &elements) : Matrix(elements, 4) {}
31 
Mat4(const float * elements)32 Mat4::Mat4(const float *elements) : Matrix(elements, 4) {}
33 
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)34 Mat4::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
Rotate(float angle,const Vector3 & axis)71 Mat4 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
Translate(const Vector3 & t)115 Mat4 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
Scale(const Vector3 & s)141 Mat4 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
Frustum(float l,float r,float b,float t,float n,float f)167 Mat4 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
Perspective(float fov,float aspectRatio,float n,float f)201 Mat4 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
Ortho(float l,float r,float b,float t,float n,float f)209 Mat4 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 
product(const Mat4 & m)241 Mat4 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 
product(const Vector4 & b)267 Vector4 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 
dump()277 void 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