Package icyllis.arc3d.core

# Class Matrix4

java.lang.Object
icyllis.arc3d.core.Matrix4

All Implemented Interfaces:
  `Matrix4c`, `Cloneable`

public non-sealed class Matrix4 extends Object implements Matrix4c, Cloneable
This class represents a 4x4 matrix and a 3D transformation, using the right-hand rule.

The memory layout (order of components) is the same as GLSL's column-major and HLSL's row-major, this is just a difference in naming and writing. A matrix looks like this:

[m11 m12 m13 m14]
[m21 m22 m23 m24]
[m31 m32 m33 m34]
[m41 m42 m43 m44]

Where [m41 m42 m43] represents the translation, and they are the last four elements in memory.

See Also:
  - `Matrix`

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `float`
  `m11`
  `float`
  `m12`
  `float`
  `m13`
  `float`
  `m14`
  `float`
  `m21`
  `float`
  `m22`
  `float`
  `m23`
  `float`
  `m24`
  `float`
  `m31`
  `float`
  `m32`
  `float`
  `m33`
  `float`
  `m34`
  `float`
  `m41`
  `float`
  `m42`
  `float`
  `m43`
  `float`
  `m44`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `Matrix4()`
  Create a new identity matrix.
  `Matrix4(float... a)`
  Create a matrix from an array of elements in row-major.
  `Matrix4(Matrix4c m)`
  Create a matrix copied from an existing matrix.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `add(Matrix4 m)`
  Add each element of the given matrix to the corresponding element of this matrix.
  `Matrix4`
  `clone()`
  `static Matrix4`
  `copy(Matrix4c m)`
  Create a copy of `mat` if not null, otherwise a new identity matrix.
  `float`
  `determinant()`
  Return the determinant of this matrix.
  `boolean`
  `equals(Object o)`
  Returns whether this matrix is exactly equal to another matrix.
  `int`
  `hashCode()`
  `boolean`
  `hasPerspective()`
  `boolean`
  `hasTranslation()`
  `static Matrix4c`
  `identity()`
  Returns a read-only identity matrix.
  `boolean`
  `invert()`
  Compute the inverse of this matrix.
  `boolean`
  `invert(Matrix4 dest)`
  Compute the inverse of this matrix.
  `boolean`
  `isAffine()`
  Returns whether this matrix is seen as an affine transformation.
  `boolean`
  `isApproxEqual(Matrix4 m)`
  Returns whether this matrix is approximately equal to given matrix.
  `boolean`
  `isAxisAligned()`
  Returns whether this matrix transforms rect to another rect.
  `boolean`
  `isIdentity()`
  Returns whether this matrix is approximately equivalent to an identity matrix.
  `boolean`
  `isScaleTranslate()`
  Returns whether this matrix at most scales and translates.
  `float`
  `localAARadius(float left, float top, float right, float bottom)`
  Return the minimum distance needed to move in local (pre-transform) space to ensure that the transformed coordinates are at least 1px away from the original mapped point.
  `float`
  `localAARadius(Rect2fc bounds)`
  Return the minimum distance needed to move in local (pre-transform) space to ensure that the transformed coordinates are at least 1px away from the original mapped point.
  `float`
  `m11()`
  `float`
  `m12()`
  `float`
  `m13()`
  `float`
  `m14()`
  `float`
  `m21()`
  `float`
  `m22()`
  `float`
  `m23()`
  `float`
  `m24()`
  `float`
  `m31()`
  `float`
  `m32()`
  `float`
  `m33()`
  `float`
  `m34()`
  `float`
  `m41()`
  `float`
  `m42()`
  `float`
  `m43()`
  `float`
  `m44()`
  `static Matrix4`
  `makeOrthographic(float width, float height, float near, float far, boolean flipY)`
  Create an orthographic projection matrix.
  `static Matrix4`
  `makeOrthographic(float left, float right, float bottom, float top, float near, float far)`
  Create an orthographic projection matrix.
  `static Matrix4`
  `makePerspective(float fov, float aspect, float near, float far)`
  Create a perspective projection matrix.
  `static Matrix4`
  `makePerspective(float left, float right, float bottom, float top, float near, float far)`
  Create a perspective projection matrix.
  `static Matrix4`
  `makeScale(float x, float y, float z)`
  Create a new scaling transformation matrix.
  `static Matrix4`
  `makeTranslate(float x, float y, float z)`
  Create a new translation transformation matrix.
  `void`
  `mapPoint(float[] p)`
  Map a point in the X-Y plane.
  `float`
  `mapPointX(float x, float y)`
  `float`
  `mapPointY(float x, float y)`
  `void`
  `mapRect(float left, float top, float right, float bottom, Rect2f dest)`
  Map the four corners of 'r' and return the bounding box of those points.
  `void`
  `mapRect(float left, float top, float right, float bottom, Rect2i dest)`
  Map the four corners of 'r' and return the bounding box of those points.
  `void`
  `mapRect(Rect2f r)`
  Map the four corners of 'r' and return the bounding box of those points.
  `void`
  `mapRect(Rect2fc r, Rect2f dest)`
  Map the four corners of 'r' and return the bounding box of those points.
  `void`
  `mapRect(Rect2fc r, Rect2i dest)`
  Map the four corners of 'r' and return the bounding box of those points.
  `void`
  `mapRect(Rect2ic r, Rect2i dest)`
  Map the four corners of 'r' and return the bounding box of those points.
  `void`
  `mapRectIn(float left, float top, float right, float bottom, Rect2i dest)`
  `void`
  `mapRectIn(Rect2fc r, Rect2i dest)`
  Map the four corners of 'r' and return the bounding box of those points.
  `void`
  `mapRectOut(float left, float top, float right, float bottom, Rect2i dest)`
  Map the four corners of 'r' and return the bounding box of those points.
  `void`
  `mapRectOut(Rect2fc r, Rect2i dest)`
  Map the four corners of 'r' and return the bounding box of those points.
  `void`
  `mapRectOut(Rect2ic r, Rect2i dest)`
  Map the four corners of 'r' and return the bounding box of those points.
  `void`
  `mapVec3(float[] vec)`
  `void`
  `normalizePerspective()`
  If the last column of the matrix is [0, 0, 0, not_one]^T, we will treat the matrix as if it is in perspective, even though it stills behaves like its affine.
  `void`
  `postConcat(float r11, float r12, float r13, float r14, float r21, float r22, float r23, float r24, float r31, float r32, float r33, float r34, float r41, float r42, float r43, float r44)`
  Post-multiply this matrix by the given `rhs` matrix.
  `void`
  `postConcat(Matrix3 rhs)`
  Post-multiply this matrix by the given `rhs` matrix.
  `void`
  `postConcat(Matrix4c rhs)`
  Post-multiply this matrix by the given `rhs` matrix.
  `void`
  `postConcat2D(Matrixc rhs)`
  Post-multiply this matrix by the given `rhs` matrix.
  `void`
  `postRotate(double angleX, double angleY, double angleZ)`
  Post-rotates this matrix from the given Euler rotation angles in radians.
  `void`
  `postRotate(double x, double y, double z, double angle)`
  Post-rotates this matrix about an arbitrary axis with the given angle in radians.
  `void`
  `postRotateX(double angle)`
  Post-rotates this matrix about the X-axis with the given angle in radians.
  `void`
  `postRotateY(double angle)`
  Post-rotates this matrix about the Y-axis with the given angle in radians.
  `void`
  `postRotateZ(double angle)`
  Post-rotates this matrix about the Z-axis with the given angle in radians.
  `void`
  `postScale(float sx, float sy)`
  Post-multiply scaling to `this` matrix by scaling the base axes by the given x, y and z factors and store the result in `dest`.
  `void`
  `postScale(float sx, float sy, float sz)`
  Post-multiply scaling to `this` matrix by scaling the base axes by the given x, y and z factors and store the result in `dest`.
  `void`
  `postScale(Vector3 s)`
  Post-scales this matrix by given vector.
  `void`
  `postScaleX(float s)`
  Post-scales this matrix by given vector.
  `void`
  `postScaleY(float s)`
  Post-scales this matrix by given vector.
  `void`
  `postScaleZ(float s)`
  Post-scales this matrix by given vector.
  `void`
  `postShear(float sxy, float sxz, float syx, float syz, float szx, float szy)`
  Post-multiply shearing to `this` matrix by the given shearing coefficients.
  `void`
  `postShear2D(float sx, float sy)`
  Post-multiply 2D shearing to `this` matrix by the given shearing coefficients.
  `void`
  `postTransform(Vector3 vec)`
  Transform a three-dimensional column vector by post-multiplication (this * vec3, w-component is considered as 1).
  `void`
  `postTransform(Vector4 vec)`
  Transform a four-dimensional column vector by post-multiplication (matrix * vector).
  `void`
  `postTranslate(float dx, float dy)`
  Post-multiply a translation to this matrix by translating by the given number of units in x, y and z.
  `void`
  `postTranslate(float dx, float dy, float dz)`
  Post-multiply a translation to this matrix by translating by the given number of units in x, y and z.
  `void`
  `postTranslate(Vector3 t)`
  Post-translates this matrix by given changes.
  `void`
  `postTranslateX(float dx)`
  Post-translates this matrix by given vector.
  `void`
  `postTranslateY(float dy)`
  Post-translates this matrix by given vector.
  `void`
  `postTranslateZ(float dz)`
  Post-translates this matrix by given vector.
  `void`
  `preConcat(float l11, float l12, float l13, float l14, float l21, float l22, float l23, float l24, float l31, float l32, float l33, float l34, float l41, float l42, float l43, float l44)`
  Pre-multiply this matrix by the given `lhs` matrix.
  `void`
  `preConcat(Matrix3 lhs)`
  Pre-multiply this matrix by the given `lhs` matrix.
  `void`
  `preConcat(Matrix4c lhs)`
  Pre-multiply this matrix by the given `lhs` matrix.
  `void`
  `preConcat2D(Matrixc lhs)`
  Pre-multiply this matrix by the given `lhs` matrix.
  `void`
  `preRotate(double angleX, double angleY, double angleZ)`
  Rotates this matrix from the given Euler rotation angles in radians.
  `void`
  `preRotate(double x, double y, double z, double angle)`
  Rotates this matrix about an arbitrary axis with the given angle in radians.
  `void`
  `preRotate(Quaternion q)`
  Rotate this matrix by the given quaternion's rotation matrix.
  `void`
  `preRotate(Vector3 axis, float angle)`
  Rotates this matrix about an arbitrary axis.
  `void`
  `preRotateX(double angle)`
  Rotates this matrix about the X-axis with the given angle in radians.
  `void`
  `preRotateY(double angle)`
  Rotates this matrix about the Y-axis with the given angle in radians.
  `void`
  `preRotateZ(double angle)`
  Rotates this matrix about the Z-axis with the given angle in radians.
  `void`
  `preScale(float sx, float sy)`
  Apply scaling to `this` matrix by scaling the base axes by the given x, y and z factors and store the result in `dest`.
  `void`
  `preScale(float sx, float sy, float sz)`
  Apply scaling to `this` matrix by scaling the base axes by the given x, y and z factors and store the result in `dest`.
  `void`
  `preScale(Vector3 s)`
  Scales this matrix by given vector.
  `void`
  `preScaleX(float s)`
  Scales this matrix by given vector.
  `void`
  `preScaleY(float s)`
  Scales this matrix by given vector.
  `void`
  `preScaleZ(float s)`
  Scales this matrix by given vector.
  `void`
  `preShear(float sxy, float sxz, float syx, float syz, float szx, float szy)`
  Pre-multiply shearing to `this` matrix by the given shearing coefficients.
  `void`
  `preShear2D(float sx, float sy)`
  Pre-multiply 2D shearing to `this` matrix by the given shearing coefficients.
  `void`
  `preTransform(Vector3 vec)`
  Transform a three-dimensional row vector by pre-multiplication (vec3 * this, w-component is considered as 1).
  `void`
  `preTransform(Vector4 vec)`
  Transform a four-dimensional row vector by pre-multiplication (vector * matrix).
  `void`
  `preTranslate(float dx, float dy)`
  Apply a translation to this matrix by translating by the given number of units in x, y and z.
  `void`
  `preTranslate(float dx, float dy, float dz)`
  Apply a translation to this matrix by translating by the given number of units in x, y and z.
  `void`
  `preTranslate(Vector3 t)`
  Translates this matrix by given changes.
  `void`
  `preTranslateX(float dx)`
  Translates this matrix by given vector.
  `void`
  `preTranslateY(float dy)`
  Translates this matrix by given vector.
  `void`
  `preTranslateZ(float dz)`
  Translates this matrix by given vector.
  `void`
  `set(float[] a)`
  Set the values in the matrix using a float array that contains the matrix elements in row-major order.
  `void`
  `set(float[] a, int offset)`
  Set the values in the matrix using a float array that contains the matrix elements in row-major order.
  `void`
  `set(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44)`
  Set the values within this matrix to the given float values.
  `void`
  `set(long p)`
  Set the values in the matrix using an address that contains the matrix elements in row-major order (UNSAFE).
  `void`
  `set(Matrix4c m)`
  Store the values of the given matrix into this matrix.
  `void`
  `set(ByteBuffer a)`
  Set the values in the matrix using a float array that contains the matrix elements in row-major order.
  `void`
  `set(FloatBuffer a)`
  Set the values in the matrix using a float array that contains the matrix elements in row-major order.
  `void`
  `setIdentity()`
  Reset this matrix to the identity.
  `Matrix4`
  `setOrthographic(float width, float height, float near, float far, boolean flipY)`
  Set this matrix to an orthographic projection matrix.
  `Matrix4`
  `setOrthographic(float left, float right, float bottom, float top, float near, float far)`
  Set this matrix to an orthographic projection matrix.
  `void`
  `setOrthographic(float left, float right, float bottom, float top, float near, float far, boolean negativeOneToOne)`
  Set this matrix to be an orthographic projection transformation for a right-handed coordinate system using the given NDC z range.
  `void`
  `setOrthographicLH(float left, float right, float bottom, float top, float near, float far, boolean negativeOneToOne)`
  Set this matrix to be an orthographic projection transformation for a left-handed coordinate system using the given NDC z range.
  `void`
  `setPerspective(double fov, double aspect, float near, float far, boolean negativeOneToOne)`
  Set this matrix to be a symmetric perspective projection frustum transformation for a right-handed coordinate system using the given NDC z range.
  `Matrix4`
  `setPerspective(float fov, float aspect, float near, float far)`
  Set this matrix to a perspective projection matrix.
  `Matrix4`
  `setPerspective(float left, float right, float bottom, float top, float near, float far)`
  Set this matrix to a perspective projection matrix.
  `void`
  `setPerspectiveLH(double fov, double aspect, float near, float far, boolean negativeOneToOne)`
  Set this matrix to be a symmetric perspective projection frustum transformation for a left-handed coordinate system using the given NDC z range.
  `void`
  `setRotation(Quaternion q)`
  Set this matrix to a rotation matrix by the quaternion's rotation.
  `void`
  `setScale(float x, float y, float z)`
  Set this matrix to be a simple scale matrix.
  `void`
  `setScale(Vector3 s)`
  Sets this matrix to a scaling matrix by given components.
  `void`
  `setShear(float sxy, float sxz, float syx, float syz, float szx, float szy)`
  Resets this matrix to a shearing matrix.
  `void`
  `setTranslate(float x, float y, float z)`
  Set this matrix to be a simple translation matrix.
  `void`
  `setTranslate(Vector3 t)`
  Sets this matrix to a translation matrix by given components.
  `void`
  `setZero()`
  Set all elements of this matrix to `0`.
  `void`
  `store(float[] a)`
  Store this matrix into the give float array in row-major order.
  `void`
  `store(float[] a, int offset)`
  Store this matrix into the give float array in row-major order.
  `void`
  `store(long p)`
  Store this matrix into the given address in GLSL column-major or HLSL row-major order.
  `void`
  `store(Matrix4 m)`
  Store this matrix elements to the given matrix.
  `void`
  `store(ByteBuffer a)`
  Store this matrix into the give float array in row-major order.
  `void`
  `store(FloatBuffer a)`
  Store this matrix into the give float array in row-major order.
  `void`
  `storeAs2D(long p)`
  Store this matrix as 2D matrix into the given address in GLSL column-major or HLSL row-major order, NOT vec4 aligned.
  `void`
  `storeAs2DAligned(long p)`
  Store this matrix as 2D matrix into the given address in GLSL column-major or HLSL row-major order, NOT vec4 aligned.
  `void`
  `subtract(Matrix4 m)`
  Subtract each element of the given matrix from the corresponding element of this matrix.
  `Matrix`
  `toMatrix()`
  Converts this 4x4 matrix to 3x3 matrix, the third row and column are discarded.
  `void`
  `toMatrix(Matrix dest)`
  Converts this 4x4 matrix to 3x3 matrix, the third row and column are discarded.
  `Matrix3`
  `toMatrix3()`
  Converts this 4x4 matrix to 3x3 matrix, the fourth row and column are discarded.
  `void`
  `toMatrix3(Matrix3 dest)`
  Converts this 4x4 matrix to 3x3 matrix, the fourth row and column are discarded.
  `String`
  `toString()`
  `float`
  `trace()`
  Compute the trace of this matrix.
  `void`
  `transpose()`
  Transpose this matrix.

  ### Methods inherited from class java.lang.Object

  `finalize, getClass, notify, notifyAll, wait, wait, wait`

- ## Field Details

  - ### m11

    public float m11

  - ### m12

    public float m12

  - ### m13

    public float m13

  - ### m14

    public float m14

  - ### m21

    public float m21

  - ### m22

    public float m22

  - ### m23

    public float m23

  - ### m24

    public float m24

  - ### m31

    public float m31

  - ### m32

    public float m32

  - ### m33

    public float m33

  - ### m34

    public float m34

  - ### m41

    public float m41

  - ### m42

    public float m42

  - ### m43

    public float m43

  - ### m44

    public float m44

- ## Constructor Details

  - ### Matrix4

    public Matrix4()
    Create a new identity matrix.

  - ### Matrix4

    public Matrix4(@Nonnull Matrix4c m)
    Create a matrix copied from an existing matrix.
    Parameters:
      `m` - the matrix to create from

  - ### Matrix4

    public Matrix4(@Nonnull float... a)
    Create a matrix from an array of elements in row-major.
    Parameters:
      `a` - the array to create from
    See Also:
      - `set(float[])`

- ## Method Details

  - ### copy

    @Nonnull public static Matrix4 copy(@Nullable Matrix4c m)
    Create a copy of `mat` if not null, otherwise a new identity matrix. Note: we assume null is identity.
    Parameters:
      `m` - the matrix to copy from
    Returns:
      a copy of the matrix

  - ### identity

    @Nonnull public static Matrix4c identity()
    Returns a read-only identity matrix.
    Returns:
      an identity matrix

  - ### makeTranslate

    @Nonnull public static Matrix4 makeTranslate(float x, float y, float z)
    Create a new translation transformation matrix.
    Parameters:
      `x` - the x-component of the translation
      `y` - the y-component of the translation
      `z` - the z-component of the translation
    Returns:
      the resulting matrix

  - ### makeScale

    @Nonnull public static Matrix4 makeScale(float x, float y, float z)
    Create a new scaling transformation matrix.
    Parameters:
      `x` - the x-component of the scaling
      `y` - the y-component of the scaling
      `z` - the z-component of the scaling
    Returns:
      the resulting matrix

  - ### makeOrthographic

    @Nonnull public static Matrix4 makeOrthographic(float left, float right, float bottom, float top, float near, float far)
    Create an orthographic projection matrix.
    Parameters:
      `left` - the left frustum plane
      `right` - the right frustum plane
      `bottom` - the bottom frustum plane
      `top` - the top frustum plane
      `near` - the near frustum plane, must be positive
      `far` - the far frustum plane, must be positive
    Returns:
      the resulting matrix

  - ### makeOrthographic

    @Nonnull public static Matrix4 makeOrthographic(float width, float height, float near, float far, boolean flipY)
    Create an orthographic projection matrix. The left plane and top plane are considered to be 0.
    Parameters:
      `width` - the distance from right frustum plane to left frustum plane
      `height` - the distance from bottom frustum plane to top frustum plane
      `near` - the near frustum plane, must be positive
      `far` - the far frustum plane, must be positive
      `flipY` - whether to flip the projection vertically
    Returns:
      the resulting matrix

  - ### makePerspective

    @Nonnull public static Matrix4 makePerspective(float left, float right, float bottom, float top, float near, float far)
    Create a perspective projection matrix.
    Parameters:
      `left` - the left frustum plane
      `right` - the right frustum plane
      `bottom` - the bottom frustum plane
      `top` - the top frustum plane
      `near` - the near frustum plane, must be positive
      `far` - the far frustum plane, must be positive
    Returns:
      the resulting matrix

  - ### makePerspective

    @Nonnull public static Matrix4 makePerspective(float fov, float aspect, float near, float far)
    Create a perspective projection matrix.
    Parameters:
      `fov` - the angle of field of view in radians (0,PI)
      `aspect` - aspect ratio of the view (width / height)
      `near` - the near frustum plane, must be positive
      `far` - the far frustum plane, must be positive
    Returns:
      the resulting matrix

  - ### m11

    public float m11()
    Specified by:
      `m11` in interface `Matrix4c`

  - ### m12

    public float m12()
    Specified by:
      `m12` in interface `Matrix4c`

  - ### m13

    public float m13()
    Specified by:
      `m13` in interface `Matrix4c`

  - ### m14

    public float m14()
    Specified by:
      `m14` in interface `Matrix4c`

  - ### m21

    public float m21()
    Specified by:
      `m21` in interface `Matrix4c`

  - ### m22

    public float m22()
    Specified by:
      `m22` in interface `Matrix4c`

  - ### m23

    public float m23()
    Specified by:
      `m23` in interface `Matrix4c`

  - ### m24

    public float m24()
    Specified by:
      `m24` in interface `Matrix4c`

  - ### m31

    public float m31()
    Specified by:
      `m31` in interface `Matrix4c`

  - ### m32

    public float m32()
    Specified by:
      `m32` in interface `Matrix4c`

  - ### m33

    public float m33()
    Specified by:
      `m33` in interface `Matrix4c`

  - ### m34

    public float m34()
    Specified by:
      `m34` in interface `Matrix4c`

  - ### m41

    public float m41()
    Specified by:
      `m41` in interface `Matrix4c`

  - ### m42

    public float m42()
    Specified by:
      `m42` in interface `Matrix4c`

  - ### m43

    public float m43()
    Specified by:
      `m43` in interface `Matrix4c`

  - ### m44

    public float m44()
    Specified by:
      `m44` in interface `Matrix4c`

  - ### add

    public void add(@Nonnull Matrix4 m)
    Add each element of the given matrix to the corresponding element of this matrix.
    Parameters:
      `m` - the addend

  - ### subtract

    public void subtract(@Nonnull Matrix4 m)
    Subtract each element of the given matrix from the corresponding element of this matrix.
    Parameters:
      `m` - the subtrahend

  - ### preConcat

    public void preConcat(@Nonnull Matrix4c lhs)
    Pre-multiply this matrix by the given `lhs` matrix.

    If `M` is `this` matrix and `L` the `lhs` matrix, then the new matrix will be `L * M` (row-major). So when transforming a vector `v` with the new matrix by using `v * L * M`, the transformation of the left-hand side matrix will be applied first.

    Parameters:
      `lhs` - the left-hand side matrix to multiply

  - ### preConcat

    public void preConcat(float l11, float l12, float l13, float l14, float l21, float l22, float l23, float l24, float l31, float l32, float l33, float l34, float l41, float l42, float l43, float l44)
    Pre-multiply this matrix by the given `lhs` matrix.

    If `M` is `this` matrix and `L` the `lhs` matrix, then the new matrix will be `L * M` (row-major). So when transforming a vector `v` with the new matrix by using `v * L * M`, the transformation of the left-hand side matrix will be applied first.

    Parameters:
      `l11` - the m11 element of the left-hand side matrix
      `l12` - the m12 element of the left-hand side matrix
      `l13` - the m13 element of the left-hand side matrix
      `l14` - the m14 element of the left-hand side matrix
      `l21` - the m21 element of the left-hand side matrix
      `l22` - the m22 element of the left-hand side matrix
      `l23` - the m23 element of the left-hand side matrix
      `l24` - the m24 element of the left-hand side matrix
      `l31` - the m31 element of the left-hand side matrix
      `l32` - the m32 element of the left-hand side matrix
      `l33` - the m33 element of the left-hand side matrix
      `l34` - the m34 element of the left-hand side matrix
      `l41` - the m41 element of the left-hand side matrix
      `l42` - the m42 element of the left-hand side matrix
      `l43` - the m43 element of the left-hand side matrix
      `l44` - the m44 element of the left-hand side matrix

  - ### postConcat

    public void postConcat(@Nonnull Matrix4c rhs)
    Post-multiply this matrix by the given `rhs` matrix.

    If `M` is `this` matrix and `R` the `rhs` matrix, then the new matrix will be `M * R` (row-major). So when transforming a vector `v` with the new matrix by using `v * M * R`, the transformation of `this` matrix will be applied first.

    Parameters:
      `rhs` - the right-hand side matrix to multiply

  - ### postConcat

    public void postConcat(float r11, float r12, float r13, float r14, float r21, float r22, float r23, float r24, float r31, float r32, float r33, float r34, float r41, float r42, float r43, float r44)
    Post-multiply this matrix by the given `rhs` matrix.

    If `M` is `this` matrix and `R` the `rhs` matrix, then the new matrix will be `M * R` (row-major). So when transforming a vector `v` with the new matrix by using `v * M * R`, the transformation of `this` matrix will be applied first.

    Parameters:
      `r11` - the m11 element of the right-hand side matrix
      `r12` - the m12 element of the right-hand side matrix
      `r13` - the m13 element of the right-hand side matrix
      `r14` - the m14 element of the right-hand side matrix
      `r21` - the m21 element of the right-hand side matrix
      `r22` - the m22 element of the right-hand side matrix
      `r23` - the m23 element of the right-hand side matrix
      `r24` - the m24 element of the right-hand side matrix
      `r31` - the m31 element of the right-hand side matrix
      `r32` - the m32 element of the right-hand side matrix
      `r33` - the m33 element of the right-hand side matrix
      `r34` - the m34 element of the right-hand side matrix
      `r41` - the m41 element of the right-hand side matrix
      `r42` - the m42 element of the right-hand side matrix
      `r43` - the m43 element of the right-hand side matrix
      `r44` - the m44 element of the right-hand side matrix

  - ### preConcat2D

    public void preConcat2D(@Nonnull Matrixc lhs)
    Pre-multiply this matrix by the given `lhs` matrix. The matrix will be expanded to a 4x4 matrix.

         [ a b c ]      [ a b 0 c ]
         [ d e f ]  ->  [ d e 0 f ]
         [ g h i ]      [ 0 0 1 0 ]
                        [ g h 0 i ]

    If `M` is `this` matrix and `L` the `lhs` matrix, then the new matrix will be `L * M` (row-major). So when transforming a vector `v` with the new matrix by using `v * L * M`, the transformation of the left-hand side matrix will be applied first.
    Parameters:
      `lhs` - the left-hand side matrix to multiply

  - ### postConcat2D

    public void postConcat2D(@Nonnull Matrixc rhs)
    Post-multiply this matrix by the given `rhs` matrix. The matrix will be expanded to a 4x4 matrix.

         [ a b c ]      [ a b 0 c ]
         [ d e f ]  ->  [ d e 0 f ]
         [ g h i ]      [ 0 0 1 0 ]
                        [ g h 0 i ]

    If `M` is `this` matrix and `R` the `rhs` matrix, then the new matrix will be `M * R` (row-major). So when transforming a vector `v` with the new matrix by using `v * M * R`, the transformation of `this` matrix will be applied first.
    Parameters:
      `rhs` - the right-hand side matrix to multiply

  - ### preConcat

    public void preConcat(@Nonnull Matrix3 lhs)
    Pre-multiply this matrix by the given `lhs` matrix. The matrix will be expanded to a 4x4 matrix.

         [ a b c ]      [ a b c 0 ]
         [ d e f ]  ->  [ d e f 0 ]
         [ g h i ]      [ g h i 0 ]
                        [ 0 0 0 1 ]

    If `M` is `this` matrix and `L` the `lhs` matrix, then the new matrix will be `L * M` (row-major). So when transforming a vector `v` with the new matrix by using `v * L * M`, the transformation of the left-hand side matrix will be applied first.
    Parameters:
      `lhs` - the left-hand side matrix to multiply

  - ### postConcat

    public void postConcat(@Nonnull Matrix3 rhs)
    Post-multiply this matrix by the given `rhs` matrix. The matrix will be expanded to a 4x4 matrix.

         [ a b c ]      [ a b c 0 ]
         [ d e f ]  ->  [ d e f 0 ]
         [ g h i ]      [ g h i 0 ]
                        [ 0 0 0 1 ]

    If `M` is `this` matrix and `R` the `rhs` matrix, then the new matrix will be `M * R` (row-major). So when transforming a vector `v` with the new matrix by using `v * M * R`, the transformation of `this` matrix will be applied first.
    Parameters:
      `rhs` - the right-hand side matrix to multiply

  - ### setZero

    public void setZero()
    Set all elements of this matrix to `0`.

  - ### setIdentity

    public void setIdentity()
    Reset this matrix to the identity.

  - ### set

    public void set(@Nonnull Matrix4c m)
    Store the values of the given matrix into this matrix.
    Parameters:
      `m` - the matrix to copy from

  - ### set

    public void set(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44)
    Set the values within this matrix to the given float values.
    Parameters:
      `m11` - the new value of m11
      `m12` - the new value of m12
      `m13` - the new value of m13
      `m14` - the new value of m14
      `m21` - the new value of m21
      `m22` - the new value of m22
      `m23` - the new value of m23
      `m24` - the new value of m24
      `m31` - the new value of m31
      `m32` - the new value of m32
      `m33` - the new value of m33
      `m34` - the new value of m34
      `m41` - the new value of m41
      `m42` - the new value of m42
      `m43` - the new value of m43
      `m44` - the new value of m44

  - ### set

    public void set(@Nonnull float[] a)
    Set the values in the matrix using a float array that contains the matrix elements in row-major order.
    Parameters:
      `a` - the array to copy from

  - ### set

    public void set(@Nonnull float[] a, int offset)
    Set the values in the matrix using a float array that contains the matrix elements in row-major order.
    Parameters:
      `a` - the array to copy from
      `offset` - the element offset

  - ### set

    public void set(@Nonnull ByteBuffer a)
    Set the values in the matrix using a float array that contains the matrix elements in row-major order.
    Parameters:
      `a` - the array to copy from

  - ### set

    public void set(@Nonnull FloatBuffer a)
    Set the values in the matrix using a float array that contains the matrix elements in row-major order.
    Parameters:
      `a` - the array to copy from

  - ### set

    public void set(long p)
    Set the values in the matrix using an address that contains the matrix elements in row-major order (UNSAFE).
    Parameters:
      `p` - the pointer of the array to copy from

  - ### store

    public void store(@Nonnull Matrix4 m)
    Store this matrix elements to the given matrix.
    Specified by:
      `store` in interface `Matrix4c`
    Parameters:
      `m` - the matrix to store

  - ### store

    public void store(@Nonnull float[] a)
    Store this matrix into the give float array in row-major order.
    Specified by:
      `store` in interface `Matrix4c`
    Parameters:
      `a` - the array to store into

  - ### store

    public void store(@Nonnull float[] a, int offset)
    Store this matrix into the give float array in row-major order.
    Specified by:
      `store` in interface `Matrix4c`
    Parameters:
      `a` - the array to store into
      `offset` - the element offset

  - ### store

    public void store(@Nonnull ByteBuffer a)
    Store this matrix into the give float array in row-major order.
    Specified by:
      `store` in interface `Matrix4c`
    Parameters:
      `a` - the pointer of the array to store

  - ### store

    public void store(@Nonnull FloatBuffer a)
    Store this matrix into the give float array in row-major order.
    Specified by:
      `store` in interface `Matrix4c`
    Parameters:
      `a` - the pointer of the array to store

  - ### store

    public void store(long p)
    Store this matrix into the given address in GLSL column-major or HLSL row-major order.
    Specified by:
      `store` in interface `Matrix4c`
    Parameters:
      `p` - the pointer of the array to store

  - ### storeAs2D

    public void storeAs2D(long p)
    Store this matrix as 2D matrix into the given address in GLSL column-major or HLSL row-major order, NOT vec4 aligned.

    Equivalent to call `toMatrix()` and `Matrix.store(long)`.

    Specified by:
      `storeAs2D` in interface `Matrix4c`
    Parameters:
      `p` - the pointer of the array to store

  - ### storeAs2DAligned

    public void storeAs2DAligned(long p)
    Store this matrix as 2D matrix into the given address in GLSL column-major or HLSL row-major order, NOT vec4 aligned.

    Equivalent to call `toMatrix()` and `Matrix.storeAligned(long)`.

    Specified by:
      `storeAs2DAligned` in interface `Matrix4c`
    Parameters:
      `p` - the pointer of the array to store

  - ### determinant

    public float determinant()
    Return the determinant of this matrix.
    Specified by:
      `determinant` in interface `Matrix4c`
    Returns:
      the determinant

  - ### trace

    public float trace()
    Compute the trace of this matrix.
    Returns:
      the trace of this matrix

  - ### transpose

    public void transpose()
    Transpose this matrix.

  - ### invert

    @CheckReturnValue public boolean invert()
    Compute the inverse of this matrix. This matrix will be inverted if it is invertible, otherwise it keeps the same as before.
    Returns:
      `true` if this matrix is invertible.

  - ### invert

    public boolean invert(@Nullable Matrix4 dest)
    Compute the inverse of this matrix. The matrix will be inverted if this matrix is invertible, otherwise it keeps the same as before.
    Specified by:
      `invert` in interface `Matrix4c`
    Parameters:
      `dest` - the destination matrix
    Returns:
      `true` if this matrix is invertible.

  - ### setOrthographic

    @Nonnull public Matrix4 setOrthographic(float left, float right, float bottom, float top, float near, float far)
    Set this matrix to an orthographic projection matrix.
    Parameters:
      `left` - the left frustum plane
      `right` - the right frustum plane
      `bottom` - the bottom frustum plane
      `top` - the top frustum plane
      `near` - the near frustum plane, must be positive
      `far` - the far frustum plane, must be positive
    Returns:
      this

  - ### setOrthographic

    @Nonnull public Matrix4 setOrthographic(float width, float height, float near, float far, boolean flipY)
    Set this matrix to an orthographic projection matrix.
    Parameters:
      `width` - the distance from right frustum plane to left frustum plane
      `height` - the distance from bottom frustum plane to top frustum plane
      `near` - the near frustum plane, must be positive
      `far` - the far frustum plane, must be positive
      `flipY` - whether to flip the projection vertically
    Returns:
      this

  - ### setOrthographic

    public void setOrthographic(float left, float right, float bottom, float top, float near, float far, boolean negativeOneToOne)
    Set this matrix to be an orthographic projection transformation for a right-handed coordinate system using the given NDC z range.
    Parameters:
      `left` - the distance from the center to the left frustum edge
      `right` - the distance from the center to the right frustum edge
      `bottom` - the distance from the center to the bottom frustum edge
      `top` - the distance from the center to the top frustum edge
      `near` - near clipping plane distance
      `far` - far clipping plane distance
      `negativeOneToOne` - whether to use Vulkan's and Direct3D's NDC z range of `[0..+1]` when `false` or whether to use OpenGL's NDC z range of `[-1..+1]` when `true`

  - ### setOrthographicLH

    public void setOrthographicLH(float left, float right, float bottom, float top, float near, float far, boolean negativeOneToOne)
    Set this matrix to be an orthographic projection transformation for a left-handed coordinate system using the given NDC z range.
    Parameters:
      `left` - the distance from the center to the left frustum edge
      `right` - the distance from the center to the right frustum edge
      `bottom` - the distance from the center to the bottom frustum edge
      `top` - the distance from the center to the top frustum edge
      `near` - near clipping plane distance
      `far` - far clipping plane distance
      `negativeOneToOne` - whether to use Vulkan's and Direct3D's NDC z range of `[0..+1]` when `false` or whether to use OpenGL's NDC z range of `[-1..+1]` when `true`

  - ### setPerspective

    @Nonnull public Matrix4 setPerspective(float left, float right, float bottom, float top, float near, float far)
    Set this matrix to a perspective projection matrix.
    Parameters:
      `left` - the left frustum plane
      `right` - the right frustum plane
      `bottom` - the bottom frustum plane
      `top` - the top frustum plane
      `near` - the near frustum plane, must be positive
      `far` - the far frustum plane, must be positive
    Returns:
      this

  - ### setPerspective

    @Nonnull public Matrix4 setPerspective(float fov, float aspect, float near, float far)
    Set this matrix to a perspective projection matrix.
    Parameters:
      `fov` - the angle of field of view in radians (0,PI)
      `aspect` - aspect ratio of the view (width / height)
      `near` - the near frustum plane, must be positive
      `far` - the far frustum plane, must be positive
    Returns:
      this

  - ### setPerspective

    public void setPerspective(double fov, double aspect, float near, float far, boolean negativeOneToOne)
    Set this matrix to be a symmetric perspective projection frustum transformation for a right-handed coordinate system using the given NDC z range.
    Parameters:
      `fov` - the field of view in radians (must be greater than zero and less than PI)
      `aspect` - the aspect ratio of the view (i.e. width / height)
      `near` - the near clipping plane, must be positive
      `far` - the far clipping plane, must be positive
      `negativeOneToOne` - whether to use Vulkan's and Direct3D's NDC z range of `[0..+1]` when `false` or whether to use OpenGL's NDC z range of `[-1..+1]` when `true`

  - ### setPerspectiveLH

    public void setPerspectiveLH(double fov, double aspect, float near, float far, boolean negativeOneToOne)
    Set this matrix to be a symmetric perspective projection frustum transformation for a left-handed coordinate system using the given NDC z range.
    Parameters:
      `fov` - the field of view in radians (must be greater than zero and less than PI)
      `aspect` - the aspect ratio of the view (i.e. width / height)
      `near` - the near clipping plane, must be positive
      `far` - the far clipping plane, must be positive
      `negativeOneToOne` - whether to use Vulkan's and Direct3D's NDC z range of `[0..+1]` when `false` or whether to use OpenGL's NDC z range of `[-1..+1]` when `true`

  - ### preTranslateX

    public void preTranslateX(float dx)
    Translates this matrix by given vector. This is equivalent to pre-multiplying by a translation matrix.
    Parameters:
      `dx` - the x-component of the translation

  - ### postTranslateX

    public void postTranslateX(float dx)
    Post-translates this matrix by given vector. This is equivalent to post-multiplying by a translation matrix.
    Parameters:
      `dx` - the x-component of the translation

  - ### preTranslateY

    public void preTranslateY(float dy)
    Translates this matrix by given vector. This is equivalent to pre-multiplying by a translation matrix.
    Parameters:
      `dy` - the y-component of the translation

  - ### postTranslateY

    public void postTranslateY(float dy)
    Post-translates this matrix by given vector. This is equivalent to post-multiplying by a translation matrix.
    Parameters:
      `dy` - the y-component of the translation

  - ### preTranslateZ

    public void preTranslateZ(float dz)
    Translates this matrix by given vector. This is equivalent to pre-multiplying by a translation matrix.
    Parameters:
      `dz` - the z-component of the translation

  - ### postTranslateZ

    public void postTranslateZ(float dz)
    Post-translates this matrix by given vector. This is equivalent to post-multiplying by a translation matrix.
    Parameters:
      `dz` - the z-component of the translation

  - ### preTranslate

    public void preTranslate(@Nonnull Vector3 t)
    Translates this matrix by given changes. This is equivalent to pre-multiplying by a translation matrix. (translation * this)
    Parameters:
      `t` - the translation vector

  - ### preTranslate

    public void preTranslate(float dx, float dy, float dz)
    Apply a translation to this matrix by translating by the given number of units in x, y and z.

    If `M` is `this` matrix and `T` the translation matrix, then the new matrix will be `T * M` (row-major). So when transforming a vector `v` with the new matrix by using `v * T * M`, the translation will be applied first.

    Parameters:
      `dx` - the x-component of the translation
      `dy` - the y-component of the translation
      `dz` - the z-component of the translation

  - ### preTranslate

    public void preTranslate(float dx, float dy)
    Apply a translation to this matrix by translating by the given number of units in x, y and z.

    If `M` is `this` matrix and `T` the translation matrix, then the new matrix will be `T * M` (row-major). So when transforming a vector `v` with the new matrix by using `v * T * M`, the translation will be applied first.

    Parameters:
      `dx` - the x-component of the translation
      `dy` - the y-component of the translation

  - ### postTranslate

    public void postTranslate(@Nonnull Vector3 t)
    Post-translates this matrix by given changes. This is equivalent to post-multiplying by a translation matrix. (this * translation)
    Parameters:
      `t` - the translation vector

  - ### postTranslate

    public void postTranslate(float dx, float dy, float dz)
    Post-multiply a translation to this matrix by translating by the given number of units in x, y and z.

    If `M` is `this` matrix and `T` the translation matrix, then the new matrix will be `M * T` (row-major). So when transforming a vector `v` with the new matrix by using `v * M * T`, the translation will be applied last.

    Parameters:
      `dx` - the x-component of the translation
      `dy` - the y-component of the translation
      `dz` - the z-component of the translation

  - ### postTranslate

    public void postTranslate(float dx, float dy)
    Post-multiply a translation to this matrix by translating by the given number of units in x, y and z.

    If `M` is `this` matrix and `T` the translation matrix, then the new matrix will be `M * T` (row-major). So when transforming a vector `v` with the new matrix by using `v * M * T`, the translation will be applied last.

    Parameters:
      `dx` - the x-component of the translation
      `dy` - the y-component of the translation

  - ### setTranslate

    public void setTranslate(@Nonnull Vector3 t)
    Sets this matrix to a translation matrix by given components.
    Parameters:
      `t` - the translation vector

  - ### setTranslate

    public void setTranslate(float x, float y, float z)
    Set this matrix to be a simple translation matrix.
    Parameters:
      `x` - the x-component of the translation
      `y` - the y-component of the translation
      `z` - the z-component of the translation

  - ### preScaleX

    public void preScaleX(float s)
    Scales this matrix by given vector. This is equivalent to pre-multiplying by a scale matrix.
    Parameters:
      `s` - the x-component of the scale

  - ### postScaleX

    public void postScaleX(float s)
    Post-scales this matrix by given vector. This is equivalent to post-multiplying by a scale matrix.
    Parameters:
      `s` - the x-component of the scale

  - ### preScaleY

    public void preScaleY(float s)
    Scales this matrix by given vector. This is equivalent to pre-multiplying by a scale matrix.
    Parameters:
      `s` - the y-component of the scale

  - ### postScaleY

    public void postScaleY(float s)
    Post-scales this matrix by given vector. This is equivalent to post-multiplying by a scale matrix.
    Parameters:
      `s` - the y-component of the scale

  - ### preScaleZ

    public void preScaleZ(float s)
    Scales this matrix by given vector. This is equivalent to pre-multiplying by a scale matrix.
    Parameters:
      `s` - the x-component of the scale

  - ### postScaleZ

    public void postScaleZ(float s)
    Post-scales this matrix by given vector. This is equivalent to post-multiplying by a scale matrix.
    Parameters:
      `s` - the x-component of the scale

  - ### preScale

    public void preScale(@Nonnull Vector3 s)
    Scales this matrix by given vector. This is equivalent to pre-multiplying by a scale matrix.
    Parameters:
      `s` - the scale vector

  - ### preScale

    public void preScale(float sx, float sy, float sz)
    Apply scaling to `this` matrix by scaling the base axes by the given x, y and z factors and store the result in `dest`.

    If `M` is `this` matrix and `S` the scaling matrix, then the new matrix will be `S * M` (row-major). So when transforming a vector `v` with the new matrix by using `v * S * M`, the scaling will be applied first.

    Parameters:
      `sx` - the x-component of the scale
      `sy` - the y-component of the scale
      `sz` - the z-component of the scale

  - ### preScale

    public void preScale(float sx, float sy)
    Apply scaling to `this` matrix by scaling the base axes by the given x, y and z factors and store the result in `dest`.

    If `M` is `this` matrix and `S` the scaling matrix, then the new matrix will be `S * M` (row-major). So when transforming a vector `v` with the new matrix by using `v * S * M`, the scaling will be applied first.

    Parameters:
      `sx` - the x-component of the scale
      `sy` - the y-component of the scale

  - ### postScale

    public void postScale(@Nonnull Vector3 s)
    Post-scales this matrix by given vector. This is equivalent to post-multiplying by a scale matrix.
    Parameters:
      `s` - the scale vector

  - ### postScale

    public void postScale(float sx, float sy, float sz)
    Post-multiply scaling to `this` matrix by scaling the base axes by the given x, y and z factors and store the result in `dest`.

    If `M` is `this` matrix and `S` the scaling matrix, then the new matrix will be `M * S` (row-major). So when transforming a vector `v` with the new matrix by using `v * M * S`, the scaling will be applied last.

    Parameters:
      `sx` - the x-component of the scale
      `sy` - the y-component of the scale
      `sz` - the z-component of the scale

  - ### postScale

    public void postScale(float sx, float sy)
    Post-multiply scaling to `this` matrix by scaling the base axes by the given x, y and z factors and store the result in `dest`.

    If `M` is `this` matrix and `S` the scaling matrix, then the new matrix will be `M * S` (row-major). So when transforming a vector `v` with the new matrix by using `v * M * S`, the scaling will be applied last.

    Parameters:
      `sx` - the x-component of the scale
      `sy` - the y-component of the scale

  - ### setScale

    public void setScale(@Nonnull Vector3 s)
    Sets this matrix to a scaling matrix by given components.
    Parameters:
      `s` - the scale vector

  - ### setScale

    public void setScale(float x, float y, float z)
    Set this matrix to be a simple scale matrix.
    Parameters:
      `x` - the x-component of the scale
      `y` - the y-component of the scale
      `z` - the z-component of the scale

  - ### preShear

    public void preShear(float sxy, float sxz, float syx, float syz, float szx, float szy)
    Pre-multiply shearing to `this` matrix by the given shearing coefficients.

    This is equivalent to pre-multiplying by a shearing matrix.

    1 | sxy | sxz
    syx | 1 | syz
    szx | szy | 1

    Parameters:
      `sxy` - the y-component of the shearing in x direction, x is unchanged
      `sxz` - the z-component of the shearing in x direction, x is unchanged
      `syx` - the x-component of the shearing in y direction, y is unchanged
      `syz` - the z-component of the shearing in y direction, y is unchanged
      `szx` - the x-component of the shearing in z direction, z is unchanged
      `szy` - the y-component of the shearing in z direction, z is unchanged

  - ### postShear

    public void postShear(float sxy, float sxz, float syx, float syz, float szx, float szy)
    Post-multiply shearing to `this` matrix by the given shearing coefficients.

    This is equivalent to post-multiplying by a shearing matrix.

    1 | sxy | sxz
    syx | 1 | syz
    szx | szy | 1

    Parameters:
      `sxy` - the y-component of the shearing in x direction, x is unchanged
      `sxz` - the z-component of the shearing in x direction, x is unchanged
      `syx` - the x-component of the shearing in y direction, y is unchanged
      `syz` - the z-component of the shearing in y direction, y is unchanged
      `szx` - the x-component of the shearing in z direction, z is unchanged
      `szy` - the y-component of the shearing in z direction, z is unchanged

  - ### preShear2D

    public void preShear2D(float sx, float sy)
    Pre-multiply 2D shearing to `this` matrix by the given shearing coefficients.
    Parameters:
      `sx` - the x-component of the shearing in y direction, y is unchanged (horizontal shearing)
      `sy` - the y-component of the shearing in x direction, x is unchanged (vertical shearing)

  - ### postShear2D

    public void postShear2D(float sx, float sy)
    Post-multiply 2D shearing to `this` matrix by the given shearing coefficients.
    Parameters:
      `sx` - the x-component of the shearing in y direction, y is unchanged (horizontal shearing)
      `sy` - the y-component of the shearing in x direction, x is unchanged (vertical shearing)

  - ### setShear

    public void setShear(float sxy, float sxz, float syx, float syz, float szx, float szy)
    Resets this matrix to a shearing matrix.

  - ### preRotateX

    public void preRotateX(double angle)
    Rotates this matrix about the X-axis with the given angle in radians.

    When used with a right-handed coordinate system, the produced rotation will rotate a vector counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin. When used with a left-handed coordinate system, the rotation is clockwise.

    This is equivalent to pre-multiplying by a rotation matrix.

    1 | 0 | 0
    0 | cosθ | sinθ
    0 | -sinθ | cosθ

    Parameters:
      `angle` - the rotation angle in radians.

  - ### postRotateX

    public void postRotateX(double angle)
    Post-rotates this matrix about the X-axis with the given angle in radians.

    When used with a right-handed coordinate system, the produced rotation will rotate a vector counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin. When used with a left-handed coordinate system, the rotation is clockwise.

    This is equivalent to post-multiplying by a rotation matrix.

    1 | 0 | 0
    0 | cosθ | sinθ
    0 | -sinθ | cosθ

    Parameters:
      `angle` - the rotation angle in radians.

  - ### preRotateY

    public void preRotateY(double angle)
    Rotates this matrix about the Y-axis with the given angle in radians.

    When used with a right-handed coordinate system, the produced rotation will rotate a vector counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin. When used with a left-handed coordinate system, the rotation is clockwise.

    This is equivalent to pre-multiplying by a rotation matrix.

    cosθ | 0 | -sinθ
    0 | 1 | 0
    sinθ | 0 | cosθ

    Parameters:
      `angle` - the rotation angle in radians.

  - ### postRotateY

    public void postRotateY(double angle)
    Post-rotates this matrix about the Y-axis with the given angle in radians.

    When used with a right-handed coordinate system, the produced rotation will rotate a vector counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin. When used with a left-handed coordinate system, the rotation is clockwise.

    This is equivalent to post-multiplying by a rotation matrix.

    cosθ | 0 | -sinθ
    0 | 1 | 0
    sinθ | 0 | cosθ

    Parameters:
      `angle` - the rotation angle in radians.

  - ### preRotateZ

    public void preRotateZ(double angle)
    Rotates this matrix about the Z-axis with the given angle in radians.

    When used with a right-handed coordinate system, the produced rotation will rotate a vector counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin. When used with a left-handed coordinate system, the rotation is clockwise.

    This is equivalent to pre-multiplying by a rotation matrix.

    cosθ | sinθ | 0
    -sinθ | cosθ | 0
    0 | 0 | 1

    Parameters:
      `angle` - the rotation angle in radians.

  - ### postRotateZ

    public void postRotateZ(double angle)
    Post-rotates this matrix about the Z-axis with the given angle in radians.

    When used with a right-handed coordinate system, the produced rotation will rotate a vector counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin. When used with a left-handed coordinate system, the rotation is clockwise.

    This is equivalent to post-multiplying by a rotation matrix.

    cosθ | sinθ | 0
    -sinθ | cosθ | 0
    0 | 0 | 1

    Parameters:
      `angle` - the rotation angle in radians.

  - ### preRotate

    public void preRotate(double angleX, double angleY, double angleZ)
    Rotates this matrix from the given Euler rotation angles in radians.

    The rotations are applied in the given order and using chained rotation per axis:

    - x - pitch - `preRotateX(double)`
    - y - yaw - `preRotateY(double)`
    - z - roll - `preRotateZ(double)`
    When used with a right-handed coordinate system, the produced rotation will rotate a vector counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin. When used with a left-handed coordinate system, the rotation is clockwise.

    This is equivalent to pre-multiplying by three rotation matrices.

    Parameters:
      `angleX` - the Euler pitch angle in radians. (rotation about the X axis)
      `angleY` - the Euler yaw angle in radians. (rotation about the Y axis)
      `angleZ` - the Euler roll angle in radians. (rotation about the Z axis)
    See Also:
      - `preRotateY(double)`
      - `preRotateZ(double)`
      - `preRotateX(double)`

  - ### postRotate

    public void postRotate(double angleX, double angleY, double angleZ)
    Post-rotates this matrix from the given Euler rotation angles in radians.

    The rotations are applied in the given order and using chained rotation per axis:

    - x - pitch - `postRotateX(double)`
    - y - yaw - `postRotateY(double)`
    - z - roll - `postRotateZ(double)`
    When used with a right-handed coordinate system, the produced rotation will rotate a vector counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin. When used with a left-handed coordinate system, the rotation is clockwise.

    This is equivalent to post-multiplying by three rotation matrices.

    Parameters:
      `angleX` - the Euler pitch angle in radians. (rotation about the X axis)
      `angleY` - the Euler yaw angle in radians. (rotation about the Y axis)
      `angleZ` - the Euler roll angle in radians. (rotation about the Z axis)
    See Also:
      - `postRotateX(double)`
      - `postRotateY(double)`
      - `postRotateZ(double)`

  - ### preRotate

    public void preRotate(@Nonnull Vector3 axis, float angle)
    Rotates this matrix about an arbitrary axis. The axis must be a normalized (unit) vector. If the axis is X, Y or Z, use axis-specified methods to rotate this matrix which are faster.

    When used with a right-handed coordinate system, the produced rotation will rotate a vector counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin. When used with a left-handed coordinate system, the rotation is clockwise.

    Parameters:
      `axis` - the rotation axis
      `angle` - rotation angle in radians
    See Also:
      - `preRotateY(double)`
      - `preRotateZ(double)`
      - `preRotateX(double)`

  - ### preRotate

    public void preRotate(double x, double y, double z, double angle)
    Rotates this matrix about an arbitrary axis with the given angle in radians. The axis described by the three components must be normalized. If it is known that the rotation axis is X, Y or Z, use axis-specified methods instead.

    When used with a right-handed coordinate system, the produced rotation will rotate a vector counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin. When used with a left-handed coordinate system, the rotation is clockwise.

    This is equivalent to pre-multiplying by a quaternion.

    Parameters:
      `x` - x-coordinate of rotation axis
      `y` - y-coordinate of rotation axis
      `z` - z-coordinate of rotation axis
      `angle` - rotation angle in radians
    See Also:
      - `preRotateX(double)`
      - `preRotateY(double)`
      - `preRotateZ(double)`

  - ### preRotate

    public void preRotate(@Nonnull Quaternion q)
    Rotate this matrix by the given quaternion's rotation matrix. (quat * this)
    Parameters:
      `q` - the quaternion to rotate by.

  - ### postRotate

    public void postRotate(double x, double y, double z, double angle)
    Post-rotates this matrix about an arbitrary axis with the given angle in radians. The axis described by the three components must be normalized. If it is known that the rotation axis is X, Y or Z, use axis-specified methods instead.

    When used with a right-handed coordinate system, the produced rotation will rotate a vector counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin. When used with a left-handed coordinate system, the rotation is clockwise.

    This is equivalent to post-multiplying by a quaternion.

    Parameters:
      `x` - x-coordinate of rotation axis
      `y` - y-coordinate of rotation axis
      `z` - z-coordinate of rotation axis
      `angle` - rotation angle in radians
    See Also:
      - `postRotateX(double)`
      - `postRotateY(double)`
      - `postRotateZ(double)`

  - ### setRotation

    public void setRotation(@Nonnull Quaternion q)
    Set this matrix to a rotation matrix by the quaternion's rotation.
    Parameters:
      `q` - the quaternion to set by.

  - ### preTransform

    public void preTransform(@Nonnull Vector4 vec)
    Transform a four-dimensional row vector by pre-multiplication (vector * matrix). This is equivalent to (matrix * vector) in GLSL.
    Parameters:
      `vec` - the vector to transform

  - ### postTransform

    public void postTransform(@Nonnull Vector4 vec)
    Transform a four-dimensional column vector by post-multiplication (matrix * vector). This is equivalent to (vector * matrix) in GLSL.
    Parameters:
      `vec` - the vector to transform

  - ### preTransform

    public void preTransform(@Nonnull Vector3 vec)
    Transform a three-dimensional row vector by pre-multiplication (vec3 * this, w-component is considered as 1). This should be used with position vectors.
    Parameters:
      `vec` - the vector to transform

  - ### postTransform

    public void postTransform(@Nonnull Vector3 vec)
    Transform a three-dimensional column vector by post-multiplication (this * vec3, w-component is considered as 1). This should be used with normal vectors.
    Parameters:
      `vec` - the vector to transform

  - ### mapRect

    public void mapRect(@Nonnull Rect2f r)
    Map the four corners of 'r' and return the bounding box of those points. The four corners of 'r' are assumed to have z = 0 and w = 1. If the matrix has perspective, the returned rectangle will be the bounding box of the projected points after being clipped to w > 0.
    Specified by:
      `mapRect` in interface `Matrix4c`

  - ### mapRect

    public void mapRect(@Nonnull Rect2fc r, @Nonnull Rect2f dest)
    Map the four corners of 'r' and return the bounding box of those points. The four corners of 'r' are assumed to have z = 0 and w = 1. If the matrix has perspective, the returned rectangle will be the bounding box of the projected points after being clipped to w > 0.
    Specified by:
      `mapRect` in interface `Matrix4c`

  - ### mapRect

    public void mapRect(float left, float top, float right, float bottom, @Nonnull Rect2f dest)
    Map the four corners of 'r' and return the bounding box of those points. The four corners of 'r' are assumed to have z = 0 and w = 1. If the matrix has perspective, the returned rectangle will be the bounding box of the projected points after being clipped to w > 0.

  - ### mapRect

    public void mapRect(@Nonnull Rect2fc r, @Nonnull Rect2i dest)
    Map the four corners of 'r' and return the bounding box of those points. The four corners of 'r' are assumed to have z = 0 and w = 1. If the matrix has perspective, the returned rectangle will be the bounding box of the projected points after being clipped to w > 0.
    Specified by:
      `mapRect` in interface `Matrix4c`

  - ### mapRect

    public void mapRect(@Nonnull Rect2ic r, @Nonnull Rect2i dest)
    Map the four corners of 'r' and return the bounding box of those points. The four corners of 'r' are assumed to have z = 0 and w = 1. If the matrix has perspective, the returned rectangle will be the bounding box of the projected points after being clipped to w > 0.
    Specified by:
      `mapRect` in interface `Matrix4c`

  - ### mapRect

    public void mapRect(float left, float top, float right, float bottom, @Nonnull Rect2i dest)
    Map the four corners of 'r' and return the bounding box of those points. The four corners of 'r' are assumed to have z = 0 and w = 1. If the matrix has perspective, the returned rectangle will be the bounding box of the projected points after being clipped to w > 0.

  - ### mapRectOut

    public void mapRectOut(@Nonnull Rect2ic r, @Nonnull Rect2i dest)
    Map the four corners of 'r' and return the bounding box of those points. The four corners of 'r' are assumed to have z = 0 and w = 1. If the matrix has perspective, the returned rectangle will be the bounding box of the projected points after being clipped to w > 0.
    Specified by:
      `mapRectOut` in interface `Matrix4c`

  - ### mapRectOut

    public void mapRectOut(@Nonnull Rect2fc r, @Nonnull Rect2i dest)
    Map the four corners of 'r' and return the bounding box of those points. The four corners of 'r' are assumed to have z = 0 and w = 1. If the matrix has perspective, the returned rectangle will be the bounding box of the projected points after being clipped to w > 0.
    Specified by:
      `mapRectOut` in interface `Matrix4c`

  - ### mapRectOut

    public void mapRectOut(float left, float top, float right, float bottom, @Nonnull Rect2i dest)
    Map the four corners of 'r' and return the bounding box of those points. The four corners of 'r' are assumed to have z = 0 and w = 1. If the matrix has perspective, the returned rectangle will be the bounding box of the projected points after being clipped to w > 0.

  - ### mapRectIn

    public void mapRectIn(@Nonnull Rect2fc r, @Nonnull Rect2i dest)
    Description copied from interface: `Matrix4c`
    Map the four corners of 'r' and return the bounding box of those points. The four corners of 'r' are assumed to have z = 0 and w = 1. If the matrix has perspective, the returned rectangle will be the bounding box of the projected points after being clipped to w > 0.
    Specified by:
      `mapRectIn` in interface `Matrix4c`

  - ### mapRectIn

    public void mapRectIn(float left, float top, float right, float bottom, @Nonnull Rect2i dest)

  - ### mapPoint

    public void mapPoint(@Nonnull float[] p)
    Map a point in the X-Y plane.
    Parameters:
      `p` - the point to transform

  - ### mapPointX

    public float mapPointX(float x, float y)

  - ### mapPointY

    public float mapPointY(float x, float y)

  - ### mapVec3

    public void mapVec3(float[] vec)

  - ### isAffine

    public boolean isAffine()
    Returns whether this matrix is seen as an affine transformation. Otherwise, there's a perspective projection.
    Returns:
      `true` if this matrix is affine.

  - ### isScaleTranslate

    public boolean isScaleTranslate()
    Returns whether this matrix at most scales and translates.
    Specified by:
      `isScaleTranslate` in interface `Matrix4c`
    Returns:
      `true` if this matrix is scale, translate, or both.

  - ### isAxisAligned

    public boolean isAxisAligned()
    Returns whether this matrix transforms rect to another rect. If true, this matrix is identity, or/and scales, or/and rotates round Z axis a multiple of 90 degrees, or mirrors on axes. In all cases, this matrix is affine and may also have translation.

    For example:

              Matrix4 matrix = Matrix4.identity();
              matrix.translate(3, 5, 7);
              matrix.scale(2, 3, 4);
              matrix.rotateX(MathUtil.PI_DIV_4);
              matrix.rotateZ(MathUtil.PI_DIV_2);

    Specified by:
      `isAxisAligned` in interface `Matrix4c`
    Returns:
      true if this matrix transform one rect into another

  - ### normalizePerspective

    public void normalizePerspective()
    If the last column of the matrix is [0, 0, 0, not_one]^T, we will treat the matrix as if it is in perspective, even though it stills behaves like its affine. If we divide everything by the not_one value, then it will behave the same, but will be treated as affine, and therefore faster (e.g. clients can forward-difference calculations).

  - ### hasPerspective

    public boolean hasPerspective()
    Specified by:
      `hasPerspective` in interface `Matrix4c`

  - ### hasTranslation

    public boolean hasTranslation()

  - ### isIdentity

    public boolean isIdentity()
    Returns whether this matrix is approximately equivalent to an identity matrix.
    Returns:
      `true` if this matrix is identity.

  - ### localAARadius

    public float localAARadius(Rect2fc bounds)
    Return the minimum distance needed to move in local (pre-transform) space to ensure that the transformed coordinates are at least 1px away from the original mapped point. This minimum distance is specific to the given local 'bounds' since the scale factors change with perspective.

    If the bounds will be clipped by the w=0 plane or otherwise is ill-conditioned, this will return positive infinity.

    Specified by:
      `localAARadius` in interface `Matrix4c`

  - ### localAARadius

    public float localAARadius(float left, float top, float right, float bottom)
    Return the minimum distance needed to move in local (pre-transform) space to ensure that the transformed coordinates are at least 1px away from the original mapped point. This minimum distance is specific to the given local 'bounds' since the scale factors change with perspective.

    If the bounds will be clipped by the w=0 plane or otherwise is ill-conditioned, this will return positive infinity.

    Specified by:
      `localAARadius` in interface `Matrix4c`

  - ### toMatrix

    public void toMatrix(@Nonnull Matrix dest)
    Converts this 4x4 matrix to 3x3 matrix, the third row and column are discarded.

         [ a b x c ]      [ a b c ]
         [ d e x f ]  ->  [ d e f ]
         [ x x x x ]      [ g h i ]
         [ g h x i ]

    Specified by:
      `toMatrix` in interface `Matrix4c`

  - ### toMatrix

    @Nonnull public Matrix toMatrix()
    Converts this 4x4 matrix to 3x3 matrix, the third row and column are discarded.

         [ a b x c ]      [ a b c ]
         [ d e x f ]  ->  [ d e f ]
         [ x x x x ]      [ g h i ]
         [ g h x i ]

    Specified by:
      `toMatrix` in interface `Matrix4c`

  - ### toMatrix3

    public void toMatrix3(@Nonnull Matrix3 dest)
    Converts this 4x4 matrix to 3x3 matrix, the fourth row and column are discarded.

         [ a b c x ]      [ a b c ]
         [ d e f x ]  ->  [ d e f ]
         [ g h i x ]      [ g h i ]
         [ x x x x ]

    Specified by:
      `toMatrix3` in interface `Matrix4c`

  - ### toMatrix3

    @Nonnull public Matrix3 toMatrix3()
    Converts this 4x4 matrix to 3x3 matrix, the fourth row and column are discarded.

         [ a b c x ]      [ a b c ]
         [ d e f x ]  ->  [ d e f ]
         [ g h i x ]      [ g h i ]
         [ x x x x ]

    Specified by:
      `toMatrix3` in interface `Matrix4c`

  - ### isApproxEqual

    public boolean isApproxEqual(@Nonnull Matrix4 m)
    Returns whether this matrix is approximately equal to given matrix.
    Specified by:
      `isApproxEqual` in interface `Matrix4c`
    Parameters:
      `m` - the matrix to compare.
    Returns:
      `true` if this matrix is equivalent to other matrix.

  - ### hashCode

    public int hashCode()
    Overrides:
      `hashCode` in class `Object`

  - ### equals

    public boolean equals(Object o)
    Returns whether this matrix is exactly equal to another matrix.
    Overrides:
      `equals` in class `Object`
    Parameters:
      `o` - the reference object with which to compare.
    Returns:
      `true` if this object is the same as the o values.

  - ### toString

    public String toString()
    Overrides:
      `toString` in class `Object`

  - ### clone

    @Nonnull public Matrix4 clone()
    Specified by:
      `clone` in interface `Matrix4c`
    Overrides:
      `clone` in class `Object`
    Returns:
      a copy of this matrix