Implement Matrix4x4::Equals
This commit is contained in:
@@ -690,6 +690,88 @@ namespace J3ML::LinearAlgebra {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Matrix3x3::SolveAxb(Vector3 b, Vector3 &x) const {
|
||||
// Solve by pivotization.
|
||||
float v00 = At(0, 0);
|
||||
float v10 = At(1, 0);
|
||||
float v20 = At(2, 0);
|
||||
|
||||
float v01 = At(0, 1);
|
||||
float v11 = At(1, 1);
|
||||
float v21 = At(2, 1);
|
||||
|
||||
float v02 = At(0, 2);
|
||||
float v12 = At(1, 2);
|
||||
float v22 = At(2, 2);
|
||||
|
||||
float av00 = std::abs(v00);
|
||||
float av10 = std::abs(v10);
|
||||
float av20 = std::abs(v20);
|
||||
|
||||
// Find which item in first column has largest absolute value.
|
||||
if (av10 >= av00 && av10 >= av20) {
|
||||
Swap(v00, v10);
|
||||
Swap(v01, v11);
|
||||
Swap(v02, v12);
|
||||
Swap(b[0], b[1]);
|
||||
} else if (av20 >= av00) {
|
||||
Swap(v00, v20);
|
||||
Swap(v01, v21);
|
||||
Swap(v02, v22);
|
||||
Swap(b[0], b[2]);
|
||||
}
|
||||
|
||||
/* a b c | x
|
||||
d e f | y
|
||||
g h i | z, where |a| >= |d| && |a| >= |g| */
|
||||
|
||||
if (Math::EqualAbs(v00, 0.f))
|
||||
return false;
|
||||
|
||||
|
||||
// Scale row so that leading element is one.
|
||||
float denom = 1.f / v00;
|
||||
v01 *= denom;
|
||||
v02 *= denom;
|
||||
b[0] *= denom;
|
||||
|
||||
/* 1 b c | x
|
||||
d e f | y
|
||||
g h i | z */
|
||||
|
||||
|
||||
// Pivotize again.
|
||||
if (std::abs(v21) >= std::abs(v11))
|
||||
{
|
||||
Swap(v11, v21);
|
||||
Swap(v12, v22);
|
||||
Swap(b[1], b[2]);
|
||||
}
|
||||
|
||||
if (Math::EqualAbs(v11, 0.f))
|
||||
return false;
|
||||
|
||||
/* 1 b c | x
|
||||
0 e f | y
|
||||
0 h i | z, where |e| >= |h| */
|
||||
|
||||
denom = 1.f / v11;
|
||||
// v11 = 1.f;
|
||||
v12 *= denom;
|
||||
b[1] *= denom;
|
||||
|
||||
/* 1 b c | x
|
||||
0 1 f | y
|
||||
0 h i | z */
|
||||
|
||||
if (Math::EqualAbs(v22, 0.f))
|
||||
return false;
|
||||
|
||||
x[2] = b[2] / v22;
|
||||
x[1] = b[1] - x[2] * v12;
|
||||
x[0] = b[0] - x[2] * v02 - x[1] * v01;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@@ -242,9 +242,6 @@ namespace J3ML::LinearAlgebra {
|
||||
0, 0, 0, 1.f);
|
||||
}
|
||||
|
||||
Matrix4x4 Matrix4x4::Translate(const Vector3 &rhs) const {
|
||||
return *this * FromTranslation(rhs);
|
||||
}
|
||||
|
||||
Vector3 Matrix4x4::Transform(const Vector3 &rhs) const {
|
||||
return Transform(rhs.x, rhs.y, rhs.z);
|
||||
@@ -424,15 +421,7 @@ namespace J3ML::LinearAlgebra {
|
||||
return GetColumn3(3);
|
||||
}
|
||||
|
||||
Matrix4x4 Matrix4x4::Scale(const Vector3& scale)
|
||||
{
|
||||
auto mat = *this;
|
||||
|
||||
mat.At(3, 0) *= scale.x;
|
||||
mat.At(3, 1) *= scale.y;
|
||||
mat.At(3, 2) *= scale.z;
|
||||
return mat;
|
||||
}
|
||||
|
||||
Matrix4x4
|
||||
Matrix4x4::LookAt(const Vector3 &localFwd, const Vector3 &targetDir, const Vector3 &localUp, const Vector3 &worldUp) {
|
||||
@@ -476,6 +465,7 @@ namespace J3ML::LinearAlgebra {
|
||||
}
|
||||
|
||||
void Matrix4x4::Pivot() {
|
||||
/// Algorithm from Eric Lengyel's Mathematics for 3D Game Programming & Computer Graphics, 2nd Ed.
|
||||
int rowIndex = 0;
|
||||
|
||||
for(int col = 0; col < Cols; ++col)
|
||||
@@ -941,4 +931,32 @@ namespace J3ML::LinearAlgebra {
|
||||
return m;
|
||||
}
|
||||
|
||||
void Matrix4x4::Decompose(Vector3 &translate, Quaternion &rotate, Vector3 &scale) const {
|
||||
assert(this->IsColOrthogonal3());
|
||||
|
||||
Matrix3x3 r;
|
||||
Decompose(translate, r, scale);
|
||||
rotate = Quaternion(r);
|
||||
|
||||
/// Test that composing back yields the original Matrix4x4.
|
||||
assert(Matrix4x4::FromTRS(translate, rotate, scale).Equals(*this, 0.1f));
|
||||
}
|
||||
|
||||
void Matrix4x4::Decompose(Vector3 &translate, Matrix4x4 &rotate, Vector3 &scale) const {
|
||||
assert(this->IsColOrthogonal3());
|
||||
|
||||
Matrix3x3 r;
|
||||
Decompose(translate, r, scale);
|
||||
rotate.SetRotatePart(r);
|
||||
rotate.SetTranslatePart(0,0,0);
|
||||
}
|
||||
|
||||
bool Matrix4x4::Equals(const Matrix4x4 &other, float epsilon) const {
|
||||
for (int iy = 0; iy < Rows; ++iy)
|
||||
for (int ix = 0; ix < Cols; ++ix)
|
||||
if (!Math::EqualAbs(At(iy, ix), other[iy][ix], epsilon))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user