From 36e1f398a77c4f1e4f28a36a552b1d95f03947f0 Mon Sep 17 00:00:00 2001 From: josh Date: Fri, 31 May 2024 15:18:14 -0400 Subject: [PATCH] Implement Matrix4x4::RandomGeneral() --- include/J3ML/LinearAlgebra/Matrix4x4.h | 31 +++++++++++++++++++------- src/J3ML/LinearAlgebra/Matrix4x4.cpp | 19 ++++++++++++---- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/include/J3ML/LinearAlgebra/Matrix4x4.h b/include/J3ML/LinearAlgebra/Matrix4x4.h index 7ddce45..813e93b 100644 --- a/include/J3ML/LinearAlgebra/Matrix4x4.h +++ b/include/J3ML/LinearAlgebra/Matrix4x4.h @@ -6,10 +6,12 @@ #include #include #include - +#include #include +using namespace J3ML::Algorithm; + namespace J3ML::LinearAlgebra { template @@ -218,6 +220,11 @@ namespace J3ML::LinearAlgebra { @see RotateFromTo(). */ static Matrix4x4 LookAt(const Vector3& localFwd, const Vector3& targetDir, const Vector3& localUp, const Vector3& worldUp); + /// Returns a random 4x4 matrix with each entry randomized between the range [minElem, maxElem] + /** Warning: The matrices returned by this function do not represent well-formed 3D transformations. + This function is mostly used for testing and debugging purposes only. */ + static Matrix4x4 RandomGeneral(RNG& rng, float minElem, float maxElem); + /// Creates a new Matrix4x4 that rotates about one of the principal axes. /** Calling RotateX, RotateY, or RotateZ is slightly faster than calling the more generic RotateAxisAngle function. @param radians The angle to rotate by, in radians. For example, Pi/4.f equals 45 degrees. @@ -293,25 +300,33 @@ namespace J3ML::LinearAlgebra { /// 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); + static Matrix4x4 D3DPerspProjLH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize); /// 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); + 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); + static Matrix4x4 OpenGLOrthoProjLH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize); /// 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); + static Matrix4x4 OpenGLOrthoProjRH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize); /// Computes a left-handed perspective projection matrix for OpenGL. /// @note Use the M*v multiplication order to project points with this matrix. + /// @param n Near-plane + /// @param f Far-plane + /// @param h Horizontal FOV + /// @param v Vertical FOV 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. + // @param n Near-plane + /// @param f Far-plane + /// @param h Horizontal FOV + /// @param v Vertical FOV static Matrix4x4 OpenGLPerspProjRH(float n, float f, float h, float v); /// Creates a new transformation matrix that translates by the given offset. @@ -604,7 +619,7 @@ namespace J3ML::LinearAlgebra { /// If a matrix is of form M=T*R*S, where T is an affine translation matrix /// R is a rotation matrix and S is a diagonal matrix with non-zero but pote ntially non-uniform scaling /// factors (possibly mirroring), then the matrix M is column-orthogonal and this function can be used to compute the inverse. - /// Calling this function is faster than the calling the generic matrix Inverse() function. + /// Calling this function is faster than the calling the generic matrix Inverted() function. /// Returns true on success. On failure, the matrix is not modified. This function fails if any of the /// elements of this vector are not finite, or if the matrix contains a zero scaling factor on X, Y, or Z. /// This function may not be called if this matrix contains any projection (last row differs from (0 0 0 1)). @@ -618,7 +633,7 @@ namespace J3ML::LinearAlgebra { /// If a matrix is of form M = T*R*S, where T is an affine translation matrix, /// R is a rotation matrix and S is a diagonal matrix with non-zero and uniform scaling factors (possibly mirroring), /// then the matrix M is both column- and row-orthogonal and this function can be used to compute this inverse. - /// This function is faster than calling InverseColOrthogonal() or the generic Inverse(). + /// This function is faster than calling InverseColOrthogonal() or the generic Inverted(). /// Returns true on success. On failure, the matrix is not modified. This function fails if any of the /// elements of this vector are not finite, or if the matrix contains a zero scaling factor on X, Y, or Z. /// This function may not be called if this matrix contains any shearing or nonuniform scaling. @@ -628,7 +643,7 @@ namespace J3ML::LinearAlgebra { /// Inverts a matrix that is a concatenation of only translate and rotate operations. /// If a matrix is of form M = T*R*S, where T is an affine translation matrix, R is a rotation /// matrix and S is either identity or a mirroring matrix, then the matrix M is orthonormal and this function can be used to compute the inverse. - /// This function is faster than calling InverseOrthogonalUniformScale(), InverseColOrthogonal(), or the generic Inverse(). + /// This function is faster than calling InverseOrthogonalUniformScale(), InverseColOrthogonal(), or the generic Inverted(). /// This function may not be called if this matrix contains any scaling or shearing, but it may contain mirroring. /// This function may not be called if this matrix contains any projection (last row differs from (0 0 0 1)). void InverseOrthonormal(); diff --git a/src/J3ML/LinearAlgebra/Matrix4x4.cpp b/src/J3ML/LinearAlgebra/Matrix4x4.cpp index b4656fb..26c467c 100644 --- a/src/J3ML/LinearAlgebra/Matrix4x4.cpp +++ b/src/J3ML/LinearAlgebra/Matrix4x4.cpp @@ -557,10 +557,10 @@ namespace J3ML::LinearAlgebra { // See http://www.songho.ca/opengl/gl_projectionmatrix.html , unlike in Direct3D, where the // Z coordinate ranges in [0, 1]. This is the only difference between D3DPerspProjRH and OpenGLPerspProjRH. using f32 = float; - float p00 = 2.f *n / h; float p01 = 0; float p02 = 0; float p03 = 0.f; - float p10 = 0; float p11 = 2.f * n / v; float p12 = 0; float p13 = 0.f; - float p20 = 0; float p21 = 0; float p22 = (n+f) / (n-f); float p23 = 2.f*n*f / (n-f); - float p30 = 0; float p31 = 0; float p32 = -1.f; float p33 = 0.f; + f32 p00 = 2.f *n / h; f32 p01 = 0; f32 p02 = 0; f32 p03 = 0.f; + f32 p10 = 0; f32 p11 = 2.f * n / v; f32 p12 = 0; f32 p13 = 0.f; + f32 p20 = 0; f32 p21 = 0; f32 p22 = (n+f) / (n-f); f32 p23 = 2.f*n*f / (n-f); + f32 p30 = 0; f32 p31 = 0; f32 p32 = -1.f; f32 p33 = 0.f; return {p00, p01, p02, p03, p10, p11, p12, p13, p20, p21, p22, p23, p30, p31, p32, p33}; } @@ -1038,5 +1038,16 @@ namespace J3ML::LinearAlgebra { 0.f, 0.f, 0.f, 1.f); } + Matrix4x4 Matrix4x4::RandomGeneral(RNG &rng, float minElem, float maxElem) { + assert(std::isfinite(minElem)); + assert(std::isfinite(maxElem)); + + Matrix4x4 m; + for (int y = 0; y < 4; ++y) + for (int x = 0; x < 4; ++x) + m[y][x] = rng.Float(minElem, maxElem); + return m; + } + } \ No newline at end of file