diff --git a/include/J3ML/LinearAlgebra/Matrix4x4.h b/include/J3ML/LinearAlgebra/Matrix4x4.h index 548188f..433557d 100644 --- a/include/J3ML/LinearAlgebra/Matrix4x4.h +++ b/include/J3ML/LinearAlgebra/Matrix4x4.h @@ -58,7 +58,6 @@ namespace LinearAlgebra { position of the local space pivot. */ Matrix4x4(const Vector4& r1, const Vector4& r2, const Vector4& r3, const Vector4& r4); - explicit Matrix4x4(const Quaternion& orientation); /// Constructs this float4x4 from the given quaternion and translation. @@ -96,6 +95,8 @@ namespace LinearAlgebra { @see RotateFromTo(). */ static Matrix4x4 LookAt(const Vector3& localFwd, const Vector3& targetDir, const Vector3& localUp, const Vector3& worldUp); + static Matrix4x4 FromTranslation(const Vector3& translation); + /// Returns the translation part. /** The translation part is stored in the fourth column of this matrix. This is equivalent to decomposing this matrix in the form M = T * M', i.e. this translation is applied last, @@ -110,8 +111,6 @@ namespace LinearAlgebra { void SetRotatePart(const Quaternion& q); void Set3x3Part(const Matrix3x3& r); - - void SetRow(int row, const Vector3& rowVector, float m_r3); void SetRow(int row, const Vector4& rowVector); void SetRow(int row, float m_r0, float m_r1, float m_r2, float m_r3); @@ -133,59 +132,19 @@ namespace LinearAlgebra { } - void SwapColumns(int col1, int col2) - { - Swap(At(0, col1), At(0, col2)); - Swap(At(1, col1), At(1, col2)); - Swap(At(2, col1), At(2, col2)); - Swap(At(3, col1), At(3, col2)); - } + void SwapColumns(int col1, int col2); /// Swaps two rows. - void SwapRows(int row1, int row2) - { - Swap(At(row1, 0), At(row2, 0)); - Swap(At(row1, 1), At(row2, 1)); - Swap(At(row1, 2), At(row2, 2)); - Swap(At(row1, 3), At(row2, 3)); - } + void SwapRows(int row1, int row2); /// Swapsthe xyz-parts of two rows element-by-element - void SwapRows3(int row1, int row2) - { - Swap(At(row1, 0), At(row2, 0)); - Swap(At(row1, 1), At(row2, 1)); - Swap(At(row1, 2), At(row2, 2)); - } + void SwapRows3(int row1, int row2); + void ScaleRow(int row, float scalar); + void ScaleRow3(int row, float scalar); + void ScaleColumn(int col, float scalar); + void ScaleColumn3(int col, float scalar); /// Algorithm from Eric Lengyel's Mathematics for 3D Game Programming & Computer Graphics, 2nd Ed. - void Pivot() - { - int rowIndex = 0; - - for(int col = 0; col < Cols; ++col) - { - int greatest = rowIndex; - - // find the rowIndex k with k >= 1 for which Mkj has the largest absolute value. - for(int i = rowIndex; i < Rows; ++i) - if (std::abs(At(i, col)) > std::abs(At(greatest, col))) - greatest = i; - - if (std::abs(At(greatest, col)) != 0) - { - if (rowIndex != greatest) - SwapRows(rowIndex, greatest); // the greatest now in rowIndex - - ScaleRow(rowIndex, 1.f/At(rowIndex, col)); - - for(int r = 0; r < Rows; ++r) - if (r != rowIndex) - SetRow(r, GetRow(r) - GetRow(rowIndex) * At(r, col)); - - ++rowIndex; - } - } - } + void Pivot(); /// Tests if this matrix does not contain any NaNs or infs. /** @return Returns true if the entries of this float4x4 are all finite, and do not contain NaN or infs. */ diff --git a/src/J3ML/LinearAlgebra/Matrix4x4.cpp b/src/J3ML/LinearAlgebra/Matrix4x4.cpp index 8ea4dc1..bd74f8d 100644 --- a/src/J3ML/LinearAlgebra/Matrix4x4.cpp +++ b/src/J3ML/LinearAlgebra/Matrix4x4.cpp @@ -440,4 +440,85 @@ namespace LinearAlgebra { Vector3 Matrix4x4::GetRow3(int index) const { return Vector3{ At(index, 0), At(index, 1), At(index, 2)}; } + + void Matrix4x4::SwapColumns(int col1, int col2) { + Swap(At(0, col1), At(0, col2)); + Swap(At(1, col1), At(1, col2)); + Swap(At(2, col1), At(2, col2)); + Swap(At(3, col1), At(3, col2)); + } + + void Matrix4x4::SwapRows(int row1, int row2) { + Swap(At(row1, 0), At(row2, 0)); + Swap(At(row1, 1), At(row2, 1)); + Swap(At(row1, 2), At(row2, 2)); + Swap(At(row1, 3), At(row2, 3)); + } + + void Matrix4x4::SwapRows3(int row1, int row2) { + Swap(At(row1, 0), At(row2, 0)); + Swap(At(row1, 1), At(row2, 1)); + Swap(At(row1, 2), At(row2, 2)); + } + + void Matrix4x4::Pivot() { + int rowIndex = 0; + + for(int col = 0; col < Cols; ++col) + { + int greatest = rowIndex; + + // find the rowIndex k with k >= 1 for which Mkj has the largest absolute value. + for(int i = rowIndex; i < Rows; ++i) + if (std::abs(At(i, col)) > std::abs(At(greatest, col))) + greatest = i; + + if (std::abs(At(greatest, col)) != 0) + { + if (rowIndex != greatest) + SwapRows(rowIndex, greatest); // the greatest now in rowIndex + + ScaleRow(rowIndex, 1.f/At(rowIndex, col)); + + for(int r = 0; r < Rows; ++r) + if (r != rowIndex) + SetRow(r, GetRow(r) - GetRow(rowIndex) * At(r, col)); + + ++rowIndex; + } + } + } + + void Matrix4x4::ScaleColumn3(int col, float scalar) { + At(0, col) *= scalar; + At(1, col) *= scalar; + At(2, col) *= scalar; + } + + void Matrix4x4::ScaleColumn(int col, float scalar) { + At(0, col) *= scalar; + At(1, col) *= scalar; + At(2, col) *= scalar; + At(3, col) *= scalar; + } + + void Matrix4x4::ScaleRow3(int row, float scalar) { + At(row, 0) *= scalar; + At(row, 1) *= scalar; + At(row, 2) *= scalar; + } + + void Matrix4x4::ScaleRow(int row, float scalar) { + At(row, 0) *= scalar; + At(row, 1) *= scalar; + At(row, 2) *= scalar; + At(row, 3) *= scalar; + } + + Matrix4x4 Matrix4x4::FromTranslation(const Vector3 &translation) { + Matrix4x4 m; + m.SetTranslatePart(translation); + m.Set3x3Part(Matrix3x3::Identity); + return m; + } } \ No newline at end of file