Implement Matrix4x4::Equals
This commit is contained in:
@@ -690,6 +690,88 @@ namespace J3ML::LinearAlgebra {
|
|||||||
return true;
|
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);
|
0, 0, 0, 1.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix4x4 Matrix4x4::Translate(const Vector3 &rhs) const {
|
|
||||||
return *this * FromTranslation(rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Matrix4x4::Transform(const Vector3 &rhs) const {
|
Vector3 Matrix4x4::Transform(const Vector3 &rhs) const {
|
||||||
return Transform(rhs.x, rhs.y, rhs.z);
|
return Transform(rhs.x, rhs.y, rhs.z);
|
||||||
@@ -424,15 +421,7 @@ namespace J3ML::LinearAlgebra {
|
|||||||
return GetColumn3(3);
|
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
|
||||||
Matrix4x4::LookAt(const Vector3 &localFwd, const Vector3 &targetDir, const Vector3 &localUp, const Vector3 &worldUp) {
|
Matrix4x4::LookAt(const Vector3 &localFwd, const Vector3 &targetDir, const Vector3 &localUp, const Vector3 &worldUp) {
|
||||||
@@ -476,6 +465,7 @@ namespace J3ML::LinearAlgebra {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Matrix4x4::Pivot() {
|
void Matrix4x4::Pivot() {
|
||||||
|
/// Algorithm from Eric Lengyel's Mathematics for 3D Game Programming & Computer Graphics, 2nd Ed.
|
||||||
int rowIndex = 0;
|
int rowIndex = 0;
|
||||||
|
|
||||||
for(int col = 0; col < Cols; ++col)
|
for(int col = 0; col < Cols; ++col)
|
||||||
@@ -941,4 +931,32 @@ namespace J3ML::LinearAlgebra {
|
|||||||
return m;
|
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