xref: /aosp_15_r20/external/angle/src/common/matrix_utils.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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