#include "tempest/matrix/C34Matrix.hpp" #include "tempest/vector/C3Vector.hpp" #include "tempest/matrix/C33Matrix.hpp" #include "tempest/quaternion/C4Quaternion.hpp" #include "tempest/math/CMath.hpp" C34Matrix C34Matrix::Rotation(float angle, const C3Vector& axis, bool unit) { C3Vector axis_ = axis; if (!unit) { axis_.Normalize(); } STORM_ASSERT(axis_.IsUnit()); float sina = CMath::sin(angle); float cosa = CMath::cos(angle); float xs = axis_.x * sina; float ys = axis_.y * sina; float zs = axis_.z * sina; float one_c = 1.0f - cosa; // https://en.wikipedia.org/wiki/Rotation_matrix // Rotation matrix from axis and angle C34Matrix result; result.a0 = axis_.x * axis_.x * one_c + cosa; result.a1 = axis_.x * axis_.y * one_c + zs; result.a2 = axis_.x * axis_.z * one_c - ys; result.b0 = axis_.x * axis_.y * one_c - zs; result.b1 = axis_.y * axis_.y * one_c + cosa; result.b2 = axis_.y * axis_.z * one_c + xs; result.c0 = axis_.x * axis_.z * one_c + ys; result.c1 = axis_.y * axis_.z * one_c - xs; result.c2 = axis_.z * axis_.z * one_c + cosa; result.d0 = 0.0f; result.d1 = 0.0f; result.d2 = 0.0f; return result; } C34Matrix::C34Matrix(const C3Vector& r0, const C3Vector& r1, const C3Vector& r2, const C3Vector& r3) : a0(r0.x) , a1(r0.y) , a2(r0.z) , b0(r1.x) , b1(r1.y) , b2(r1.z) , c0(r2.x) , c1(r2.y) , c2(r2.z) , d0(r3.x) , d1(r3.y) , d2(r3.z) { } C34Matrix::C34Matrix(const C3Vector& r0, const C3Vector& r1, const C3Vector& r2) : a0(r0.x) , a1(r0.y) , a2(r0.z) , b0(r1.x) , b1(r1.y) , b2(r1.z) , c0(r2.x) , c1(r2.y) , c2(r2.z) , d0(0.0f) , d1(0.0f) , d2(0.0f) { } C34Matrix::C34Matrix(const C33Matrix& m) : a0(m.a0) , a1(m.a1) , a2(m.a2) , b0(m.b0) , b1(m.b1) , b2(m.b2) , c0(m.c0) , c1(m.c1) , c2(m.c2) , d0(0.0f) , d1(0.0f) , d2(0.0f) { } C34Matrix::C34Matrix(float a0, float a1, float a2, float b0, float b1, float b2, float c0, float c1, float c2, float d0, float d1, float d2) : a0(a0) , a1(a1) , a2(a2) , b0(b0) , b1(b1) , b2(b2) , c0(c0) , c1(c1) , c2(c2) , d0(d0) , d1(d1) , d2(d2) { } C34Matrix::C34Matrix(float a) : a0(a) , a1(a) , a2(a) , b0(a) , b1(a) , b2(a) , c0(a) , c1(a) , c2(a) , d0(a) , d1(a) , d2(a) { } C34Matrix& C34Matrix::operator+=(const C34Matrix& a) { this->a0 += a.a0; this->a1 += a.a1; this->a2 += a.a2; this->b0 += a.b0; this->b1 += a.b1; this->b2 += a.b2; this->c0 += a.c0; this->c1 += a.c1; this->c2 += a.c2; this->d0 += a.d0; this->d1 += a.d1; this->d2 += a.d2; return *this; } C34Matrix& C34Matrix::operator-=(const C34Matrix& a) { this->a0 -= a.a0; this->a1 -= a.a1; this->a2 -= a.a2; this->b0 -= a.b0; this->b1 -= a.b1; this->b2 -= a.b2; this->c0 -= a.c0; this->c1 -= a.c1; this->c2 -= a.c2; this->d0 -= a.d0; this->d1 -= a.d1; this->d2 -= a.d2; return *this; } C34Matrix& C34Matrix::operator*=(float a) { this->a0 *= a; this->a1 *= a; this->a2 *= a; this->b0 *= a; this->b1 *= a; this->b2 *= a; this->c0 *= a; this->c1 *= a; this->c2 *= a; this->d0 *= a; this->d1 *= a; this->d2 *= a; return *this; } C34Matrix& C34Matrix::operator*=(const C34Matrix& a) { *this = *this * a; return *this; } C34Matrix& C34Matrix::operator/=(float a) { this->a0 /= a; this->a1 /= a; this->a2 /= a; this->b0 /= a; this->b1 /= a; this->b2 /= a; this->c0 /= a; this->c1 /= a; this->c2 /= a; this->d0 /= a; this->d1 /= a; this->d2 /= a; return *this; } void C34Matrix::Zero() { this->a0 = 0.0f; this->a1 = 0.0f; this->a2 = 0.0f; this->b0 = 0.0f; this->b1 = 0.0f; this->b2 = 0.0f; this->c0 = 0.0f; this->c1 = 0.0f; this->c2 = 0.0f; this->d0 = 0.0f; this->d1 = 0.0f; this->d2 = 0.0f; } void C34Matrix::Identity() { this->a0 = 1.0f; this->a1 = 0.0f; this->a2 = 0.0f; this->b0 = 0.0f; this->b1 = 1.0f; this->b2 = 0.0f; this->c0 = 0.0f; this->c1 = 0.0f; this->c2 = 1.0f; this->d0 = 0.0f; this->d1 = 0.0f; this->d2 = 0.0f; } float C34Matrix::Trace() { return this->a0 + this->b1 + this->c2; } void C34Matrix::Scale(float scale) { this->a0 *= scale; this->a1 *= scale; this->a2 *= scale; this->b0 *= scale; this->b1 *= scale; this->b2 *= scale; this->c0 *= scale; this->c1 *= scale; this->c2 *= scale; } void C34Matrix::Scale(const C3Vector& scale) { this->a0 *= scale.x; this->a1 *= scale.x; this->a2 *= scale.x; this->b0 *= scale.y; this->b1 *= scale.y; this->b2 *= scale.y; this->c0 *= scale.z; this->c1 *= scale.z; this->c2 *= scale.z; } void C34Matrix::Rotate(const C4Quaternion& rotation) { *this = C34Matrix(C33Matrix(rotation)) * (*this); } void C34Matrix::Rotate(float angle, const C3Vector& axis, bool unit) { *this = C34Matrix::Rotation(angle, axis, unit) * (*this); } void C34Matrix::Translate(const C3Vector& move) { this->d0 = this->a0 * move.x + this->b0 * move.y + this->c0 * move.z + this->d0; this->d1 = this->a1 * move.x + this->b1 * move.y + this->c1 * move.z + this->d1; this->d2 = this->a2 * move.x + this->b2 * move.y + this->c2 * move.z + this->d2; } C34Matrix C34Matrix::AffineInverse(const C3Vector& v) const { C33Matrix rotationScale(*this); C3Vector s = { 1.0f / v.x, 1.0f / v.y, 1.0f / v.z }; rotationScale.Scale(s); C34Matrix matrix(rotationScale.Transpose()); matrix.Scale(s); C3Vector move(-this->d0, -this->d1, -this->d2); matrix.Translate(move); return matrix; } C34Matrix C34Matrix::AffineInverse(float a) const { if (CMath::fequalz(a, 1.0f, 0.00000095367432f)) { return this->AffineInverse(); } C34Matrix matrix(C33Matrix(*this).Transpose()); matrix.Scale(1.0f / (a * a)); C3Vector move(-this->d0, -this->d1, -this->d2); matrix.Translate(move); return matrix; } C34Matrix C34Matrix::AffineInverse() const { C34Matrix matrix(C33Matrix(*this).Transpose()); C3Vector move(-this->d0, -this->d1, -this->d2); matrix.Translate(move); return matrix; } C34Matrix operator+(const C34Matrix& l, const C34Matrix& r) { return { l.a0 + r.a0, l.a1 + r.a1, l.a2 + r.a2, l.b0 + r.b0, l.b1 + r.b1, l.b2 + r.b2, l.c0 + r.c0, l.c1 + r.c1, l.c2 + r.c2, l.d0 + r.d0, l.d1 + r.d1, l.d2 + r.d2, }; } C34Matrix operator+(const C34Matrix& l, float a) { return { l.a0 + a, l.a1 + a, l.a2 + a, l.b0 + a, l.b1 + a, l.b2 + a, l.c0 + a, l.c1 + a, l.c2 + a, l.d0 + a, l.d1 + a, l.d2 + a, }; } C34Matrix operator-(const C34Matrix& l, const C34Matrix& r) { return { l.a0 - r.a0, l.a1 - r.a1, l.a2 - r.a2, l.b0 - r.b0, l.b1 - r.b1, l.b2 - r.b2, l.c0 - r.c0, l.c1 - r.c1, l.c2 - r.c2, l.d0 - r.d0, l.d1 - r.d1, l.d2 - r.d2, }; } C34Matrix operator-(const C34Matrix& l, float a) { return { l.a0 - a, l.a1 - a, l.a2 - a, l.b0 - a, l.b1 - a, l.b2 - a, l.c0 - a, l.c1 - a, l.c2 - a, l.d0 - a, l.d1 - a, l.d2 - a, }; } C34Matrix operator*(const C34Matrix& l, const C34Matrix& r) { float d2 = (((l.d0 * r.a2) + (l.d1 * r.b2)) + (l.d2 * r.c2)) + r.d2; float d1 = (((l.d0 * r.a1) + (l.d1 * r.b1)) + (l.d2 * r.c1)) + r.d1; float d0 = (((l.d0 * r.a0) + (l.d1 * r.b0)) + (l.d2 * r.c0)) + r.d0; float c2 = ((l.c0 * r.a2) + (l.c1 * r.b2)) + (l.c2 * r.c2); float c1 = ((l.c0 * r.a1) + (l.c1 * r.b1)) + (l.c2 * r.c1); float c0 = ((l.c0 * r.a0) + (l.c1 * r.b0)) + (l.c2 * r.c0); float b2 = ((l.b0 * r.a2) + (l.b1 * r.b2)) + (l.b2 * r.c2); float b1 = ((l.b0 * r.a1) + (l.b1 * r.b1)) + (l.b2 * r.c1); float b0 = ((l.b0 * r.a0) + (l.b1 * r.b0)) + (l.b2 * r.c0); float a2 = ((l.a0 * r.a2) + (l.a1 * r.b2)) + (l.a2 * r.c2); float a1 = ((l.a0 * r.a1) + (l.a1 * r.b1)) + (l.a2 * r.c1); float a0 = ((l.a0 * r.a0) + (l.a1 * r.b0)) + (l.a2 * r.c0); return { a0, a1, a2, b0, b1, b2, c0, c1, c2, d0, d1, d2 }; } C34Matrix operator*(const C34Matrix& l, float a) { return { l.a0 * a, l.a1 * a, l.a2 * a, l.b0 * a, l.b1 * a, l.b2 * a, l.c0 * a, l.c1 * a, l.c2 * a, l.d0 * a, l.d1 * a, l.d2 * a, }; } C34Matrix operator/(const C34Matrix& l, float a) { return { l.a0 / a, l.a1 / a, l.a2 / a, l.b0 / a, l.b1 / a, l.b2 / a, l.c0 / a, l.c1 / a, l.c2 / a, l.d0 / a, l.d1 / a, l.d2 / a, }; }