Implement Matrix4x4::ShearX ShearY ShearZ D3DOrthoProjLH D3DOrthoProjRH D3DPerspProjLH

This commit is contained in:
2024-05-22 12:27:37 -04:00
parent 0c85b8408c
commit d2b51d348c
2 changed files with 136 additions and 31 deletions

View File

@@ -274,7 +274,56 @@ namespace J3ML::LinearAlgebra {
static Matrix4x4 RotateFromTo(const Vector3& sourceDirection, const Vector3 &targetDirection,
const Vector3 &sourceDirection2, const Vector3 &targetDirection2);
/// Produces a matrix that shears along a principal axis.
/** The shear matrix offsets the two other axes according to the
position of the point along the shear axis. */
static Matrix4x4 ShearX(float yFactor, float zFactor);
static Matrix4x4 ShearY(float xFactor, float zFactor);
static Matrix4x4 ShearZ(float xFactor, float yFactor);
/// Identical to D3DXMatrixOrthoLH, except transposed to account for Matrix * vector convention used in J3ML.
/// See http://msdn.microsoft.com/en-us/library/windows/desktop/bb205346(v=vs.85).aspx
/// @note Use the M*v multiplication order to project points with this matrix.
static Matrix4x4 D3DOrthoProjLH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize);
/// Identical to D3DXMatrixOrthoRH, except transposed to account for Matrix * vector convention used in J3ML.
/// See http://msdn.microsoft.com/en-us/library/windows/desktop/bb205349(v=vs.85).aspx
/// @note Use the M*v multiplication order to project points with this matrix.
static Matrix4x4 D3DOrthoProjRH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize);
/// Identical to D3DXMatrixPerspectiveLH, except transposed to account for Matrix * vector convention used in J3ML.
/// See http://msdn.microsoft.com/en-us/library/windows/desktop/bb205352(v=vs.85).aspx
/// @note Use the M*v multiplication order to project points with this matrix.
static Matrix4x4 D3DPerspProjLH(float n, float f, float h, float v);
/// Identical to D3DXMatrixPerspectiveRH, except transposed to account for Matrix * vector convention used in J3ML.
/// See http://msdn.microsoft.com/en-us/library/windows/desktop/bb205355(v=vs.85).aspx
/// @note Use the M*v multiplication order to project points with this matrix.
static Matrix4x4 D3DPerspProjRH(float n, float f, float h, float v)
{
Matrix4x4 p;
p[0][0] = 2.f * n / h; p[0][1] = 0; p[0][2] = 0; p[0][3] = 0.f;
p[1][0] = 0; p[1][1] = 2.f * n / v; p[1][2] = 0; p[1][3] = 0.f;
p[2][0] = 0; p[2][1] = 0; p[2][2] = f / (f-n); p[2][3] = n * f / (n-f);
p[3][0] = 0; p[3][1] = 0; p[3][2] = 1.f; p[3][3] = 0.f;
return p;
}
/// Computes a left-handled orthographic projection matrix for OpenGL.
/// @note Use the M*v multiplication order to project points with this matrix.
static Matrix4x4 OpenGLOrthoProjLH(float n, float f, float h, float v);
/// Computes a right-handled orthographic projection matrix for OpenGL.
/// @note Use the M*v multiplication order to project points with this matrix.
static Matrix4x4 OpenGLOrthoProjRH(float n, float f, float h, float v);
/// Computes a left-handed perspective projection matrix for OpenGL.
/// @note Use the M*v multiplication order to project points with this matrix.
static Matrix4x4 OpenGLPerspProjLH(float n, float f, float h, float v);
/// Identical to http://www.opengl.org/sdk/docs/man/xhtml/gluPerspective.xml , except uses viewport sizes instead of FOV to set up the
/// projection matrix.
/// @note Use the M*v multiplication order to project points with this matrix.
static Matrix4x4 OpenGLPerspProjRH(float n, float f, float h, float v);
public:
/// 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,
@@ -309,28 +358,51 @@ namespace J3ML::LinearAlgebra {
void SetRotatePartZ(float angleRadians);
void Set3x3Part(const Matrix3x3& r);
/// Sets the value of a given row.
/// @param row The index of the row to a set, in the range [0-3].
/// @param data A pointer to an array of 4 floats that contain the new x,y,z,w values for the row.
void SetRow(int row, const float* data);
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);
/// Sets the value of a given column.
/// @param column The index of the column to set, in the range [0-3].
/// @param data A pointer to an array of 3 floats that contain the new x,y,z,w values for the column.
void SetCol(int col, const float *data);
void SetCol(int col, const Vector3& colVector, float m_c3);
void SetCol(int col, const Vector4& colVector);
void SetCol(int col, float m_c0, float m_c1, float m_c2, float m_c3);
void SetCol(int col, const float *data);
Vector4 GetRow(int index) const;
Vector4 GetColumn(int index) const;
/// Returns the given row.
/** @param The zero-based index [0, 3] of the row to get */
Vector4 GetRow(int row) const;
Vector4 Row(int row) const;
Vector4& Row(int row);
/// Returns only the first-three elements of the given row.
Vector3 GetRow3(int index) const;
Vector3 GetColumn3(int index) const;
Vector3 Row3(int i) const;
/// This method also allows assignment to the retrieved row.
Vector3& Row3(int row);
/// Returns the given column.
/** @param col The zero-based index [0, 3] of the column to get. */
Vector4 GetColumn(int index) const;
Vector4 Column(int index) const;
Vector4 Col(int i) const;
Vector4 Row(int i) const;
Vector4 Col3(int i) const;
Vector4 Row3(int i) const;
Vector3 GetScale() const
{
/// Returns only the first three elements of the given column.
Vector3 GetColumn3(int index) const;
Vector3 Column3(int index) const { return GetColumn3(index);}
Vector3 Col3(int i) const;
/// Returns the scaling performed by this matrix. This function assumes taht the last row is [0 0 0 1].
/// GetScale().x specifies the amount of scaling applied to the local x direction vector when it is transformed by this matrix.
/// i.e. GetScale()[i] equals Col[i].Length();
Vector3 GetScale() const;
}
Matrix4x4 Scale(const Vector3&);
float &At(int row, int col);
@@ -414,25 +486,6 @@ namespace J3ML::LinearAlgebra {
static Matrix4x4 FromTranslation(const Vector3& rhs);
static Matrix4x4 D3DOrthoProjLH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize);
static Matrix4x4 D3DOrthoProjRH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize);
static Matrix4x4 D3DPerspProjLH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize);
static Matrix4x4 D3DPerspProjRH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize);
/// Computes a left-handled orthographic projection matrix for OpenGL.
/// @note Use the M*v multiplication order to project points with this matrix.
static Matrix4x4 OpenGLOrthoProjLH(float n, float f, float h, float v);
/// Computes a right-handled orthographic projection matrix for OpenGL.
/// @note Use the M*v multiplication order to project points with this matrix.
static Matrix4x4 OpenGLOrthoProjRH(float n, float f, float h, float v);
/// Computes a left-handed perspective projection matrix for OpenGL.
/// @note Use the M*v multiplication order to project points with this matrix.
static Matrix4x4 OpenGLPerspProjLH(float n, float f, float h, float v);
/// Identical to http://www.opengl.org/sdk/docs/man/xhtml/gluPerspective.xml , except uses viewport sizes instead of FOV to set up the
/// projection matrix.
/// @note Use the M*v multiplication order to project points with this matrix.
static Matrix4x4 OpenGLPerspProjRH(float n, float f, float h, float v);
Vector4 operator[](int row);

View File

@@ -651,9 +651,9 @@ namespace J3ML::LinearAlgebra {
Vector4 Matrix4x4::Row(int i) const { return GetRow(i);}
Vector4 Matrix4x4::Col3(int i) const { return GetColumn3(i);}
Vector3 Matrix4x4::Col3(int i) const { return GetColumn3(i);}
Vector4 Matrix4x4::Row3(int i) const { return GetRow3(i);}
Vector3 Matrix4x4::Row3(int i) const { return GetRow3(i);}
Vector3 Matrix4x4::TransformDir(float tx, float ty, float tz) const
{
@@ -764,4 +764,56 @@ namespace J3ML::LinearAlgebra {
return copy;
}
Vector4 &Matrix4x4::Row(int row) {
assert(row >= 0);
assert(row < Rows);
return reinterpret_cast<Vector4 &> (elems[row]);
}
Vector3 &Matrix4x4::Row3(int row) {
assert(row >= 0);
assert(row < Rows);
return reinterpret_cast<Vector3 &> (elems[row]);
}
Vector4 Matrix4x4::Column(int index) const { return GetColumn(index);}
Vector3 Matrix4x4::GetScale() const {
return Vector3(
GetColumn3(0).Length(),
GetColumn3(1).Length(),
GetColumn3(2).Length());
}
Matrix4x4 Matrix4x4::ShearX(float yFactor, float zFactor) {
return Matrix4x4(1.f, yFactor, zFactor, 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);
}
Matrix4x4 Matrix4x4::ShearY(float xFactor, float zFactor) /// [similarOverload: ShearX] [hideIndex]
{
return Matrix4x4(1.f, 0.f, 0.f, 0.f,
xFactor, 1.f, zFactor, 0.f,
0.f, 0.f, 1.f, 0.f,
0.f, 0.f, 0.f, 1.f);
}
Matrix4x4 Matrix4x4::ShearZ(float xFactor, float yFactor) /// [similarOverload: ShearX] [hideIndex]
{
return Matrix4x4(1.f, 0.f, 0.f, 0.f,
0.f, 1.f, 0.f, 0.f,
xFactor, yFactor, 1.f, 0.f,
0.f, 0.f, 0.f, 1.f);
}
Matrix4x4 Matrix4x4::D3DPerspProjLH(float n, float f, float h, float v) {
Matrix4x4 p;
p[0][0] = 2.f * n / h; p[0][1] = 0; p[0][2] = 0; p[0][3] = 0.f;
p[1][0] = 0; p[1][1] = 2.f * n / v; p[1][2] = 0; p[1][3] = 0.f;
p[2][0] = 0; p[2][1] = 0; p[2][2] = f / (f-n); p[2][3] = n * f / (n-f);
p[3][0] = 0; p[3][1] = 0; p[3][2] = 1.f; p[3][3] = 0.f;
}
}