xref: /aosp_15_r20/external/angle/util/Matrix.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // Matrix:
7*8975f5c5SAndroid Build Coastguard Worker //   Helper class for doing matrix math.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include "Matrix.h"
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker #define _USE_MATH_DEFINES
13*8975f5c5SAndroid Build Coastguard Worker #include <math.h>
14*8975f5c5SAndroid Build Coastguard Worker #include <cstddef>
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
17*8975f5c5SAndroid Build Coastguard Worker 
Matrix4()18*8975f5c5SAndroid Build Coastguard Worker Matrix4::Matrix4()
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker     data[0]  = 1.0f;
21*8975f5c5SAndroid Build Coastguard Worker     data[4]  = 0.0f;
22*8975f5c5SAndroid Build Coastguard Worker     data[8]  = 0.0f;
23*8975f5c5SAndroid Build Coastguard Worker     data[12] = 0.0f;
24*8975f5c5SAndroid Build Coastguard Worker     data[1]  = 0.0f;
25*8975f5c5SAndroid Build Coastguard Worker     data[5]  = 1.0f;
26*8975f5c5SAndroid Build Coastguard Worker     data[9]  = 0.0f;
27*8975f5c5SAndroid Build Coastguard Worker     data[13] = 0.0f;
28*8975f5c5SAndroid Build Coastguard Worker     data[2]  = 0.0f;
29*8975f5c5SAndroid Build Coastguard Worker     data[6]  = 0.0f;
30*8975f5c5SAndroid Build Coastguard Worker     data[10] = 1.0f;
31*8975f5c5SAndroid Build Coastguard Worker     data[14] = 0.0f;
32*8975f5c5SAndroid Build Coastguard Worker     data[3]  = 0.0f;
33*8975f5c5SAndroid Build Coastguard Worker     data[7]  = 0.0f;
34*8975f5c5SAndroid Build Coastguard Worker     data[11] = 0.0f;
35*8975f5c5SAndroid Build Coastguard Worker     data[15] = 1.0f;
36*8975f5c5SAndroid Build Coastguard Worker }
37*8975f5c5SAndroid Build Coastguard Worker 
Matrix4(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)38*8975f5c5SAndroid Build Coastguard Worker Matrix4::Matrix4(float m00,
39*8975f5c5SAndroid Build Coastguard Worker                  float m01,
40*8975f5c5SAndroid Build Coastguard Worker                  float m02,
41*8975f5c5SAndroid Build Coastguard Worker                  float m03,
42*8975f5c5SAndroid Build Coastguard Worker                  float m10,
43*8975f5c5SAndroid Build Coastguard Worker                  float m11,
44*8975f5c5SAndroid Build Coastguard Worker                  float m12,
45*8975f5c5SAndroid Build Coastguard Worker                  float m13,
46*8975f5c5SAndroid Build Coastguard Worker                  float m20,
47*8975f5c5SAndroid Build Coastguard Worker                  float m21,
48*8975f5c5SAndroid Build Coastguard Worker                  float m22,
49*8975f5c5SAndroid Build Coastguard Worker                  float m23,
50*8975f5c5SAndroid Build Coastguard Worker                  float m30,
51*8975f5c5SAndroid Build Coastguard Worker                  float m31,
52*8975f5c5SAndroid Build Coastguard Worker                  float m32,
53*8975f5c5SAndroid Build Coastguard Worker                  float m33)
54*8975f5c5SAndroid Build Coastguard Worker {
55*8975f5c5SAndroid Build Coastguard Worker     data[0]  = m00;
56*8975f5c5SAndroid Build Coastguard Worker     data[4]  = m01;
57*8975f5c5SAndroid Build Coastguard Worker     data[8]  = m02;
58*8975f5c5SAndroid Build Coastguard Worker     data[12] = m03;
59*8975f5c5SAndroid Build Coastguard Worker     data[1]  = m10;
60*8975f5c5SAndroid Build Coastguard Worker     data[5]  = m11;
61*8975f5c5SAndroid Build Coastguard Worker     data[9]  = m12;
62*8975f5c5SAndroid Build Coastguard Worker     data[13] = m13;
63*8975f5c5SAndroid Build Coastguard Worker     data[2]  = m20;
64*8975f5c5SAndroid Build Coastguard Worker     data[6]  = m21;
65*8975f5c5SAndroid Build Coastguard Worker     data[10] = m22;
66*8975f5c5SAndroid Build Coastguard Worker     data[14] = m23;
67*8975f5c5SAndroid Build Coastguard Worker     data[3]  = m30;
68*8975f5c5SAndroid Build Coastguard Worker     data[7]  = m31;
69*8975f5c5SAndroid Build Coastguard Worker     data[11] = m32;
70*8975f5c5SAndroid Build Coastguard Worker     data[15] = m33;
71*8975f5c5SAndroid Build Coastguard Worker }
72*8975f5c5SAndroid Build Coastguard Worker 
identity()73*8975f5c5SAndroid Build Coastguard Worker Matrix4 Matrix4::identity()
74*8975f5c5SAndroid Build Coastguard Worker {
75*8975f5c5SAndroid Build Coastguard Worker     return Matrix4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
76*8975f5c5SAndroid Build Coastguard Worker                    0.0f, 0.0f, 1.0f);
77*8975f5c5SAndroid Build Coastguard Worker }
78*8975f5c5SAndroid Build Coastguard Worker 
rotate(float angle,const Vector3 & p)79*8975f5c5SAndroid Build Coastguard Worker Matrix4 Matrix4::rotate(float angle, const Vector3 &p)
80*8975f5c5SAndroid Build Coastguard Worker {
81*8975f5c5SAndroid Build Coastguard Worker     Vector3 u   = p.normalized();
82*8975f5c5SAndroid Build Coastguard Worker     float theta = static_cast<float>(angle * (M_PI / 180.0f));
83*8975f5c5SAndroid Build Coastguard Worker     float cos_t = cosf(theta);
84*8975f5c5SAndroid Build Coastguard Worker     float sin_t = sinf(theta);
85*8975f5c5SAndroid Build Coastguard Worker 
86*8975f5c5SAndroid Build Coastguard Worker     return Matrix4(cos_t + (u.x() * u.x() * (1.0f - cos_t)),
87*8975f5c5SAndroid Build Coastguard Worker                    (u.x() * u.y() * (1.0f - cos_t)) - (u.z() * sin_t),
88*8975f5c5SAndroid Build Coastguard Worker                    (u.x() * u.z() * (1.0f - cos_t)) + (u.y() * sin_t), 0.0f,
89*8975f5c5SAndroid Build Coastguard Worker                    (u.y() * u.x() * (1.0f - cos_t)) + (u.z() * sin_t),
90*8975f5c5SAndroid Build Coastguard Worker                    cos_t + (u.y() * u.y() * (1.0f - cos_t)),
91*8975f5c5SAndroid Build Coastguard Worker                    (u.y() * u.z() * (1.0f - cos_t)) - (u.x() * sin_t), 0.0f,
92*8975f5c5SAndroid Build Coastguard Worker                    (u.z() * u.x() * (1.0f - cos_t)) - (u.y() * sin_t),
93*8975f5c5SAndroid Build Coastguard Worker                    (u.z() * u.y() * (1.0f - cos_t)) + (u.x() * sin_t),
94*8975f5c5SAndroid Build Coastguard Worker                    cos_t + (u.z() * u.z() * (1.0f - cos_t)), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
95*8975f5c5SAndroid Build Coastguard Worker }
96*8975f5c5SAndroid Build Coastguard Worker 
translate(const Vector3 & t)97*8975f5c5SAndroid Build Coastguard Worker Matrix4 Matrix4::translate(const Vector3 &t)
98*8975f5c5SAndroid Build Coastguard Worker {
99*8975f5c5SAndroid Build Coastguard Worker     return Matrix4(1.0f, 0.0f, 0.0f, t.x(), 0.0f, 1.0f, 0.0f, t.y(), 0.0f, 0.0f, 1.0f, t.z(), 0.0f,
100*8975f5c5SAndroid Build Coastguard Worker                    0.0f, 0.0f, 1.0f);
101*8975f5c5SAndroid Build Coastguard Worker }
102*8975f5c5SAndroid Build Coastguard Worker 
scale(const Vector3 & s)103*8975f5c5SAndroid Build Coastguard Worker Matrix4 Matrix4::scale(const Vector3 &s)
104*8975f5c5SAndroid Build Coastguard Worker {
105*8975f5c5SAndroid Build Coastguard Worker     return Matrix4(s.x(), 0.0f, 0.0f, 0.0f, 0.0f, s.y(), 0.0f, 0.0f, 0.0f, 0.0f, s.z(), 0.0f, 0.0f,
106*8975f5c5SAndroid Build Coastguard Worker                    0.0f, 0.0f, 1.0f);
107*8975f5c5SAndroid Build Coastguard Worker }
108*8975f5c5SAndroid Build Coastguard Worker 
frustum(float l,float r,float b,float t,float n,float f)109*8975f5c5SAndroid Build Coastguard Worker Matrix4 Matrix4::frustum(float l, float r, float b, float t, float n, float f)
110*8975f5c5SAndroid Build Coastguard Worker {
111*8975f5c5SAndroid Build Coastguard Worker     return Matrix4((2.0f * n) / (r - l), 0.0f, (r + l) / (r - l), 0.0f, 0.0f, (2.0f * n) / (t - b),
112*8975f5c5SAndroid Build Coastguard Worker                    (t + b) / (t - b), 0.0f, 0.0f, 0.0f, -(f + n) / (f - n),
113*8975f5c5SAndroid Build Coastguard Worker                    -(2.0f * f * n) / (f - n), 0.0f, 0.0f, -1.0f, 0.0f);
114*8975f5c5SAndroid Build Coastguard Worker }
115*8975f5c5SAndroid Build Coastguard Worker 
perspective(float fovY,float aspectRatio,float nearZ,float farZ)116*8975f5c5SAndroid Build Coastguard Worker Matrix4 Matrix4::perspective(float fovY, float aspectRatio, float nearZ, float farZ)
117*8975f5c5SAndroid Build Coastguard Worker {
118*8975f5c5SAndroid Build Coastguard Worker     const float frustumHeight = tanf(static_cast<float>(fovY / 360.0f * M_PI)) * nearZ;
119*8975f5c5SAndroid Build Coastguard Worker     const float frustumWidth  = frustumHeight * aspectRatio;
120*8975f5c5SAndroid Build Coastguard Worker     return frustum(-frustumWidth, frustumWidth, -frustumHeight, frustumHeight, nearZ, farZ);
121*8975f5c5SAndroid Build Coastguard Worker }
122*8975f5c5SAndroid Build Coastguard Worker 
ortho(float l,float r,float b,float t,float n,float f)123*8975f5c5SAndroid Build Coastguard Worker Matrix4 Matrix4::ortho(float l, float r, float b, float t, float n, float f)
124*8975f5c5SAndroid Build Coastguard Worker {
125*8975f5c5SAndroid Build Coastguard Worker     return Matrix4(2.0f / (r - l), 0.0f, 0.0f, -(r + l) / (r - l), 0.0f, 2.0f / (t - b), 0.0f,
126*8975f5c5SAndroid Build Coastguard Worker                    -(t + b) / (t - b), 0.0f, 0.0f, -2.0f / (f - n), -(f + n) / (f - n), 0.0f, 0.0f,
127*8975f5c5SAndroid Build Coastguard Worker                    0.0f, 1.0f);
128*8975f5c5SAndroid Build Coastguard Worker }
129*8975f5c5SAndroid Build Coastguard Worker 
rollPitchYaw(float roll,float pitch,float yaw)130*8975f5c5SAndroid Build Coastguard Worker Matrix4 Matrix4::rollPitchYaw(float roll, float pitch, float yaw)
131*8975f5c5SAndroid Build Coastguard Worker {
132*8975f5c5SAndroid Build Coastguard Worker     return rotate(yaw, Vector3(0, 0, 1)) * rotate(pitch, Vector3(0, 1, 0)) *
133*8975f5c5SAndroid Build Coastguard Worker            rotate(roll, Vector3(1, 0, 0));
134*8975f5c5SAndroid Build Coastguard Worker }
135*8975f5c5SAndroid Build Coastguard Worker 
invert(const Matrix4 & mat)136*8975f5c5SAndroid Build Coastguard Worker Matrix4 Matrix4::invert(const Matrix4 &mat)
137*8975f5c5SAndroid Build Coastguard Worker {
138*8975f5c5SAndroid Build Coastguard Worker     Matrix4 inverted(
139*8975f5c5SAndroid Build Coastguard Worker         mat.data[5] * mat.data[10] * mat.data[15] - mat.data[5] * mat.data[11] * mat.data[14] -
140*8975f5c5SAndroid Build Coastguard Worker             mat.data[9] * mat.data[6] * mat.data[15] + mat.data[9] * mat.data[7] * mat.data[14] +
141*8975f5c5SAndroid Build Coastguard Worker             mat.data[13] * mat.data[6] * mat.data[11] - mat.data[13] * mat.data[7] * mat.data[10],
142*8975f5c5SAndroid Build Coastguard Worker         -mat.data[4] * mat.data[10] * mat.data[15] + mat.data[4] * mat.data[11] * mat.data[14] +
143*8975f5c5SAndroid Build Coastguard Worker             mat.data[8] * mat.data[6] * mat.data[15] - mat.data[8] * mat.data[7] * mat.data[14] -
144*8975f5c5SAndroid Build Coastguard Worker             mat.data[12] * mat.data[6] * mat.data[11] + mat.data[12] * mat.data[7] * mat.data[10],
145*8975f5c5SAndroid Build Coastguard Worker         mat.data[4] * mat.data[9] * mat.data[15] - mat.data[4] * mat.data[11] * mat.data[13] -
146*8975f5c5SAndroid Build Coastguard Worker             mat.data[8] * mat.data[5] * mat.data[15] + mat.data[8] * mat.data[7] * mat.data[13] +
147*8975f5c5SAndroid Build Coastguard Worker             mat.data[12] * mat.data[5] * mat.data[11] - mat.data[12] * mat.data[7] * mat.data[9],
148*8975f5c5SAndroid Build Coastguard Worker         -mat.data[4] * mat.data[9] * mat.data[14] + mat.data[4] * mat.data[10] * mat.data[13] +
149*8975f5c5SAndroid Build Coastguard Worker             mat.data[8] * mat.data[5] * mat.data[14] - mat.data[8] * mat.data[6] * mat.data[13] -
150*8975f5c5SAndroid Build Coastguard Worker             mat.data[12] * mat.data[5] * mat.data[10] + mat.data[12] * mat.data[6] * mat.data[9],
151*8975f5c5SAndroid Build Coastguard Worker         -mat.data[1] * mat.data[10] * mat.data[15] + mat.data[1] * mat.data[11] * mat.data[14] +
152*8975f5c5SAndroid Build Coastguard Worker             mat.data[9] * mat.data[2] * mat.data[15] - mat.data[9] * mat.data[3] * mat.data[14] -
153*8975f5c5SAndroid Build Coastguard Worker             mat.data[13] * mat.data[2] * mat.data[11] + mat.data[13] * mat.data[3] * mat.data[10],
154*8975f5c5SAndroid Build Coastguard Worker         mat.data[0] * mat.data[10] * mat.data[15] - mat.data[0] * mat.data[11] * mat.data[14] -
155*8975f5c5SAndroid Build Coastguard Worker             mat.data[8] * mat.data[2] * mat.data[15] + mat.data[8] * mat.data[3] * mat.data[14] +
156*8975f5c5SAndroid Build Coastguard Worker             mat.data[12] * mat.data[2] * mat.data[11] - mat.data[12] * mat.data[3] * mat.data[10],
157*8975f5c5SAndroid Build Coastguard Worker         -mat.data[0] * mat.data[9] * mat.data[15] + mat.data[0] * mat.data[11] * mat.data[13] +
158*8975f5c5SAndroid Build Coastguard Worker             mat.data[8] * mat.data[1] * mat.data[15] - mat.data[8] * mat.data[3] * mat.data[13] -
159*8975f5c5SAndroid Build Coastguard Worker             mat.data[12] * mat.data[1] * mat.data[11] + mat.data[12] * mat.data[3] * mat.data[9],
160*8975f5c5SAndroid Build Coastguard Worker         mat.data[0] * mat.data[9] * mat.data[14] - mat.data[0] * mat.data[10] * mat.data[13] -
161*8975f5c5SAndroid Build Coastguard Worker             mat.data[8] * mat.data[1] * mat.data[14] + mat.data[8] * mat.data[2] * mat.data[13] +
162*8975f5c5SAndroid Build Coastguard Worker             mat.data[12] * mat.data[1] * mat.data[10] - mat.data[12] * mat.data[2] * mat.data[9],
163*8975f5c5SAndroid Build Coastguard Worker         mat.data[1] * mat.data[6] * mat.data[15] - mat.data[1] * mat.data[7] * mat.data[14] -
164*8975f5c5SAndroid Build Coastguard Worker             mat.data[5] * mat.data[2] * mat.data[15] + mat.data[5] * mat.data[3] * mat.data[14] +
165*8975f5c5SAndroid Build Coastguard Worker             mat.data[13] * mat.data[2] * mat.data[7] - mat.data[13] * mat.data[3] * mat.data[6],
166*8975f5c5SAndroid Build Coastguard Worker         -mat.data[0] * mat.data[6] * mat.data[15] + mat.data[0] * mat.data[7] * mat.data[14] +
167*8975f5c5SAndroid Build Coastguard Worker             mat.data[4] * mat.data[2] * mat.data[15] - mat.data[4] * mat.data[3] * mat.data[14] -
168*8975f5c5SAndroid Build Coastguard Worker             mat.data[12] * mat.data[2] * mat.data[7] + mat.data[12] * mat.data[3] * mat.data[6],
169*8975f5c5SAndroid Build Coastguard Worker         mat.data[0] * mat.data[5] * mat.data[15] - mat.data[0] * mat.data[7] * mat.data[13] -
170*8975f5c5SAndroid Build Coastguard Worker             mat.data[4] * mat.data[1] * mat.data[15] + mat.data[4] * mat.data[3] * mat.data[13] +
171*8975f5c5SAndroid Build Coastguard Worker             mat.data[12] * mat.data[1] * mat.data[7] - mat.data[12] * mat.data[3] * mat.data[5],
172*8975f5c5SAndroid Build Coastguard Worker         -mat.data[0] * mat.data[5] * mat.data[14] + mat.data[0] * mat.data[6] * mat.data[13] +
173*8975f5c5SAndroid Build Coastguard Worker             mat.data[4] * mat.data[1] * mat.data[14] - mat.data[4] * mat.data[2] * mat.data[13] -
174*8975f5c5SAndroid Build Coastguard Worker             mat.data[12] * mat.data[1] * mat.data[6] + mat.data[12] * mat.data[2] * mat.data[5],
175*8975f5c5SAndroid Build Coastguard Worker         -mat.data[1] * mat.data[6] * mat.data[11] + mat.data[1] * mat.data[7] * mat.data[10] +
176*8975f5c5SAndroid Build Coastguard Worker             mat.data[5] * mat.data[2] * mat.data[11] - mat.data[5] * mat.data[3] * mat.data[10] -
177*8975f5c5SAndroid Build Coastguard Worker             mat.data[9] * mat.data[2] * mat.data[7] + mat.data[9] * mat.data[3] * mat.data[6],
178*8975f5c5SAndroid Build Coastguard Worker         mat.data[0] * mat.data[6] * mat.data[11] - mat.data[0] * mat.data[7] * mat.data[10] -
179*8975f5c5SAndroid Build Coastguard Worker             mat.data[4] * mat.data[2] * mat.data[11] + mat.data[4] * mat.data[3] * mat.data[10] +
180*8975f5c5SAndroid Build Coastguard Worker             mat.data[8] * mat.data[2] * mat.data[7] - mat.data[8] * mat.data[3] * mat.data[6],
181*8975f5c5SAndroid Build Coastguard Worker         -mat.data[0] * mat.data[5] * mat.data[11] + mat.data[0] * mat.data[7] * mat.data[9] +
182*8975f5c5SAndroid Build Coastguard Worker             mat.data[4] * mat.data[1] * mat.data[11] - mat.data[4] * mat.data[3] * mat.data[9] -
183*8975f5c5SAndroid Build Coastguard Worker             mat.data[8] * mat.data[1] * mat.data[7] + mat.data[8] * mat.data[3] * mat.data[5],
184*8975f5c5SAndroid Build Coastguard Worker         mat.data[0] * mat.data[5] * mat.data[10] - mat.data[0] * mat.data[6] * mat.data[9] -
185*8975f5c5SAndroid Build Coastguard Worker             mat.data[4] * mat.data[1] * mat.data[10] + mat.data[4] * mat.data[2] * mat.data[9] +
186*8975f5c5SAndroid Build Coastguard Worker             mat.data[8] * mat.data[1] * mat.data[6] - mat.data[8] * mat.data[2] * mat.data[5]);
187*8975f5c5SAndroid Build Coastguard Worker 
188*8975f5c5SAndroid Build Coastguard Worker     float determinant = mat.data[0] * inverted.data[0] + mat.data[1] * inverted.data[4] +
189*8975f5c5SAndroid Build Coastguard Worker                         mat.data[2] * inverted.data[8] + mat.data[3] * inverted.data[12];
190*8975f5c5SAndroid Build Coastguard Worker 
191*8975f5c5SAndroid Build Coastguard Worker     if (determinant != 0.0f)
192*8975f5c5SAndroid Build Coastguard Worker     {
193*8975f5c5SAndroid Build Coastguard Worker         inverted *= 1.0f / determinant;
194*8975f5c5SAndroid Build Coastguard Worker     }
195*8975f5c5SAndroid Build Coastguard Worker     else
196*8975f5c5SAndroid Build Coastguard Worker     {
197*8975f5c5SAndroid Build Coastguard Worker         inverted = identity();
198*8975f5c5SAndroid Build Coastguard Worker     }
199*8975f5c5SAndroid Build Coastguard Worker 
200*8975f5c5SAndroid Build Coastguard Worker     return inverted;
201*8975f5c5SAndroid Build Coastguard Worker }
202*8975f5c5SAndroid Build Coastguard Worker 
transpose(const Matrix4 & mat)203*8975f5c5SAndroid Build Coastguard Worker Matrix4 Matrix4::transpose(const Matrix4 &mat)
204*8975f5c5SAndroid Build Coastguard Worker {
205*8975f5c5SAndroid Build Coastguard Worker     return Matrix4(mat.data[0], mat.data[1], mat.data[2], mat.data[3], mat.data[4], mat.data[5],
206*8975f5c5SAndroid Build Coastguard Worker                    mat.data[6], mat.data[7], mat.data[8], mat.data[9], mat.data[10], mat.data[11],
207*8975f5c5SAndroid Build Coastguard Worker                    mat.data[12], mat.data[13], mat.data[14], mat.data[15]);
208*8975f5c5SAndroid Build Coastguard Worker }
209*8975f5c5SAndroid Build Coastguard Worker 
transform(const Matrix4 & mat,const Vector3 & pt)210*8975f5c5SAndroid Build Coastguard Worker Vector3 Matrix4::transform(const Matrix4 &mat, const Vector3 &pt)
211*8975f5c5SAndroid Build Coastguard Worker {
212*8975f5c5SAndroid Build Coastguard Worker     Vector4 transformed = (mat * Vector4(pt, 1.0f)).normalized();
213*8975f5c5SAndroid Build Coastguard Worker     return Vector3(transformed.x(), transformed.y(), transformed.z());
214*8975f5c5SAndroid Build Coastguard Worker }
215*8975f5c5SAndroid Build Coastguard Worker 
transform(const Matrix4 & mat,const Vector4 & pt)216*8975f5c5SAndroid Build Coastguard Worker Vector3 Matrix4::transform(const Matrix4 &mat, const Vector4 &pt)
217*8975f5c5SAndroid Build Coastguard Worker {
218*8975f5c5SAndroid Build Coastguard Worker     Vector4 transformed = (mat * pt).normalized();
219*8975f5c5SAndroid Build Coastguard Worker     return Vector3(transformed.x(), transformed.y(), transformed.z());
220*8975f5c5SAndroid Build Coastguard Worker }
221*8975f5c5SAndroid Build Coastguard Worker 
operator *(const Matrix4 & a,const Matrix4 & b)222*8975f5c5SAndroid Build Coastguard Worker Matrix4 operator*(const Matrix4 &a, const Matrix4 &b)
223*8975f5c5SAndroid Build Coastguard Worker {
224*8975f5c5SAndroid Build Coastguard Worker     return Matrix4(a.data[0] * b.data[0] + a.data[4] * b.data[1] + a.data[8] * b.data[2] +
225*8975f5c5SAndroid Build Coastguard Worker                        a.data[12] * b.data[3],
226*8975f5c5SAndroid Build Coastguard Worker                    a.data[0] * b.data[4] + a.data[4] * b.data[5] + a.data[8] * b.data[6] +
227*8975f5c5SAndroid Build Coastguard Worker                        a.data[12] * b.data[7],
228*8975f5c5SAndroid Build Coastguard Worker                    a.data[0] * b.data[8] + a.data[4] * b.data[9] + a.data[8] * b.data[10] +
229*8975f5c5SAndroid Build Coastguard Worker                        a.data[12] * b.data[11],
230*8975f5c5SAndroid Build Coastguard Worker                    a.data[0] * b.data[12] + a.data[4] * b.data[13] + a.data[8] * b.data[14] +
231*8975f5c5SAndroid Build Coastguard Worker                        a.data[12] * b.data[15],
232*8975f5c5SAndroid Build Coastguard Worker                    a.data[1] * b.data[0] + a.data[5] * b.data[1] + a.data[9] * b.data[2] +
233*8975f5c5SAndroid Build Coastguard Worker                        a.data[13] * b.data[3],
234*8975f5c5SAndroid Build Coastguard Worker                    a.data[1] * b.data[4] + a.data[5] * b.data[5] + a.data[9] * b.data[6] +
235*8975f5c5SAndroid Build Coastguard Worker                        a.data[13] * b.data[7],
236*8975f5c5SAndroid Build Coastguard Worker                    a.data[1] * b.data[8] + a.data[5] * b.data[9] + a.data[9] * b.data[10] +
237*8975f5c5SAndroid Build Coastguard Worker                        a.data[13] * b.data[11],
238*8975f5c5SAndroid Build Coastguard Worker                    a.data[1] * b.data[12] + a.data[5] * b.data[13] + a.data[9] * b.data[14] +
239*8975f5c5SAndroid Build Coastguard Worker                        a.data[13] * b.data[15],
240*8975f5c5SAndroid Build Coastguard Worker                    a.data[2] * b.data[0] + a.data[6] * b.data[1] + a.data[10] * b.data[2] +
241*8975f5c5SAndroid Build Coastguard Worker                        a.data[14] * b.data[3],
242*8975f5c5SAndroid Build Coastguard Worker                    a.data[2] * b.data[4] + a.data[6] * b.data[5] + a.data[10] * b.data[6] +
243*8975f5c5SAndroid Build Coastguard Worker                        a.data[14] * b.data[7],
244*8975f5c5SAndroid Build Coastguard Worker                    a.data[2] * b.data[8] + a.data[6] * b.data[9] + a.data[10] * b.data[10] +
245*8975f5c5SAndroid Build Coastguard Worker                        a.data[14] * b.data[11],
246*8975f5c5SAndroid Build Coastguard Worker                    a.data[2] * b.data[12] + a.data[6] * b.data[13] + a.data[10] * b.data[14] +
247*8975f5c5SAndroid Build Coastguard Worker                        a.data[14] * b.data[15],
248*8975f5c5SAndroid Build Coastguard Worker                    a.data[3] * b.data[0] + a.data[7] * b.data[1] + a.data[11] * b.data[2] +
249*8975f5c5SAndroid Build Coastguard Worker                        a.data[15] * b.data[3],
250*8975f5c5SAndroid Build Coastguard Worker                    a.data[3] * b.data[4] + a.data[7] * b.data[5] + a.data[11] * b.data[6] +
251*8975f5c5SAndroid Build Coastguard Worker                        a.data[15] * b.data[7],
252*8975f5c5SAndroid Build Coastguard Worker                    a.data[3] * b.data[8] + a.data[7] * b.data[9] + a.data[11] * b.data[10] +
253*8975f5c5SAndroid Build Coastguard Worker                        a.data[15] * b.data[11],
254*8975f5c5SAndroid Build Coastguard Worker                    a.data[3] * b.data[12] + a.data[7] * b.data[13] + a.data[11] * b.data[14] +
255*8975f5c5SAndroid Build Coastguard Worker                        a.data[15] * b.data[15]);
256*8975f5c5SAndroid Build Coastguard Worker }
257*8975f5c5SAndroid Build Coastguard Worker 
operator *=(Matrix4 & a,const Matrix4 & b)258*8975f5c5SAndroid Build Coastguard Worker Matrix4 &operator*=(Matrix4 &a, const Matrix4 &b)
259*8975f5c5SAndroid Build Coastguard Worker {
260*8975f5c5SAndroid Build Coastguard Worker     a = a * b;
261*8975f5c5SAndroid Build Coastguard Worker     return a;
262*8975f5c5SAndroid Build Coastguard Worker }
263*8975f5c5SAndroid Build Coastguard Worker 
operator *(const Matrix4 & a,float b)264*8975f5c5SAndroid Build Coastguard Worker Matrix4 operator*(const Matrix4 &a, float b)
265*8975f5c5SAndroid Build Coastguard Worker {
266*8975f5c5SAndroid Build Coastguard Worker     Matrix4 ret(a);
267*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < 16; i++)
268*8975f5c5SAndroid Build Coastguard Worker     {
269*8975f5c5SAndroid Build Coastguard Worker         ret.data[i] *= b;
270*8975f5c5SAndroid Build Coastguard Worker     }
271*8975f5c5SAndroid Build Coastguard Worker     return ret;
272*8975f5c5SAndroid Build Coastguard Worker }
273*8975f5c5SAndroid Build Coastguard Worker 
operator *=(Matrix4 & a,float b)274*8975f5c5SAndroid Build Coastguard Worker Matrix4 &operator*=(Matrix4 &a, float b)
275*8975f5c5SAndroid Build Coastguard Worker {
276*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < 16; i++)
277*8975f5c5SAndroid Build Coastguard Worker     {
278*8975f5c5SAndroid Build Coastguard Worker         a.data[i] *= b;
279*8975f5c5SAndroid Build Coastguard Worker     }
280*8975f5c5SAndroid Build Coastguard Worker     return a;
281*8975f5c5SAndroid Build Coastguard Worker }
282*8975f5c5SAndroid Build Coastguard Worker 
operator *(const Matrix4 & a,const Vector4 & b)283*8975f5c5SAndroid Build Coastguard Worker Vector4 operator*(const Matrix4 &a, const Vector4 &b)
284*8975f5c5SAndroid Build Coastguard Worker {
285*8975f5c5SAndroid Build Coastguard Worker     return Vector4(a.data[0] * b.x() + a.data[4] * b.y() + a.data[8] * b.z() + a.data[12] * b.w(),
286*8975f5c5SAndroid Build Coastguard Worker                    a.data[1] * b.x() + a.data[5] * b.y() + a.data[9] * b.z() + a.data[13] * b.w(),
287*8975f5c5SAndroid Build Coastguard Worker                    a.data[2] * b.x() + a.data[6] * b.y() + a.data[10] * b.z() + a.data[14] * b.w(),
288*8975f5c5SAndroid Build Coastguard Worker                    a.data[3] * b.x() + a.data[7] * b.y() + a.data[11] * b.z() + a.data[15] * b.w());
289*8975f5c5SAndroid Build Coastguard Worker }
290*8975f5c5SAndroid Build Coastguard Worker 
operator ==(const Matrix4 & a,const Matrix4 & b)291*8975f5c5SAndroid Build Coastguard Worker bool operator==(const Matrix4 &a, const Matrix4 &b)
292*8975f5c5SAndroid Build Coastguard Worker {
293*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < 16; i++)
294*8975f5c5SAndroid Build Coastguard Worker     {
295*8975f5c5SAndroid Build Coastguard Worker         if (a.data[i] != b.data[i])
296*8975f5c5SAndroid Build Coastguard Worker         {
297*8975f5c5SAndroid Build Coastguard Worker             return false;
298*8975f5c5SAndroid Build Coastguard Worker         }
299*8975f5c5SAndroid Build Coastguard Worker     }
300*8975f5c5SAndroid Build Coastguard Worker     return true;
301*8975f5c5SAndroid Build Coastguard Worker }
302*8975f5c5SAndroid Build Coastguard Worker 
operator !=(const Matrix4 & a,const Matrix4 & b)303*8975f5c5SAndroid Build Coastguard Worker bool operator!=(const Matrix4 &a, const Matrix4 &b)
304*8975f5c5SAndroid Build Coastguard Worker {
305*8975f5c5SAndroid Build Coastguard Worker     return !(a == b);
306*8975f5c5SAndroid Build Coastguard Worker }
307