Implement Matrix4x4::RandomGeneral()

This commit is contained in:
2024-05-31 15:18:14 -04:00
parent a4f10b0b7e
commit 36e1f398a7
2 changed files with 38 additions and 12 deletions

View File

@@ -6,10 +6,12 @@
#include <J3ML/LinearAlgebra/Quaternion.h> #include <J3ML/LinearAlgebra/Quaternion.h>
#include <J3ML/LinearAlgebra/Vector4.h> #include <J3ML/LinearAlgebra/Vector4.h>
#include <J3ML/LinearAlgebra/Matrices.inl> #include <J3ML/LinearAlgebra/Matrices.inl>
#include <J3ML/Algorithm/RNG.h>
#include <algorithm> #include <algorithm>
using namespace J3ML::Algorithm;
namespace J3ML::LinearAlgebra { namespace J3ML::LinearAlgebra {
template <typename Matrix> template <typename Matrix>
@@ -218,6 +220,11 @@ namespace J3ML::LinearAlgebra {
@see RotateFromTo(). */ @see RotateFromTo(). */
static Matrix4x4 LookAt(const Vector3& localFwd, const Vector3& targetDir, const Vector3& localUp, const Vector3& worldUp); 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. /// 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. /** 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. @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. /// 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 /// 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. /// @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. /// 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 /// 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. /// @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. /// Computes a left-handled orthographic projection matrix for OpenGL.
/// @note Use the M*v multiplication order to project points with this matrix. /// @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. /// Computes a right-handled orthographic projection matrix for OpenGL.
/// @note Use the M*v multiplication order to project points with this matrix. /// @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. /// Computes a left-handed perspective projection matrix for OpenGL.
/// @note Use the M*v multiplication order to project points with this 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 OpenGLPerspProjLH(float n, float f, float h, float v); 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 /// 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. /// projection matrix.
/// @note Use the M*v multiplication order to project points with this 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); static Matrix4x4 OpenGLPerspProjRH(float n, float f, float h, float v);
/// Creates a new transformation matrix that translates by the given offset. /// 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 /// 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 /// 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. /// 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 /// 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. /// 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)). /// 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, /// 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), /// 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. /// 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 /// 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. /// 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. /// 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. /// 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 /// 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. /// 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 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)). /// This function may not be called if this matrix contains any projection (last row differs from (0 0 0 1)).
void InverseOrthonormal(); void InverseOrthonormal();

View File

@@ -557,10 +557,10 @@ namespace J3ML::LinearAlgebra {
// See http://www.songho.ca/opengl/gl_projectionmatrix.html , unlike in Direct3D, where the // 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. // Z coordinate ranges in [0, 1]. This is the only difference between D3DPerspProjRH and OpenGLPerspProjRH.
using f32 = float; using f32 = float;
float p00 = 2.f *n / h; float p01 = 0; float p02 = 0; float p03 = 0.f; f32 p00 = 2.f *n / h; f32 p01 = 0; f32 p02 = 0; f32 p03 = 0.f;
float p10 = 0; float p11 = 2.f * n / v; float p12 = 0; float p13 = 0.f; f32 p10 = 0; f32 p11 = 2.f * n / v; f32 p12 = 0; f32 p13 = 0.f;
float p20 = 0; float p21 = 0; float p22 = (n+f) / (n-f); float p23 = 2.f*n*f / (n-f); f32 p20 = 0; f32 p21 = 0; f32 p22 = (n+f) / (n-f); f32 p23 = 2.f*n*f / (n-f);
float p30 = 0; float p31 = 0; float p32 = -1.f; float p33 = 0.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}; 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); 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;
}
} }