| // |
| // Copyright 2018 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| |
| // matrix_utils.cpp: Contains implementations for Mat4 methods. |
| |
| #include "common/matrix_utils.h" |
| |
| namespace angle |
| { |
| |
| 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) |
| {} |
| |
| Mat4::Mat4(const Matrix<float> generalMatrix) : Matrix(std::vector<float>(16, 0), 4, 4) |
| { |
| unsigned int minCols = std::min((unsigned int)4, generalMatrix.columns()); |
| unsigned int minRows = std::min((unsigned int)4, generalMatrix.rows()); |
| for (unsigned int i = 0; i < minCols; i++) |
| { |
| for (unsigned int j = 0; j < minRows; j++) |
| { |
| mElements[j * minCols + i] = generalMatrix.at(j, i); |
| } |
| } |
| } |
| |
| Mat4::Mat4(const std::vector<float> &elements) : Matrix(elements, 4) {} |
| |
| Mat4::Mat4(const float *elements) : Matrix(elements, 4) {} |
| |
| Mat4::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) |
| : Matrix(std::vector<float>(16, 0), 4, 4) |
| { |
| mElements[0] = m00; |
| mElements[1] = m01; |
| mElements[2] = m02; |
| mElements[3] = m03; |
| mElements[4] = m10; |
| mElements[5] = m11; |
| mElements[6] = m12; |
| mElements[7] = m13; |
| mElements[8] = m20; |
| mElements[9] = m21; |
| mElements[10] = m22; |
| mElements[11] = m23; |
| mElements[12] = m30; |
| mElements[13] = m31; |
| mElements[14] = m32; |
| mElements[15] = m33; |
| } |
| |
| // static |
| Mat4 Mat4::Rotate(float angle, const Vector3 &axis) |
| { |
| auto axis_normalized = axis.normalized(); |
| float angle_radians = angle * (3.14159265358979323f / 180.0f); |
| float c = cos(angle_radians); |
| float ci = 1.f - c; |
| float s = sin(angle_radians); |
| |
| float x = axis_normalized.x(); |
| float y = axis_normalized.y(); |
| float z = axis_normalized.z(); |
| |
| float x2 = x * x; |
| float y2 = y * y; |
| float z2 = z * z; |
| |
| float xy = x * y; |
| float yz = y * z; |
| float zx = z * x; |
| |
| float r00 = c + ci * x2; |
| float r01 = ci * xy + s * z; |
| float r02 = ci * zx - s * y; |
| float r03 = 0.f; |
| |
| float r10 = ci * xy - s * z; |
| float r11 = c + ci * y2; |
| float r12 = ci * yz + s * x; |
| float r13 = 0.f; |
| |
| float r20 = ci * zx + s * y; |
| float r21 = ci * yz - s * x; |
| float r22 = c + ci * z2; |
| float r23 = 0.f; |
| |
| float r30 = 0.f; |
| float r31 = 0.f; |
| float r32 = 0.f; |
| float r33 = 1.f; |
| |
| return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33); |
| } |
| |
| // static |
| Mat4 Mat4::Translate(const Vector3 &t) |
| { |
| float r00 = 1.f; |
| float r01 = 0.f; |
| float r02 = 0.f; |
| float r03 = 0.f; |
| |
| float r10 = 0.f; |
| float r11 = 1.f; |
| float r12 = 0.f; |
| float r13 = 0.f; |
| |
| float r20 = 0.f; |
| float r21 = 0.f; |
| float r22 = 1.f; |
| float r23 = 0.f; |
| |
| float r30 = t.x(); |
| float r31 = t.y(); |
| float r32 = t.z(); |
| float r33 = 1.f; |
| |
| return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33); |
| } |
| |
| // static |
| Mat4 Mat4::Scale(const Vector3 &s) |
| { |
| float r00 = s.x(); |
| float r01 = 0.f; |
| float r02 = 0.f; |
| float r03 = 0.f; |
| |
| float r10 = 0.f; |
| float r11 = s.y(); |
| float r12 = 0.f; |
| float r13 = 0.f; |
| |
| float r20 = 0.f; |
| float r21 = 0.f; |
| float r22 = s.z(); |
| float r23 = 0.f; |
| |
| float r30 = 0.f; |
| float r31 = 0.f; |
| float r32 = 0.f; |
| float r33 = 1.f; |
| |
| return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33); |
| } |
| |
| // static |
| Mat4 Mat4::Frustum(float l, float r, float b, float t, float n, float f) |
| { |
| float nn = 2.f * n; |
| float fpn = f + n; |
| float fmn = f - n; |
| float tpb = t + b; |
| float tmb = t - b; |
| float rpl = r + l; |
| float rml = r - l; |
| |
| float r00 = nn / rml; |
| float r01 = 0.f; |
| float r02 = 0.f; |
| float r03 = 0.f; |
| |
| float r10 = 0.f; |
| float r11 = nn / tmb; |
| float r12 = 0.f; |
| float r13 = 0.f; |
| |
| float r20 = rpl / rml; |
| float r21 = tpb / tmb; |
| float r22 = -fpn / fmn; |
| float r23 = -1.f; |
| |
| float r30 = 0.f; |
| float r31 = 0.f; |
| float r32 = -nn * f / fmn; |
| float r33 = 0.f; |
| |
| return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33); |
| } |
| |
| // static |
| Mat4 Mat4::Perspective(float fov, float aspectRatio, float n, float f) |
| { |
| const float frustumHeight = tanf(static_cast<float>(fov / 360.0f * 3.14159265358979323)) * n; |
| const float frustumWidth = frustumHeight * aspectRatio; |
| return Frustum(-frustumWidth, frustumWidth, -frustumHeight, frustumHeight, n, f); |
| } |
| |
| // static |
| Mat4 Mat4::Ortho(float l, float r, float b, float t, float n, float f) |
| { |
| float fpn = f + n; |
| float fmn = f - n; |
| float tpb = t + b; |
| float tmb = t - b; |
| float rpl = r + l; |
| float rml = r - l; |
| |
| float r00 = 2.f / rml; |
| float r01 = 0.f; |
| float r02 = 0.f; |
| float r03 = 0.f; |
| |
| float r10 = 0.f; |
| float r11 = 2.f / tmb; |
| float r12 = 0.f; |
| float r13 = 0.f; |
| |
| float r20 = 0.f; |
| float r21 = 0.f; |
| float r22 = -2.f / fmn; |
| float r23 = 0.f; |
| |
| float r30 = -rpl / rml; |
| float r31 = -tpb / tmb; |
| float r32 = -fpn / fmn; |
| float r33 = 1.f; |
| |
| return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33); |
| } |
| |
| Mat4 Mat4::product(const Mat4 &m) |
| { |
| const float *a = mElements.data(); |
| const float *b = m.mElements.data(); |
| |
| return Mat4(a[0] * b[0] + a[4] * b[1] + a[8] * b[2] + a[12] * b[3], |
| a[1] * b[0] + a[5] * b[1] + a[9] * b[2] + a[13] * b[3], |
| a[2] * b[0] + a[6] * b[1] + a[10] * b[2] + a[14] * b[3], |
| a[3] * b[0] + a[7] * b[1] + a[11] * b[2] + a[15] * b[3], |
| |
| a[0] * b[4] + a[4] * b[5] + a[8] * b[6] + a[12] * b[7], |
| a[1] * b[4] + a[5] * b[5] + a[9] * b[6] + a[13] * b[7], |
| a[2] * b[4] + a[6] * b[5] + a[10] * b[6] + a[14] * b[7], |
| a[3] * b[4] + a[7] * b[5] + a[11] * b[6] + a[15] * b[7], |
| |
| a[0] * b[8] + a[4] * b[9] + a[8] * b[10] + a[12] * b[11], |
| a[1] * b[8] + a[5] * b[9] + a[9] * b[10] + a[13] * b[11], |
| a[2] * b[8] + a[6] * b[9] + a[10] * b[10] + a[14] * b[11], |
| a[3] * b[8] + a[7] * b[9] + a[11] * b[10] + a[15] * b[11], |
| |
| a[0] * b[12] + a[4] * b[13] + a[8] * b[14] + a[12] * b[15], |
| a[1] * b[12] + a[5] * b[13] + a[9] * b[14] + a[13] * b[15], |
| a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14] * b[15], |
| a[3] * b[12] + a[7] * b[13] + a[11] * b[14] + a[15] * b[15]); |
| } |
| |
| Vector4 Mat4::product(const Vector4 &b) |
| { |
| return Vector4( |
| mElements[0] * b.x() + mElements[4] * b.y() + mElements[8] * b.z() + mElements[12] * b.w(), |
| mElements[1] * b.x() + mElements[5] * b.y() + mElements[9] * b.z() + mElements[13] * b.w(), |
| mElements[2] * b.x() + mElements[6] * b.y() + mElements[10] * b.z() + mElements[14] * b.w(), |
| mElements[3] * b.x() + mElements[7] * b.y() + mElements[11] * b.z() + |
| mElements[15] * b.w()); |
| } |
| |
| void Mat4::dump() |
| { |
| printf("[ %f %f %f %f ]\n", mElements[0], mElements[4], mElements[8], mElements[12]); |
| printf("[ %f %f %f %f ]\n", mElements[1], mElements[5], mElements[9], mElements[13]); |
| printf("[ %f %f %f %f ]\n", mElements[2], mElements[6], mElements[10], mElements[14]); |
| printf("[ %f %f %f %f ]\n", mElements[3], mElements[7], mElements[11], mElements[15]); |
| } |
| |
| } // namespace angle |