2 // Copyright (c) 2014 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.
7 // Helper class for doing matrix math.
12 #define _USE_MATH_DEFINES
16 using namespace angle;
38 Matrix4::Matrix4(float m00,
73 Matrix4 Matrix4::identity()
75 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,
79 Matrix4 Matrix4::rotate(float angle, const Vector3 &p)
81 Vector3 u = p.normalized();
82 float theta = static_cast<float>(angle * (M_PI / 180.0f));
83 float cos_t = cosf(theta);
84 float sin_t = sinf(theta);
86 return Matrix4(cos_t + (u.x() * u.x() * (1.0f - cos_t)),
87 (u.x() * u.y() * (1.0f - cos_t)) - (u.z() * sin_t),
88 (u.x() * u.z() * (1.0f - cos_t)) + (u.y() * sin_t), 0.0f,
89 (u.y() * u.x() * (1.0f - cos_t)) + (u.z() * sin_t),
90 cos_t + (u.y() * u.y() * (1.0f - cos_t)),
91 (u.y() * u.z() * (1.0f - cos_t)) - (u.x() * sin_t), 0.0f,
92 (u.z() * u.x() * (1.0f - cos_t)) - (u.y() * sin_t),
93 (u.z() * u.y() * (1.0f - cos_t)) + (u.x() * sin_t),
94 cos_t + (u.z() * u.z() * (1.0f - cos_t)), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
97 Matrix4 Matrix4::translate(const Vector3 &t)
99 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,
103 Matrix4 Matrix4::scale(const Vector3 &s)
105 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,
109 Matrix4 Matrix4::frustum(float l, float r, float b, float t, float n, float f)
111 return Matrix4((2.0f * n) / (r - l), 0.0f, (r + l) / (r - l), 0.0f, 0.0f, (2.0f * n) / (t - b),
112 (t + b) / (t - b), 0.0f, 0.0f, 0.0f, -(f + n) / (f - n),
113 -(2.0f * f * n) / (f - n), 0.0f, 0.0f, -1.0f, 0.0f);
116 Matrix4 Matrix4::perspective(float fovY, float aspectRatio, float nearZ, float farZ)
118 const float frustumHeight = tanf(static_cast<float>(fovY / 360.0f * M_PI)) * nearZ;
119 const float frustumWidth = frustumHeight * aspectRatio;
120 return frustum(-frustumWidth, frustumWidth, -frustumHeight, frustumHeight, nearZ, farZ);
123 Matrix4 Matrix4::ortho(float l, float r, float b, float t, float n, float f)
125 return Matrix4(2.0f / (r - l), 0.0f, 0.0f, -(r + l) / (r - l), 0.0f, 2.0f / (t - b), 0.0f,
126 -(t + b) / (t - b), 0.0f, 0.0f, -2.0f / (f - n), -(f + n) / (f - n), 0.0f, 0.0f,
130 Matrix4 Matrix4::rollPitchYaw(float roll, float pitch, float yaw)
132 return rotate(yaw, Vector3(0, 0, 1)) * rotate(pitch, Vector3(0, 1, 0)) *
133 rotate(roll, Vector3(1, 0, 0));
136 Matrix4 Matrix4::invert(const Matrix4 &mat)
139 mat.data[5] * mat.data[10] * mat.data[15] - mat.data[5] * mat.data[11] * mat.data[14] -
140 mat.data[9] * mat.data[6] * mat.data[15] + mat.data[9] * mat.data[7] * mat.data[14] +
141 mat.data[13] * mat.data[6] * mat.data[11] - mat.data[13] * mat.data[7] * mat.data[10],
142 -mat.data[4] * mat.data[10] * mat.data[15] + mat.data[4] * mat.data[11] * mat.data[14] +
143 mat.data[8] * mat.data[6] * mat.data[15] - mat.data[8] * mat.data[7] * mat.data[14] -
144 mat.data[12] * mat.data[6] * mat.data[11] + mat.data[12] * mat.data[7] * mat.data[10],
145 mat.data[4] * mat.data[9] * mat.data[15] - mat.data[4] * mat.data[11] * mat.data[13] -
146 mat.data[8] * mat.data[5] * mat.data[15] + mat.data[8] * mat.data[7] * mat.data[13] +
147 mat.data[12] * mat.data[5] * mat.data[11] - mat.data[12] * mat.data[7] * mat.data[9],
148 -mat.data[4] * mat.data[9] * mat.data[14] + mat.data[4] * mat.data[10] * mat.data[13] +
149 mat.data[8] * mat.data[5] * mat.data[14] - mat.data[8] * mat.data[6] * mat.data[13] -
150 mat.data[12] * mat.data[5] * mat.data[10] + mat.data[12] * mat.data[6] * mat.data[9],
151 -mat.data[1] * mat.data[10] * mat.data[15] + mat.data[1] * mat.data[11] * mat.data[14] +
152 mat.data[9] * mat.data[2] * mat.data[15] - mat.data[9] * mat.data[3] * mat.data[14] -
153 mat.data[13] * mat.data[2] * mat.data[11] + mat.data[13] * mat.data[3] * mat.data[10],
154 mat.data[0] * mat.data[10] * mat.data[15] - mat.data[0] * mat.data[11] * mat.data[14] -
155 mat.data[8] * mat.data[2] * mat.data[15] + mat.data[8] * mat.data[3] * mat.data[14] +
156 mat.data[12] * mat.data[2] * mat.data[11] - mat.data[12] * mat.data[3] * mat.data[10],
157 -mat.data[0] * mat.data[9] * mat.data[15] + mat.data[0] * mat.data[11] * mat.data[13] +
158 mat.data[8] * mat.data[1] * mat.data[15] - mat.data[8] * mat.data[3] * mat.data[13] -
159 mat.data[12] * mat.data[1] * mat.data[11] + mat.data[12] * mat.data[3] * mat.data[9],
160 mat.data[0] * mat.data[9] * mat.data[14] - mat.data[0] * mat.data[10] * mat.data[13] -
161 mat.data[8] * mat.data[1] * mat.data[14] + mat.data[8] * mat.data[2] * mat.data[13] +
162 mat.data[12] * mat.data[1] * mat.data[10] - mat.data[12] * mat.data[2] * mat.data[9],
163 mat.data[1] * mat.data[6] * mat.data[15] - mat.data[1] * mat.data[7] * mat.data[14] -
164 mat.data[5] * mat.data[2] * mat.data[15] + mat.data[5] * mat.data[3] * mat.data[14] +
165 mat.data[13] * mat.data[2] * mat.data[7] - mat.data[13] * mat.data[3] * mat.data[6],
166 -mat.data[0] * mat.data[6] * mat.data[15] + mat.data[0] * mat.data[7] * mat.data[14] +
167 mat.data[4] * mat.data[2] * mat.data[15] - mat.data[4] * mat.data[3] * mat.data[14] -
168 mat.data[12] * mat.data[2] * mat.data[7] + mat.data[12] * mat.data[3] * mat.data[6],
169 mat.data[0] * mat.data[5] * mat.data[15] - mat.data[0] * mat.data[7] * mat.data[13] -
170 mat.data[4] * mat.data[1] * mat.data[15] + mat.data[4] * mat.data[3] * mat.data[13] +
171 mat.data[12] * mat.data[1] * mat.data[7] - mat.data[12] * mat.data[3] * mat.data[5],
172 -mat.data[0] * mat.data[5] * mat.data[14] + mat.data[0] * mat.data[6] * mat.data[13] +
173 mat.data[4] * mat.data[1] * mat.data[14] - mat.data[4] * mat.data[2] * mat.data[13] -
174 mat.data[12] * mat.data[1] * mat.data[6] + mat.data[12] * mat.data[2] * mat.data[5],
175 -mat.data[1] * mat.data[6] * mat.data[11] + mat.data[1] * mat.data[7] * mat.data[10] +
176 mat.data[5] * mat.data[2] * mat.data[11] - mat.data[5] * mat.data[3] * mat.data[10] -
177 mat.data[9] * mat.data[2] * mat.data[7] + mat.data[9] * mat.data[3] * mat.data[6],
178 mat.data[0] * mat.data[6] * mat.data[11] - mat.data[0] * mat.data[7] * mat.data[10] -
179 mat.data[4] * mat.data[2] * mat.data[11] + mat.data[4] * mat.data[3] * mat.data[10] +
180 mat.data[8] * mat.data[2] * mat.data[7] - mat.data[8] * mat.data[3] * mat.data[6],
181 -mat.data[0] * mat.data[5] * mat.data[11] + mat.data[0] * mat.data[7] * mat.data[9] +
182 mat.data[4] * mat.data[1] * mat.data[11] - mat.data[4] * mat.data[3] * mat.data[9] -
183 mat.data[8] * mat.data[1] * mat.data[7] + mat.data[8] * mat.data[3] * mat.data[5],
184 mat.data[0] * mat.data[5] * mat.data[10] - mat.data[0] * mat.data[6] * mat.data[9] -
185 mat.data[4] * mat.data[1] * mat.data[10] + mat.data[4] * mat.data[2] * mat.data[9] +
186 mat.data[8] * mat.data[1] * mat.data[6] - mat.data[8] * mat.data[2] * mat.data[5]);
188 float determinant = mat.data[0] * inverted.data[0] + mat.data[1] * inverted.data[4] +
189 mat.data[2] * inverted.data[8] + mat.data[3] * inverted.data[12];
191 if (determinant != 0.0f)
193 inverted *= 1.0f / determinant;
197 inverted = identity();
203 Matrix4 Matrix4::transpose(const Matrix4 &mat)
205 return Matrix4(mat.data[0], mat.data[1], mat.data[2], mat.data[3], mat.data[4], mat.data[5],
206 mat.data[6], mat.data[7], mat.data[8], mat.data[9], mat.data[10], mat.data[11],
207 mat.data[12], mat.data[13], mat.data[14], mat.data[15]);
210 Vector3 Matrix4::transform(const Matrix4 &mat, const Vector3 &pt)
212 Vector4 transformed = (mat * Vector4(pt, 1.0f)).normalized();
213 return Vector3(transformed.x(), transformed.y(), transformed.z());
216 Vector3 Matrix4::transform(const Matrix4 &mat, const Vector4 &pt)
218 Vector4 transformed = (mat * pt).normalized();
219 return Vector3(transformed.x(), transformed.y(), transformed.z());
222 Matrix4 operator*(const Matrix4 &a, const Matrix4 &b)
224 return Matrix4(a.data[0] * b.data[0] + a.data[4] * b.data[1] + a.data[8] * b.data[2] +
225 a.data[12] * b.data[3],
226 a.data[0] * b.data[4] + a.data[4] * b.data[5] + a.data[8] * b.data[6] +
227 a.data[12] * b.data[7],
228 a.data[0] * b.data[8] + a.data[4] * b.data[9] + a.data[8] * b.data[10] +
229 a.data[12] * b.data[11],
230 a.data[0] * b.data[12] + a.data[4] * b.data[13] + a.data[8] * b.data[14] +
231 a.data[12] * b.data[15],
232 a.data[1] * b.data[0] + a.data[5] * b.data[1] + a.data[9] * b.data[2] +
233 a.data[13] * b.data[3],
234 a.data[1] * b.data[4] + a.data[5] * b.data[5] + a.data[9] * b.data[6] +
235 a.data[13] * b.data[7],
236 a.data[1] * b.data[8] + a.data[5] * b.data[9] + a.data[9] * b.data[10] +
237 a.data[13] * b.data[11],
238 a.data[1] * b.data[12] + a.data[5] * b.data[13] + a.data[9] * b.data[14] +
239 a.data[13] * b.data[15],
240 a.data[2] * b.data[0] + a.data[6] * b.data[1] + a.data[10] * b.data[2] +
241 a.data[14] * b.data[3],
242 a.data[2] * b.data[4] + a.data[6] * b.data[5] + a.data[10] * b.data[6] +
243 a.data[14] * b.data[7],
244 a.data[2] * b.data[8] + a.data[6] * b.data[9] + a.data[10] * b.data[10] +
245 a.data[14] * b.data[11],
246 a.data[2] * b.data[12] + a.data[6] * b.data[13] + a.data[10] * b.data[14] +
247 a.data[14] * b.data[15],
248 a.data[3] * b.data[0] + a.data[7] * b.data[1] + a.data[11] * b.data[2] +
249 a.data[15] * b.data[3],
250 a.data[3] * b.data[4] + a.data[7] * b.data[5] + a.data[11] * b.data[6] +
251 a.data[15] * b.data[7],
252 a.data[3] * b.data[8] + a.data[7] * b.data[9] + a.data[11] * b.data[10] +
253 a.data[15] * b.data[11],
254 a.data[3] * b.data[12] + a.data[7] * b.data[13] + a.data[11] * b.data[14] +
255 a.data[15] * b.data[15]);
258 Matrix4 &operator*=(Matrix4 &a, const Matrix4 &b)
264 Matrix4 operator*(const Matrix4 &a, float b)
267 for (size_t i = 0; i < 16; i++)
274 Matrix4 &operator*=(Matrix4 &a, float b)
276 for (size_t i = 0; i < 16; i++)
283 Vector4 operator*(const Matrix4 &a, const Vector4 &b)
285 return Vector4(a.data[0] * b.x() + a.data[4] * b.y() + a.data[8] * b.z() + a.data[12] * b.w(),
286 a.data[1] * b.x() + a.data[5] * b.y() + a.data[9] * b.z() + a.data[13] * b.w(),
287 a.data[2] * b.x() + a.data[6] * b.y() + a.data[10] * b.z() + a.data[14] * b.w(),
288 a.data[3] * b.x() + a.data[7] * b.y() + a.data[11] * b.z() + a.data[15] * b.w());
291 bool operator==(const Matrix4 &a, const Matrix4 &b)
293 for (size_t i = 0; i < 16; i++)
295 if (a.data[i] != b.data[i])
303 bool operator!=(const Matrix4 &a, const Matrix4 &b)