org.joml.Matrix4fc Maven / Gradle / Ivy
/*
* The MIT License
*
* Copyright (c) 2016-2020 JOML
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.joml;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.util.*;
/**
* Interface to a read-only view of a 4x4 matrix of single-precision floats.
*
* @author Kai Burjack
*/
public interface Matrix4fc {
/**
* Argument to the first parameter of {@link #frustumPlane(int, Vector4f)} and
* {@link #frustumPlane(int, Planef)}
* identifying the plane with equation x=-1
when using the identity matrix.
*/
int PLANE_NX = 0;
/**
* Argument to the first parameter of {@link #frustumPlane(int, Vector4f)} and
* {@link #frustumPlane(int, Planef)}
* identifying the plane with equation x=1
when using the identity matrix.
*/
int PLANE_PX = 1;
/**
* Argument to the first parameter of {@link #frustumPlane(int, Vector4f)} and
* {@link #frustumPlane(int, Planef)}
* identifying the plane with equation y=-1
when using the identity matrix.
*/
int PLANE_NY = 2;
/**
* Argument to the first parameter of {@link #frustumPlane(int, Vector4f)} and
* {@link #frustumPlane(int, Planef)}
* identifying the plane with equation y=1
when using the identity matrix.
*/
int PLANE_PY = 3;
/**
* Argument to the first parameter of {@link #frustumPlane(int, Vector4f)} and
* {@link #frustumPlane(int, Planef)}
* identifying the plane with equation z=-1
when using the identity matrix.
*/
int PLANE_NZ = 4;
/**
* Argument to the first parameter of {@link #frustumPlane(int, Vector4f)} and
* {@link #frustumPlane(int, Planef)}
* identifying the plane with equation z=1
when using the identity matrix.
*/
int PLANE_PZ = 5;
/**
* Argument to the first parameter of {@link #frustumCorner(int, Vector3f)}
* identifying the corner (-1, -1, -1)
when using the identity matrix.
*/
int CORNER_NXNYNZ = 0;
/**
* Argument to the first parameter of {@link #frustumCorner(int, Vector3f)}
* identifying the corner (1, -1, -1)
when using the identity matrix.
*/
int CORNER_PXNYNZ = 1;
/**
* Argument to the first parameter of {@link #frustumCorner(int, Vector3f)}
* identifying the corner (1, 1, -1)
when using the identity matrix.
*/
int CORNER_PXPYNZ = 2;
/**
* Argument to the first parameter of {@link #frustumCorner(int, Vector3f)}
* identifying the corner (-1, 1, -1)
when using the identity matrix.
*/
int CORNER_NXPYNZ = 3;
/**
* Argument to the first parameter of {@link #frustumCorner(int, Vector3f)}
* identifying the corner (1, -1, 1)
when using the identity matrix.
*/
int CORNER_PXNYPZ = 4;
/**
* Argument to the first parameter of {@link #frustumCorner(int, Vector3f)}
* identifying the corner (-1, -1, 1)
when using the identity matrix.
*/
int CORNER_NXNYPZ = 5;
/**
* Argument to the first parameter of {@link #frustumCorner(int, Vector3f)}
* identifying the corner (-1, 1, 1)
when using the identity matrix.
*/
int CORNER_NXPYPZ = 6;
/**
* Argument to the first parameter of {@link #frustumCorner(int, Vector3f)}
* identifying the corner (1, 1, 1)
when using the identity matrix.
*/
int CORNER_PXPYPZ = 7;
/**
* Bit returned by {@link #properties()} to indicate that the matrix represents a perspective transformation.
*/
byte PROPERTY_PERSPECTIVE = 1<<0;
/**
* Bit returned by {@link #properties()} to indicate that the matrix represents an affine transformation.
*/
byte PROPERTY_AFFINE = 1<<1;
/**
* Bit returned by {@link #properties()} to indicate that the matrix represents the identity transformation.
*/
byte PROPERTY_IDENTITY = 1<<2;
/**
* Bit returned by {@link #properties()} to indicate that the matrix represents a pure translation transformation.
*/
byte PROPERTY_TRANSLATION = 1<<3;
/**
* Bit returned by {@link #properties()} to indicate that the upper-left 3x3 submatrix represents an orthogonal
* matrix (i.e. orthonormal basis). For practical reasons, this property also always implies
* {@link #PROPERTY_AFFINE} in this implementation.
*/
byte PROPERTY_ORTHONORMAL = 1<<4;
/**
* Return the assumed properties of this matrix. This is a bit-combination of
* {@link #PROPERTY_IDENTITY}, {@link #PROPERTY_AFFINE},
* {@link #PROPERTY_TRANSLATION} and {@link #PROPERTY_PERSPECTIVE}.
*
* @return the properties of the matrix
*/
int properties();
/**
* Return the value of the matrix element at column 0 and row 0.
*
* @return the value of the matrix element
*/
float m00();
/**
* Return the value of the matrix element at column 0 and row 1.
*
* @return the value of the matrix element
*/
float m01();
/**
* Return the value of the matrix element at column 0 and row 2.
*
* @return the value of the matrix element
*/
float m02();
/**
* Return the value of the matrix element at column 0 and row 3.
*
* @return the value of the matrix element
*/
float m03();
/**
* Return the value of the matrix element at column 1 and row 0.
*
* @return the value of the matrix element
*/
float m10();
/**
* Return the value of the matrix element at column 1 and row 1.
*
* @return the value of the matrix element
*/
float m11();
/**
* Return the value of the matrix element at column 1 and row 2.
*
* @return the value of the matrix element
*/
float m12();
/**
* Return the value of the matrix element at column 1 and row 3.
*
* @return the value of the matrix element
*/
float m13();
/**
* Return the value of the matrix element at column 2 and row 0.
*
* @return the value of the matrix element
*/
float m20();
/**
* Return the value of the matrix element at column 2 and row 1.
*
* @return the value of the matrix element
*/
float m21();
/**
* Return the value of the matrix element at column 2 and row 2.
*
* @return the value of the matrix element
*/
float m22();
/**
* Return the value of the matrix element at column 2 and row 3.
*
* @return the value of the matrix element
*/
float m23();
/**
* Return the value of the matrix element at column 3 and row 0.
*
* @return the value of the matrix element
*/
float m30();
/**
* Return the value of the matrix element at column 3 and row 1.
*
* @return the value of the matrix element
*/
float m31();
/**
* Return the value of the matrix element at column 3 and row 2.
*
* @return the value of the matrix element
*/
float m32();
/**
* Return the value of the matrix element at column 3 and row 3.
*
* @return the value of the matrix element
*/
float m33();
/**
* Multiply this matrix by the supplied right
matrix and store the result in dest
.
*
* If M
is this
matrix and R
the right
matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* transformation of the right matrix will be applied first!
*
* @param right
* the right operand of the matrix multiplication
* @param dest
* the destination matrix, which will hold the result
* @return dest
*/
Matrix4f mul(Matrix4fc right, Matrix4f dest);
/**
* Pre-multiply this matrix by the supplied left
matrix and store the result in dest
.
*
* If M
is this
matrix and L
the left
matrix,
* then the new matrix will be L * M
. So when transforming a
* vector v
with the new matrix by using L * M * v
, the
* transformation of this
matrix will be applied first!
*
* @param left
* the left operand of the matrix multiplication
* @param dest
* the destination matrix, which will hold the result
* @return dest
*/
Matrix4f mulLocal(Matrix4fc left, Matrix4f dest);
/**
* Pre-multiply this matrix by the supplied left
matrix, both of which are assumed to be {@link #isAffine() affine}, and store the result in dest
.
*
* This method assumes that this
matrix and the given left
matrix both represent an {@link #isAffine() affine} transformation
* (i.e. their last rows are equal to (0, 0, 0, 1)
)
* and can be used to speed up matrix multiplication if the matrices only represent affine transformations, such as translation, rotation, scaling and shearing (in any combination).
*
* This method will not modify either the last row of this
or the last row of left
.
*
* If M
is this
matrix and L
the left
matrix,
* then the new matrix will be L * M
. So when transforming a
* vector v
with the new matrix by using L * M * v
, the
* transformation of this
matrix will be applied first!
*
* @param left
* the left operand of the matrix multiplication (the last row is assumed to be (0, 0, 0, 1)
)
* @param dest
* the destination matrix, which will hold the result
* @return dest
*/
Matrix4f mulLocalAffine(Matrix4fc left, Matrix4f dest);
/**
* Multiply this matrix by the supplied right
matrix and store the result in dest
.
*
* If M
is this
matrix and R
the right
matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* transformation of the right matrix will be applied first!
*
* @param right
* the right operand of the matrix multiplication
* @param dest
* the destination matrix, which will hold the result
* @return dest
*/
Matrix4f mul(Matrix3x2fc right, Matrix4f dest);
/**
* Multiply this matrix by the supplied right
matrix and store the result in dest
.
*
* The last row of the right
matrix is assumed to be (0, 0, 0, 1)
.
*
* If M
is this
matrix and R
the right
matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* transformation of the right matrix will be applied first!
*
* @param right
* the right operand of the matrix multiplication
* @param dest
* the destination matrix, which will hold the result
* @return dest
*/
Matrix4f mul(Matrix4x3fc right, Matrix4f dest);
/**
* Multiply this
symmetric perspective projection matrix by the supplied {@link #isAffine() affine} view
matrix and store the result in dest
.
*
* If P
is this
matrix and V
the view
matrix,
* then the new matrix will be P * V
. So when transforming a
* vector v
with the new matrix by using P * V * v
, the
* transformation of the view
matrix will be applied first!
*
* @param view
* the {@link #isAffine() affine} matrix to multiply this
symmetric perspective projection matrix by
* @param dest
* the destination matrix, which will hold the result
* @return dest
*/
Matrix4f mulPerspectiveAffine(Matrix4fc view, Matrix4f dest);
/**
* Multiply this
symmetric perspective projection matrix by the supplied view
matrix and store the result in dest
.
*
* If P
is this
matrix and V
the view
matrix,
* then the new matrix will be P * V
. So when transforming a
* vector v
with the new matrix by using P * V * v
, the
* transformation of the view
matrix will be applied first!
*
* @param view
* the matrix to multiply this
symmetric perspective projection matrix by
* @param dest
* the destination matrix, which will hold the result
* @return dest
*/
Matrix4f mulPerspectiveAffine(Matrix4x3fc view, Matrix4f dest);
/**
* Multiply this matrix by the supplied right
matrix, which is assumed to be {@link #isAffine() affine}, and store the result in dest
.
*
* This method assumes that the given right
matrix represents an {@link #isAffine() affine} transformation (i.e. its last row is equal to (0, 0, 0, 1)
)
* and can be used to speed up matrix multiplication if the matrix only represents affine transformations, such as translation, rotation, scaling and shearing (in any combination).
*
* If M
is this
matrix and R
the right
matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* transformation of the right matrix will be applied first!
*
* @param right
* the right operand of the matrix multiplication (the last row is assumed to be (0, 0, 0, 1)
)
* @param dest
* the destination matrix, which will hold the result
* @return dest
*/
Matrix4f mulAffineR(Matrix4fc right, Matrix4f dest);
/**
* Multiply this matrix by the supplied right
matrix, both of which are assumed to be {@link #isAffine() affine}, and store the result in dest
.
*
* This method assumes that this
matrix and the given right
matrix both represent an {@link #isAffine() affine} transformation
* (i.e. their last rows are equal to (0, 0, 0, 1)
)
* and can be used to speed up matrix multiplication if the matrices only represent affine transformations, such as translation, rotation, scaling and shearing (in any combination).
*
* This method will not modify either the last row of this
or the last row of right
.
*
* If M
is this
matrix and R
the right
matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* transformation of the right matrix will be applied first!
*
* @param right
* the right operand of the matrix multiplication (the last row is assumed to be (0, 0, 0, 1)
)
* @param dest
* the destination matrix, which will hold the result
* @return dest
*/
Matrix4f mulAffine(Matrix4fc right, Matrix4f dest);
/**
* Multiply this matrix, which is assumed to only contain a translation, by the supplied right
matrix, which is assumed to be {@link #isAffine() affine}, and store the result in dest
.
*
* This method assumes that this
matrix only contains a translation, and that the given right
matrix represents an {@link #isAffine() affine} transformation
* (i.e. its last row is equal to (0, 0, 0, 1)
).
*
* This method will not modify either the last row of this
or the last row of right
.
*
* If M
is this
matrix and R
the right
matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* transformation of the right matrix will be applied first!
*
* @param right
* the right operand of the matrix multiplication (the last row is assumed to be (0, 0, 0, 1)
)
* @param dest
* the destination matrix, which will hold the result
* @return dest
*/
Matrix4f mulTranslationAffine(Matrix4fc right, Matrix4f dest);
/**
* Multiply this
orthographic projection matrix by the supplied {@link #isAffine() affine} view
matrix
* and store the result in dest
.
*
* If M
is this
matrix and V
the view
matrix,
* then the new matrix will be M * V
. So when transforming a
* vector v
with the new matrix by using M * V * v
, the
* transformation of the view
matrix will be applied first!
*
* @param view
* the affine matrix which to multiply this
with
* @param dest
* the destination matrix, which will hold the result
* @return dest
*/
Matrix4f mulOrthoAffine(Matrix4fc view, Matrix4f dest);
/**
* Component-wise add the upper 4x3 submatrices of this
and other
* by first multiplying each component of other
's 4x3 submatrix by otherFactor
,
* adding that to this
and storing the final result in dest
.
*
* The other components of dest
will be set to the ones of this
.
*
* The matrices this
and other
will not be changed.
*
* @param other
* the other matrix
* @param otherFactor
* the factor to multiply each of the other matrix's 4x3 components
* @param dest
* will hold the result
* @return dest
*/
Matrix4f fma4x3(Matrix4fc other, float otherFactor, Matrix4f dest);
/**
* Component-wise add this
and other
and store the result in dest
.
*
* @param other
* the other addend
* @param dest
* will hold the result
* @return dest
*/
Matrix4f add(Matrix4fc other, Matrix4f dest);
/**
* Component-wise subtract subtrahend
from this
and store the result in dest
.
*
* @param subtrahend
* the subtrahend
* @param dest
* will hold the result
* @return dest
*/
Matrix4f sub(Matrix4fc subtrahend, Matrix4f dest);
/**
* Component-wise multiply this
by other
and store the result in dest
.
*
* @param other
* the other matrix
* @param dest
* will hold the result
* @return dest
*/
Matrix4f mulComponentWise(Matrix4fc other, Matrix4f dest);
/**
* Component-wise add the upper 4x3 submatrices of this
and other
* and store the result in dest
.
*
* The other components of dest
will be set to the ones of this
.
*
* @param other
* the other addend
* @param dest
* will hold the result
* @return dest
*/
Matrix4f add4x3(Matrix4fc other, Matrix4f dest);
/**
* Component-wise subtract the upper 4x3 submatrices of subtrahend
from this
* and store the result in dest
.
*
* The other components of dest
will be set to the ones of this
.
*
* @param subtrahend
* the subtrahend
* @param dest
* will hold the result
* @return dest
*/
Matrix4f sub4x3(Matrix4fc subtrahend, Matrix4f dest);
/**
* Component-wise multiply the upper 4x3 submatrices of this
by other
* and store the result in dest
.
*
* The other components of dest
will be set to the ones of this
.
*
* @param other
* the other matrix
* @param dest
* will hold the result
* @return dest
*/
Matrix4f mul4x3ComponentWise(Matrix4fc other, Matrix4f dest);
/**
* Return the determinant of this matrix.
*
* If this
matrix represents an {@link #isAffine() affine} transformation, such as translation, rotation, scaling and shearing,
* and thus its last row is equal to (0, 0, 0, 1)
, then {@link #determinantAffine()} can be used instead of this method.
*
* @see #determinantAffine()
*
* @return the determinant
*/
float determinant();
/**
* Return the determinant of the upper left 3x3 submatrix of this matrix.
*
* @return the determinant
*/
float determinant3x3();
/**
* Return the determinant of this matrix by assuming that it represents an {@link #isAffine() affine} transformation and thus
* its last row is equal to (0, 0, 0, 1)
.
*
* @return the determinant
*/
float determinantAffine();
/**
* Invert this matrix and write the result into dest
.
*
* If this
matrix represents an {@link #isAffine() affine} transformation, such as translation, rotation, scaling and shearing,
* and thus its last row is equal to (0, 0, 0, 1)
, then {@link #invertAffine(Matrix4f)} can be used instead of this method.
*
* @see #invertAffine(Matrix4f)
*
* @param dest
* will hold the result
* @return dest
*/
Matrix4f invert(Matrix4f dest);
/**
* If this
is a perspective projection matrix obtained via one of the {@link #perspective(float, float, float, float, Matrix4f) perspective()} methods,
* that is, if this
is a symmetrical perspective frustum transformation,
* then this method builds the inverse of this
and stores it into the given dest
.
*
* This method can be used to quickly obtain the inverse of a perspective projection matrix when being obtained via {@link #perspective(float, float, float, float, Matrix4f) perspective()}.
*
* @see #perspective(float, float, float, float, Matrix4f)
*
* @param dest
* will hold the inverse of this
* @return dest
*/
Matrix4f invertPerspective(Matrix4f dest);
/**
* If this
is an arbitrary perspective projection matrix obtained via one of the {@link #frustum(float, float, float, float, float, float, Matrix4f) frustum()} methods,
* then this method builds the inverse of this
and stores it into the given dest
.
*
* This method can be used to quickly obtain the inverse of a perspective projection matrix.
*
* If this matrix represents a symmetric perspective frustum transformation, as obtained via {@link #perspective(float, float, float, float, Matrix4f) perspective()}, then
* {@link #invertPerspective(Matrix4f)} should be used instead.
*
* @see #frustum(float, float, float, float, float, float, Matrix4f)
* @see #invertPerspective(Matrix4f)
*
* @param dest
* will hold the inverse of this
* @return dest
*/
Matrix4f invertFrustum(Matrix4f dest);
/**
* Invert this
orthographic projection matrix and store the result into the given dest
.
*
* This method can be used to quickly obtain the inverse of an orthographic projection matrix.
*
* @param dest
* will hold the inverse of this
* @return dest
*/
Matrix4f invertOrtho(Matrix4f dest);
/**
* If this
is a perspective projection matrix obtained via one of the {@link #perspective(float, float, float, float, Matrix4f) perspective()} methods,
* that is, if this
is a symmetrical perspective frustum transformation
* and the given view
matrix is {@link #isAffine() affine} and has unit scaling (for example by being obtained via {@link #lookAt(float, float, float, float, float, float, float, float, float, Matrix4f) lookAt()}),
* then this method builds the inverse of this * view
and stores it into the given dest
.
*
* This method can be used to quickly obtain the inverse of the combination of the view and projection matrices, when both were obtained
* via the common methods {@link #perspective(float, float, float, float, Matrix4f) perspective()} and {@link #lookAt(float, float, float, float, float, float, float, float, float, Matrix4f) lookAt()} or
* other methods, that build affine matrices, such as {@link #translate(float, float, float, Matrix4f) translate} and {@link #rotate(float, float, float, float, Matrix4f)}, except for {@link #scale(float, float, float, Matrix4f) scale()}.
*
* For the special cases of the matrices this
and view
mentioned above, this method is equivalent to the following code:
*
* dest.set(this).mul(view).invert();
*
*
* @param view
* the view transformation (must be {@link #isAffine() affine} and have unit scaling)
* @param dest
* will hold the inverse of this * view
* @return dest
*/
Matrix4f invertPerspectiveView(Matrix4fc view, Matrix4f dest);
/**
* If this
is a perspective projection matrix obtained via one of the {@link #perspective(float, float, float, float, Matrix4f) perspective()} methods,
* that is, if this
is a symmetrical perspective frustum transformation
* and the given view
matrix has unit scaling,
* then this method builds the inverse of this * view
and stores it into the given dest
.
*
* This method can be used to quickly obtain the inverse of the combination of the view and projection matrices, when both were obtained
* via the common methods {@link #perspective(float, float, float, float, Matrix4f) perspective()} and {@link #lookAt(float, float, float, float, float, float, float, float, float, Matrix4f) lookAt()} or
* other methods, that build affine matrices, such as {@link #translate(float, float, float, Matrix4f) translate} and {@link #rotate(float, float, float, float, Matrix4f)}, except for {@link #scale(float, float, float, Matrix4f) scale()}.
*
* For the special cases of the matrices this
and view
mentioned above, this method is equivalent to the following code:
*
* dest.set(this).mul(view).invert();
*
*
* @param view
* the view transformation (must have unit scaling)
* @param dest
* will hold the inverse of this * view
* @return dest
*/
Matrix4f invertPerspectiveView(Matrix4x3fc view, Matrix4f dest);
/**
* Invert this matrix by assuming that it is an {@link #isAffine() affine} transformation (i.e. its last row is equal to (0, 0, 0, 1)
)
* and write the result into dest
.
*
* @param dest
* will hold the result
* @return dest
*/
Matrix4f invertAffine(Matrix4f dest);
/**
* Transpose this matrix and store the result in dest
.
*
* @param dest
* will hold the result
* @return dest
*/
Matrix4f transpose(Matrix4f dest);
/**
* Transpose only the upper left 3x3 submatrix of this matrix and store the result in dest
.
*
* All other matrix elements are left unchanged.
*
* @param dest
* will hold the result
* @return dest
*/
Matrix4f transpose3x3(Matrix4f dest);
/**
* Transpose only the upper left 3x3 submatrix of this matrix and store the result in dest
.
*
* @param dest
* will hold the result
* @return dest
*/
Matrix3f transpose3x3(Matrix3f dest);
/**
* Get only the translation components (m30, m31, m32)
of this matrix and store them in the given vector xyz
.
*
* @param dest
* will hold the translation components of this matrix
* @return dest
*/
Vector3f getTranslation(Vector3f dest);
/**
* Get the scaling factors of this
matrix for the three base axes.
*
* @param dest
* will hold the scaling factors for x
, y
and z
* @return dest
*/
Vector3f getScale(Vector3f dest);
/**
* Get the current values of this
matrix and store them into
* dest
.
*
* @param dest
* the destination matrix
* @return the passed in destination
*/
Matrix4f get(Matrix4f dest);
/**
* Get the current values of the upper 4x3 submatrix of this
matrix and store them into
* dest
.
*
* @see Matrix4x3f#set(Matrix4fc)
*
* @param dest
* the destination matrix
* @return the passed in destination
*/
Matrix4x3f get4x3(Matrix4x3f dest);
/**
* Get the current values of this
matrix and store them into
* dest
.
*
* @param dest
* the destination matrix
* @return the passed in destination
*/
Matrix4d get(Matrix4d dest);
/**
* Get the current values of the upper left 3x3 submatrix of this
matrix and store them into
* dest
.
*
* @see Matrix3f#set(Matrix4fc)
*
* @param dest
* the destination matrix
* @return the passed in destination
*/
Matrix3f get3x3(Matrix3f dest);
/**
* Get the current values of the upper left 3x3 submatrix of this
matrix and store them into
* dest
.
*
* @see Matrix3d#set(Matrix4fc)
*
* @param dest
* the destination matrix
* @return the passed in destination
*/
Matrix3d get3x3(Matrix3d dest);
/**
* Get the rotational component of this
matrix and store the represented rotation
* into the given {@link AxisAngle4f}.
*
* @see AxisAngle4f#set(Matrix4fc)
*
* @param dest
* the destination {@link AxisAngle4f}
* @return the passed in destination
*/
AxisAngle4f getRotation(AxisAngle4f dest);
/**
* Get the rotational component of this
matrix and store the represented rotation
* into the given {@link AxisAngle4d}.
*
* @see AxisAngle4f#set(Matrix4fc)
*
* @param dest
* the destination {@link AxisAngle4d}
* @return the passed in destination
*/
AxisAngle4d getRotation(AxisAngle4d dest);
/**
* Get the current values of this
matrix and store the represented rotation
* into the given {@link Quaternionf}.
*
* This method assumes that the first three column vectors of the upper left 3x3 submatrix are not normalized and
* thus allows to ignore any additional scaling factor that is applied to the matrix.
*
* @see Quaternionf#setFromUnnormalized(Matrix4fc)
*
* @param dest
* the destination {@link Quaternionf}
* @return the passed in destination
*/
Quaternionf getUnnormalizedRotation(Quaternionf dest);
/**
* Get the current values of this
matrix and store the represented rotation
* into the given {@link Quaternionf}.
*
* This method assumes that the first three column vectors of the upper left 3x3 submatrix are normalized.
*
* @see Quaternionf#setFromNormalized(Matrix4fc)
*
* @param dest
* the destination {@link Quaternionf}
* @return the passed in destination
*/
Quaternionf getNormalizedRotation(Quaternionf dest);
/**
* Get the current values of this
matrix and store the represented rotation
* into the given {@link Quaterniond}.
*
* This method assumes that the first three column vectors of the upper left 3x3 submatrix are not normalized and
* thus allows to ignore any additional scaling factor that is applied to the matrix.
*
* @see Quaterniond#setFromUnnormalized(Matrix4fc)
*
* @param dest
* the destination {@link Quaterniond}
* @return the passed in destination
*/
Quaterniond getUnnormalizedRotation(Quaterniond dest);
/**
* Get the current values of this
matrix and store the represented rotation
* into the given {@link Quaterniond}.
*
* This method assumes that the first three column vectors of the upper left 3x3 submatrix are normalized.
*
* @see Quaterniond#setFromNormalized(Matrix4fc)
*
* @param dest
* the destination {@link Quaterniond}
* @return the passed in destination
*/
Quaterniond getNormalizedRotation(Quaterniond dest);
/**
* Store this matrix in column-major order into the supplied {@link FloatBuffer} at the current
* buffer {@link FloatBuffer#position() position}.
*
* This method will not increment the position of the given FloatBuffer.
*
* In order to specify the offset into the FloatBuffer at which
* the matrix is stored, use {@link #get(int, FloatBuffer)}, taking
* the absolute position as parameter.
*
* @see #get(int, FloatBuffer)
*
* @param buffer
* will receive the values of this matrix in column-major order at its current position
* @return the passed in buffer
*/
FloatBuffer get(FloatBuffer buffer);
/**
* Store this matrix in column-major order into the supplied {@link FloatBuffer} starting at the specified
* absolute buffer position/index.
*
* This method will not increment the position of the given FloatBuffer.
*
* @param index
* the absolute position into the FloatBuffer
* @param buffer
* will receive the values of this matrix in column-major order
* @return the passed in buffer
*/
FloatBuffer get(int index, FloatBuffer buffer);
/**
* Store this matrix in column-major order into the supplied {@link ByteBuffer} at the current
* buffer {@link ByteBuffer#position() position}.
*
* This method will not increment the position of the given ByteBuffer.
*
* In order to specify the offset into the ByteBuffer at which
* the matrix is stored, use {@link #get(int, ByteBuffer)}, taking
* the absolute position as parameter.
*
* @see #get(int, ByteBuffer)
*
* @param buffer
* will receive the values of this matrix in column-major order at its current position
* @return the passed in buffer
*/
ByteBuffer get(ByteBuffer buffer);
/**
* Store this matrix in column-major order into the supplied {@link ByteBuffer} starting at the specified
* absolute buffer position/index.
*
* This method will not increment the position of the given ByteBuffer.
*
* @param index
* the absolute position into the ByteBuffer
* @param buffer
* will receive the values of this matrix in column-major order
* @return the passed in buffer
*/
ByteBuffer get(int index, ByteBuffer buffer);
/**
* Store the upper 4x3 submatrix in column-major order into the supplied {@link FloatBuffer} at the current
* buffer {@link FloatBuffer#position() position}.
*
* This method will not increment the position of the given FloatBuffer.
*
* In order to specify the offset into the FloatBuffer at which
* the matrix is stored, use {@link #get(int, FloatBuffer)}, taking
* the absolute position as parameter.
*
* @see #get(int, FloatBuffer)
*
* @param buffer
* will receive the values of the upper 4x3 submatrix in column-major order at its current position
* @return the passed in buffer
*/
FloatBuffer get4x3(FloatBuffer buffer);
/**
* Store the upper 4x3 submatrix in column-major order into the supplied {@link FloatBuffer} starting at the specified
* absolute buffer position/index.
*
* This method will not increment the position of the given FloatBuffer.
*
* @param index
* the absolute position into the FloatBuffer
* @param buffer
* will receive the values of the upper 4x3 submatrix in column-major order
* @return the passed in buffer
*/
FloatBuffer get4x3(int index, FloatBuffer buffer);
/**
* Store the upper 4x3 submatrix in column-major order into the supplied {@link ByteBuffer} at the current
* buffer {@link ByteBuffer#position() position}.
*
* This method will not increment the position of the given ByteBuffer.
*
* In order to specify the offset into the ByteBuffer at which
* the matrix is stored, use {@link #get(int, ByteBuffer)}, taking
* the absolute position as parameter.
*
* @see #get(int, ByteBuffer)
*
* @param buffer
* will receive the values of the upper 4x3 submatrix in column-major order at its current position
* @return the passed in buffer
*/
ByteBuffer get4x3(ByteBuffer buffer);
/**
* Store the upper 4x3 submatrix in column-major order into the supplied {@link ByteBuffer} starting at the specified
* absolute buffer position/index.
*
* This method will not increment the position of the given ByteBuffer.
*
* @param index
* the absolute position into the ByteBuffer
* @param buffer
* will receive the values of the upper 4x3 submatrix in column-major order
* @return the passed in buffer
*/
ByteBuffer get4x3(int index, ByteBuffer buffer);
/**
* Store the left 3x4 submatrix in column-major order into the supplied {@link FloatBuffer} at the current
* buffer {@link FloatBuffer#position() position}.
*
* This method will not increment the position of the given FloatBuffer.
*
* In order to specify the offset into the FloatBuffer at which
* the matrix is stored, use {@link #get3x4(int, FloatBuffer)}, taking
* the absolute position as parameter.
*
* @see #get3x4(int, FloatBuffer)
*
* @param buffer
* will receive the values of the left 3x4 submatrix in column-major order at its current position
* @return the passed in buffer
*/
FloatBuffer get3x4(FloatBuffer buffer);
/**
* Store the left 3x4 submatrix in column-major order into the supplied {@link FloatBuffer} starting at the specified
* absolute buffer position/index.
*
* This method will not increment the position of the given FloatBuffer.
*
* @param index
* the absolute position into the FloatBuffer
* @param buffer
* will receive the values of the left 3x4 submatrix in column-major order
* @return the passed in buffer
*/
FloatBuffer get3x4(int index, FloatBuffer buffer);
/**
* Store the left 3x4 submatrix in column-major order into the supplied {@link ByteBuffer} at the current
* buffer {@link ByteBuffer#position() position}.
*
* This method will not increment the position of the given ByteBuffer.
*
* In order to specify the offset into the ByteBuffer at which
* the matrix is stored, use {@link #get3x4(int, ByteBuffer)}, taking
* the absolute position as parameter.
*
* @see #get3x4(int, ByteBuffer)
*
* @param buffer
* will receive the values of the left 3x4 submatrix in column-major order at its current position
* @return the passed in buffer
*/
ByteBuffer get3x4(ByteBuffer buffer);
/**
* Store the left 3x4 submatrix in column-major order into the supplied {@link ByteBuffer} starting at the specified
* absolute buffer position/index.
*
* This method will not increment the position of the given ByteBuffer.
*
* @param index
* the absolute position into the ByteBuffer
* @param buffer
* will receive the values of the left 3x4 submatrix in column-major order
* @return the passed in buffer
*/
ByteBuffer get3x4(int index, ByteBuffer buffer);
/**
* Store the transpose of this matrix in column-major order into the supplied {@link FloatBuffer} at the current
* buffer {@link FloatBuffer#position() position}.
*
* This method will not increment the position of the given FloatBuffer.
*
* In order to specify the offset into the FloatBuffer at which
* the matrix is stored, use {@link #getTransposed(int, FloatBuffer)}, taking
* the absolute position as parameter.
*
* @see #getTransposed(int, FloatBuffer)
*
* @param buffer
* will receive the values of this matrix in column-major order at its current position
* @return the passed in buffer
*/
FloatBuffer getTransposed(FloatBuffer buffer);
/**
* Store the transpose of this matrix in column-major order into the supplied {@link FloatBuffer} starting at the specified
* absolute buffer position/index.
*
* This method will not increment the position of the given FloatBuffer.
*
* @param index
* the absolute position into the FloatBuffer
* @param buffer
* will receive the values of this matrix in column-major order
* @return the passed in buffer
*/
FloatBuffer getTransposed(int index, FloatBuffer buffer);
/**
* Store the transpose of this matrix in column-major order into the supplied {@link ByteBuffer} at the current
* buffer {@link ByteBuffer#position() position}.
*
* This method will not increment the position of the given ByteBuffer.
*
* In order to specify the offset into the ByteBuffer at which
* the matrix is stored, use {@link #getTransposed(int, ByteBuffer)}, taking
* the absolute position as parameter.
*
* @see #getTransposed(int, ByteBuffer)
*
* @param buffer
* will receive the values of this matrix in column-major order at its current position
* @return the passed in buffer
*/
ByteBuffer getTransposed(ByteBuffer buffer);
/**
* Store the transpose of this matrix in column-major order into the supplied {@link ByteBuffer} starting at the specified
* absolute buffer position/index.
*
* This method will not increment the position of the given ByteBuffer.
*
* @param index
* the absolute position into the ByteBuffer
* @param buffer
* will receive the values of this matrix in column-major order
* @return the passed in buffer
*/
ByteBuffer getTransposed(int index, ByteBuffer buffer);
/**
* Store the upper 4x3 submatrix of this
matrix in row-major order into the supplied {@link FloatBuffer} at the current
* buffer {@link FloatBuffer#position() position}.
*
* This method will not increment the position of the given FloatBuffer.
*
* In order to specify the offset into the FloatBuffer at which
* the matrix is stored, use {@link #get4x3Transposed(int, FloatBuffer)}, taking
* the absolute position as parameter.
*
* @see #get4x3Transposed(int, FloatBuffer)
*
* @param buffer
* will receive the values of the upper 4x3 submatrix in row-major order at its current position
* @return the passed in buffer
*/
FloatBuffer get4x3Transposed(FloatBuffer buffer);
/**
* Store the upper 4x3 submatrix of this
matrix in row-major order into the supplied {@link FloatBuffer} starting at the specified
* absolute buffer position/index.
*
* This method will not increment the position of the given FloatBuffer.
*
* @param index
* the absolute position into the FloatBuffer
* @param buffer
* will receive the values of the upper 4x3 submatrix in row-major order
* @return the passed in buffer
*/
FloatBuffer get4x3Transposed(int index, FloatBuffer buffer);
/**
* Store the upper 4x3 submatrix of this
matrix in row-major order into the supplied {@link ByteBuffer} at the current
* buffer {@link ByteBuffer#position() position}.
*
* This method will not increment the position of the given ByteBuffer.
*
* In order to specify the offset into the ByteBuffer at which
* the matrix is stored, use {@link #get4x3Transposed(int, ByteBuffer)}, taking
* the absolute position as parameter.
*
* @see #get4x3Transposed(int, ByteBuffer)
*
* @param buffer
* will receive the values of the upper 4x3 submatrix in row-major order at its current position
* @return the passed in buffer
*/
ByteBuffer get4x3Transposed(ByteBuffer buffer);
/**
* Store the upper 4x3 submatrix of this
matrix in row-major order into the supplied {@link ByteBuffer} starting at the specified
* absolute buffer position/index.
*
* This method will not increment the position of the given ByteBuffer.
*
* @param index
* the absolute position into the ByteBuffer
* @param buffer
* will receive the values of the upper 4x3 submatrix in row-major order
* @return the passed in buffer
*/
ByteBuffer get4x3Transposed(int index, ByteBuffer buffer);
/**
* Store this matrix in column-major order at the given off-heap address.
*
* This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
*
* This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.
*
* @param address
* the off-heap address where to store this matrix
* @return this
*/
Matrix4fc getToAddress(long address);
/**
* Store this matrix into the supplied float array in column-major order at the given offset.
*
* @param arr
* the array to write the matrix values into
* @param offset
* the offset into the array
* @return the passed in array
*/
float[] get(float[] arr, int offset);
/**
* Store this matrix into the supplied float array in column-major order.
*
* In order to specify an explicit offset into the array, use the method {@link #get(float[], int)}.
*
* @see #get(float[], int)
*
* @param arr
* the array to write the matrix values into
* @return the passed in array
*/
float[] get(float[] arr);
/**
* Transform/multiply the given vector by this matrix and store the result in that vector.
*
* @see Vector4f#mul(Matrix4fc)
*
* @param v
* the vector to transform and to hold the final result
* @return v
*/
Vector4f transform(Vector4f v);
/**
* Transform/multiply the given vector by this matrix and store the result in dest
.
*
* @see Vector4f#mul(Matrix4fc, Vector4f)
*
* @param v
* the vector to transform
* @param dest
* will contain the result
* @return dest
*/
Vector4f transform(Vector4fc v, Vector4f dest);
/**
* Transform/multiply the vector (x, y, z, w)
by this matrix and store the result in dest
.
*
* @param x
* the x coordinate of the vector to transform
* @param y
* the y coordinate of the vector to transform
* @param z
* the z coordinate of the vector to transform
* @param w
* the w coordinate of the vector to transform
* @param dest
* will contain the result
* @return dest
*/
Vector4f transform(float x, float y, float z, float w, Vector4f dest);
/**
* Transform/multiply the given vector by this matrix, perform perspective divide and store the result in that vector.
*
* @see Vector4f#mulProject(Matrix4fc)
*
* @param v
* the vector to transform and to hold the final result
* @return v
*/
Vector4f transformProject(Vector4f v);
/**
* Transform/multiply the given vector by this matrix, perform perspective divide and store the result in dest
.
*
* @see Vector4f#mulProject(Matrix4fc, Vector4f)
*
* @param v
* the vector to transform
* @param dest
* will contain the result
* @return dest
*/
Vector4f transformProject(Vector4fc v, Vector4f dest);
/**
* Transform/multiply the vector (x, y, z, w)
by this matrix, perform perspective divide and store the result in dest
.
*
* @param x
* the x coordinate of the vector to transform
* @param y
* the y coordinate of the vector to transform
* @param z
* the z coordinate of the vector to transform
* @param w
* the w coordinate of the vector to transform
* @param dest
* will contain the result
* @return dest
*/
Vector4f transformProject(float x, float y, float z, float w, Vector4f dest);
/**
* Transform/multiply the given vector by this matrix, perform perspective divide and store the result in that vector.
*
* This method uses w=1.0
as the fourth vector component.
*
* @see Vector3f#mulProject(Matrix4fc)
*
* @param v
* the vector to transform and to hold the final result
* @return v
*/
Vector3f transformProject(Vector3f v);
/**
* Transform/multiply the given vector by this matrix, perform perspective divide and store the result in dest
.
*
* This method uses w=1.0
as the fourth vector component.
*
* @see Vector3f#mulProject(Matrix4fc, Vector3f)
*
* @param v
* the vector to transform
* @param dest
* will contain the result
* @return dest
*/
Vector3f transformProject(Vector3fc v, Vector3f dest);
/**
* Transform/multiply the vector (x, y, z)
by this matrix, perform perspective divide and store the result in dest
.
*
* This method uses w=1.0
as the fourth vector component.
*
* @param x
* the x coordinate of the vector to transform
* @param y
* the y coordinate of the vector to transform
* @param z
* the z coordinate of the vector to transform
* @param dest
* will contain the result
* @return dest
*/
Vector3f transformProject(float x, float y, float z, Vector3f dest);
/**
* Transform/multiply the vector (x, y, z, w)
by this matrix, perform perspective divide and store
* (x, y, z)
of the result in dest
.
*
* @param x
* the x coordinate of the vector to transform
* @param y
* the y coordinate of the vector to transform
* @param z
* the z coordinate of the vector to transform
* @param w
* the w coordinate of the vector to transform
* @param dest
* will contain the (x, y, z)
components of the result
* @return dest
*/
Vector3f transformProject(float x, float y, float z, float w, Vector3f dest);
/**
* Transform/multiply the given 3D-vector, as if it was a 4D-vector with w=1, by
* this matrix and store the result in that vector.
*
* The given 3D-vector is treated as a 4D-vector with its w-component being 1.0, so it
* will represent a position/location in 3D-space rather than a direction. This method is therefore
* not suited for perspective projection transformations as it will not save the
* w
component of the transformed vector.
* For perspective projection use {@link #transform(Vector4f)} or {@link #transformProject(Vector3f)}
* when perspective divide should be applied, too.
*
* In order to store the result in another vector, use {@link #transformPosition(Vector3fc, Vector3f)}.
*
* @see #transformPosition(Vector3fc, Vector3f)
* @see #transform(Vector4f)
* @see #transformProject(Vector3f)
*
* @param v
* the vector to transform and to hold the final result
* @return v
*/
Vector3f transformPosition(Vector3f v);
/**
* Transform/multiply the given 3D-vector, as if it was a 4D-vector with w=1, by
* this matrix and store the result in dest
.
*
* The given 3D-vector is treated as a 4D-vector with its w-component being 1.0, so it
* will represent a position/location in 3D-space rather than a direction. This method is therefore
* not suited for perspective projection transformations as it will not save the
* w
component of the transformed vector.
* For perspective projection use {@link #transform(Vector4fc, Vector4f)} or
* {@link #transformProject(Vector3fc, Vector3f)} when perspective divide should be applied, too.
*
* In order to store the result in the same vector, use {@link #transformPosition(Vector3f)}.
*
* @see #transformPosition(Vector3f)
* @see #transform(Vector4fc, Vector4f)
* @see #transformProject(Vector3fc, Vector3f)
*
* @param v
* the vector to transform
* @param dest
* will hold the result
* @return dest
*/
Vector3f transformPosition(Vector3fc v, Vector3f dest);
/**
* Transform/multiply the 3D-vector (x, y, z)
, as if it was a 4D-vector with w=1, by
* this matrix and store the result in dest
.
*
* The given 3D-vector is treated as a 4D-vector with its w-component being 1.0, so it
* will represent a position/location in 3D-space rather than a direction. This method is therefore
* not suited for perspective projection transformations as it will not save the
* w
component of the transformed vector.
* For perspective projection use {@link #transform(float, float, float, float, Vector4f)} or
* {@link #transformProject(float, float, float, Vector3f)} when perspective divide should be applied, too.
*
* @see #transform(float, float, float, float, Vector4f)
* @see #transformProject(float, float, float, Vector3f)
*
* @param x
* the x coordinate of the position
* @param y
* the y coordinate of the position
* @param z
* the z coordinate of the position
* @param dest
* will hold the result
* @return dest
*/
Vector3f transformPosition(float x, float y, float z, Vector3f dest);
/**
* Transform/multiply the given 3D-vector, as if it was a 4D-vector with w=0, by
* this matrix and store the result in that vector.
*
* The given 3D-vector is treated as a 4D-vector with its w-component being 0.0
, so it
* will represent a direction in 3D-space rather than a position. This method will therefore
* not take the translation part of the matrix into account.
*
* In order to store the result in another vector, use {@link #transformDirection(Vector3fc, Vector3f)}.
*
* @see #transformDirection(Vector3fc, Vector3f)
*
* @param v
* the vector to transform and to hold the final result
* @return v
*/
Vector3f transformDirection(Vector3f v);
/**
* Transform/multiply the given 3D-vector, as if it was a 4D-vector with w=0, by
* this matrix and store the result in dest
.
*
* The given 3D-vector is treated as a 4D-vector with its w-component being 0.0
, so it
* will represent a direction in 3D-space rather than a position. This method will therefore
* not take the translation part of the matrix into account.
*
* In order to store the result in the same vector, use {@link #transformDirection(Vector3f)}.
*
* @see #transformDirection(Vector3f)
*
* @param v
* the vector to transform and to hold the final result
* @param dest
* will hold the result
* @return dest
*/
Vector3f transformDirection(Vector3fc v, Vector3f dest);
/**
* Transform/multiply the given 3D-vector (x, y, z)
, as if it was a 4D-vector with w=0, by
* this matrix and store the result in dest
.
*
* The given 3D-vector is treated as a 4D-vector with its w-component being 0.0
, so it
* will represent a direction in 3D-space rather than a position. This method will therefore
* not take the translation part of the matrix into account.
*
* @param x
* the x coordinate of the direction to transform
* @param y
* the y coordinate of the direction to transform
* @param z
* the z coordinate of the direction to transform
* @param dest
* will hold the result
* @return dest
*/
Vector3f transformDirection(float x, float y, float z, Vector3f dest);
/**
* Transform/multiply the given 4D-vector by assuming that this
matrix represents an {@link #isAffine() affine} transformation
* (i.e. its last row is equal to (0, 0, 0, 1)
).
*
* In order to store the result in another vector, use {@link #transformAffine(Vector4fc, Vector4f)}.
*
* @see #transformAffine(Vector4fc, Vector4f)
*
* @param v
* the vector to transform and to hold the final result
* @return v
*/
Vector4f transformAffine(Vector4f v);
/**
* Transform/multiply the given 4D-vector by assuming that this
matrix represents an {@link #isAffine() affine} transformation
* (i.e. its last row is equal to (0, 0, 0, 1)
) and store the result in dest
.
*
* In order to store the result in the same vector, use {@link #transformAffine(Vector4f)}.
*
* @see #transformAffine(Vector4f)
*
* @param v
* the vector to transform and to hold the final result
* @param dest
* will hold the result
* @return dest
*/
Vector4f transformAffine(Vector4fc v, Vector4f dest);
/**
* Transform/multiply the 4D-vector (x, y, z, w)
by assuming that this
matrix represents an {@link #isAffine() affine} transformation
* (i.e. its last row is equal to (0, 0, 0, 1)
) and store the result in dest
.
*
* @param x
* the x coordinate of the direction to transform
* @param y
* the y coordinate of the direction to transform
* @param z
* the z coordinate of the direction to transform
* @param w
* the w coordinate of the direction to transform
* @param dest
* will hold the result
* @return dest
*/
Vector4f transformAffine(float x, float y, float z, float w, Vector4f dest);
/**
* Apply scaling to this
matrix by scaling the base axes by the given xyz.x
,
* xyz.y
and xyz.z
factors, respectively and store the result in dest
.
*
* If M
is this
matrix and S
the scaling matrix,
* then the new matrix will be M * S
. So when transforming a
* vector v
with the new matrix by using M * S * v
* , the scaling will be applied first!
*
* @param xyz
* the factors of the x, y and z component, respectively
* @param dest
* will hold the result
* @return dest
*/
Matrix4f scale(Vector3fc xyz, Matrix4f dest);
/**
* Apply scaling to this matrix by uniformly scaling all base axes by the given xyz
factor
* and store the result in dest
.
*
* If M
is this
matrix and S
the scaling matrix,
* then the new matrix will be M * S
. So when transforming a
* vector v
with the new matrix by using M * S * v
, the
* scaling will be applied first!
*
* Individual scaling of all three axes can be applied using {@link #scale(float, float, float, Matrix4f)}.
*
* @see #scale(float, float, float, Matrix4f)
*
* @param xyz
* the factor for all components
* @param dest
* will hold the result
* @return dest
*/
Matrix4f scale(float xyz, Matrix4f dest);
/**
* Apply scaling to this matrix by by scaling the X axis by x
and the Y axis by y
* and store the result in dest
.
*
* If M
is this
matrix and S
the scaling matrix,
* then the new matrix will be M * S
. So when transforming a
* vector v
with the new matrix by using M * S * v
, the
* scaling will be applied first!
*
* @param x
* the factor of the x component
* @param y
* the factor of the y component
* @param dest
* will hold the result
* @return dest
*/
Matrix4f scaleXY(float x, float y, Matrix4f dest);
/**
* 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 M * S
. So when transforming a
* vector v
with the new matrix by using M * S * v
* , the scaling will be applied first!
*
* @param x
* the factor of the x component
* @param y
* the factor of the y component
* @param z
* the factor of the z component
* @param dest
* will hold the result
* @return dest
*/
Matrix4f scale(float x, float y, float z, Matrix4f dest);
/**
* Apply scaling to this
matrix by scaling the base axes by the given sx,
* sy and sz factors while using (ox, oy, oz)
as the scaling origin,
* and store the result in dest
.
*
* If M
is this
matrix and S
the scaling matrix,
* then the new matrix will be M * S
. So when transforming a
* vector v
with the new matrix by using M * S * v
* , the scaling will be applied first!
*
* This method is equivalent to calling: translate(ox, oy, oz, dest).scale(sx, sy, sz).translate(-ox, -oy, -oz)
*
* @param sx
* the scaling factor of the x component
* @param sy
* the scaling factor of the y component
* @param sz
* the scaling factor of the z component
* @param ox
* the x coordinate of the scaling origin
* @param oy
* the y coordinate of the scaling origin
* @param oz
* the z coordinate of the scaling origin
* @param dest
* will hold the result
* @return dest
*/
Matrix4f scaleAround(float sx, float sy, float sz, float ox, float oy, float oz, Matrix4f dest);
/**
* Apply scaling to this matrix by scaling all three base axes by the given factor
* while using (ox, oy, oz)
as the scaling origin,
* and store the result in dest
.
*
* If M
is this
matrix and S
the scaling matrix,
* then the new matrix will be M * S
. So when transforming a
* vector v
with the new matrix by using M * S * v
, the
* scaling will be applied first!
*
* This method is equivalent to calling: translate(ox, oy, oz, dest).scale(factor).translate(-ox, -oy, -oz)
*
* @param factor
* the scaling factor for all three axes
* @param ox
* the x coordinate of the scaling origin
* @param oy
* the y coordinate of the scaling origin
* @param oz
* the z coordinate of the scaling origin
* @param dest
* will hold the result
* @return this
*/
Matrix4f scaleAround(float factor, float ox, float oy, float oz, Matrix4f dest);
/**
* Pre-multiply scaling to this
matrix by scaling all base axes by the given xyz
factor,
* and store the result in dest
.
*
* If M
is this
matrix and S
the scaling matrix,
* then the new matrix will be S * M
. So when transforming a
* vector v
with the new matrix by using S * M * v
* , the scaling will be applied last!
*
* @param xyz
* the factor to scale all three base axes by
* @param dest
* will hold the result
* @return dest
*/
Matrix4f scaleLocal(float xyz, Matrix4f dest);
/**
* Pre-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 S * M
. So when transforming a
* vector v
with the new matrix by using S * M * v
* , the scaling will be applied last!
*
* @param x
* the factor of the x component
* @param y
* the factor of the y component
* @param z
* the factor of the z component
* @param dest
* will hold the result
* @return dest
*/
Matrix4f scaleLocal(float x, float y, float z, Matrix4f dest);
/**
* Pre-multiply scaling to this
matrix by scaling the base axes by the given sx,
* sy and sz factors while using the given (ox, oy, oz)
as the scaling origin,
* and store the result in dest
.
*
* If M
is this
matrix and S
the scaling matrix,
* then the new matrix will be S * M
. So when transforming a
* vector v
with the new matrix by using S * M * v
* , the scaling will be applied last!
*
* This method is equivalent to calling: new Matrix4f().translate(ox, oy, oz).scale(sx, sy, sz).translate(-ox, -oy, -oz).mul(this, dest)
*
* @param sx
* the scaling factor of the x component
* @param sy
* the scaling factor of the y component
* @param sz
* the scaling factor of the z component
* @param ox
* the x coordinate of the scaling origin
* @param oy
* the y coordinate of the scaling origin
* @param oz
* the z coordinate of the scaling origin
* @param dest
* will hold the result
* @return dest
*/
Matrix4f scaleAroundLocal(float sx, float sy, float sz, float ox, float oy, float oz, Matrix4f dest);
/**
* Pre-multiply scaling to this matrix by scaling all three base axes by the given factor
* while using (ox, oy, oz)
as the scaling origin,
* and store the result in dest
.
*
* If M
is this
matrix and S
the scaling matrix,
* then the new matrix will be S * M
. So when transforming a
* vector v
with the new matrix by using S * M * v
, the
* scaling will be applied last!
*
* This method is equivalent to calling: new Matrix4f().translate(ox, oy, oz).scale(factor).translate(-ox, -oy, -oz).mul(this, dest)
*
* @param factor
* the scaling factor for all three axes
* @param ox
* the x coordinate of the scaling origin
* @param oy
* the y coordinate of the scaling origin
* @param oz
* the z coordinate of the scaling origin
* @param dest
* will hold the result
* @return this
*/
Matrix4f scaleAroundLocal(float factor, float ox, float oy, float oz, Matrix4f dest);
/**
* Apply rotation about the X axis to this matrix by rotating the given amount of radians
* and store the result in dest
.
*
* 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.
*
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* rotation will be applied first!
*
* Reference: http://en.wikipedia.org
*
* @param ang
* the angle in radians
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateX(float ang, Matrix4f dest);
/**
* Apply rotation about the Y axis to this matrix by rotating the given amount of radians
* and store the result in dest
.
*
* 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.
*
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* rotation will be applied first!
*
* Reference: http://en.wikipedia.org
*
* @param ang
* the angle in radians
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateY(float ang, Matrix4f dest);
/**
* Apply rotation about the Z axis to this matrix by rotating the given amount of radians
* and store the result in dest
.
*
* 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.
*
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* rotation will be applied first!
*
* Reference: http://en.wikipedia.org
*
* @param ang
* the angle in radians
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateZ(float ang, Matrix4f dest);
/**
* Apply rotation about the Z axis to align the local +X
towards (dirX, dirY)
and store the result in dest
.
*
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* rotation will be applied first!
*
* The vector (dirX, dirY)
must be a unit vector.
*
* @param dirX
* the x component of the normalized direction
* @param dirY
* the y component of the normalized direction
* @param dest
* will hold the result
* @return this
*/
Matrix4f rotateTowardsXY(float dirX, float dirY, Matrix4f dest);
/**
* Apply rotation of angleX
radians about the X axis, followed by a rotation of angleY
radians about the Y axis and
* followed by a rotation of angleZ
radians about the Z axis and store the result in dest
.
*
* 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.
*
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* rotation will be applied first!
*
* This method is equivalent to calling: rotateX(angleX, dest).rotateY(angleY).rotateZ(angleZ)
*
* @param angleX
* the angle to rotate about X
* @param angleY
* the angle to rotate about Y
* @param angleZ
* the angle to rotate about Z
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateXYZ(float angleX, float angleY, float angleZ, Matrix4f dest);
/**
* Apply rotation of angleX
radians about the X axis, followed by a rotation of angleY
radians about the Y axis and
* followed by a rotation of angleZ
radians about the Z axis and store the result in dest
.
*
* 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 method assumes that this
matrix represents an {@link #isAffine() affine} transformation (i.e. its last row is equal to (0, 0, 0, 1)
)
* and can be used to speed up matrix multiplication if the matrix only represents affine transformations, such as translation, rotation, scaling and shearing (in any combination).
*
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* rotation will be applied first!
*
* @param angleX
* the angle to rotate about X
* @param angleY
* the angle to rotate about Y
* @param angleZ
* the angle to rotate about Z
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateAffineXYZ(float angleX, float angleY, float angleZ, Matrix4f dest);
/**
* Apply rotation of angleZ
radians about the Z axis, followed by a rotation of angleY
radians about the Y axis and
* followed by a rotation of angleX
radians about the X axis and store the result in dest
.
*
* 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.
*
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* rotation will be applied first!
*
* This method is equivalent to calling: rotateZ(angleZ, dest).rotateY(angleY).rotateX(angleX)
*
* @param angleZ
* the angle to rotate about Z
* @param angleY
* the angle to rotate about Y
* @param angleX
* the angle to rotate about X
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateZYX(float angleZ, float angleY, float angleX, Matrix4f dest);
/**
* Apply rotation of angleZ
radians about the Z axis, followed by a rotation of angleY
radians about the Y axis and
* followed by a rotation of angleX
radians about the X axis and store the result in dest
.
*
* 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 method assumes that this
matrix represents an {@link #isAffine() affine} transformation (i.e. its last row is equal to (0, 0, 0, 1)
)
* and can be used to speed up matrix multiplication if the matrix only represents affine transformations, such as translation, rotation, scaling and shearing (in any combination).
*
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* rotation will be applied first!
*
* @param angleZ
* the angle to rotate about Z
* @param angleY
* the angle to rotate about Y
* @param angleX
* the angle to rotate about X
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateAffineZYX(float angleZ, float angleY, float angleX, Matrix4f dest);
/**
* Apply rotation of angleY
radians about the Y axis, followed by a rotation of angleX
radians about the X axis and
* followed by a rotation of angleZ
radians about the Z axis and store the result in dest
.
*
* 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.
*
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* rotation will be applied first!
*
* This method is equivalent to calling: rotateY(angleY, dest).rotateX(angleX).rotateZ(angleZ)
*
* @param angleY
* the angle to rotate about Y
* @param angleX
* the angle to rotate about X
* @param angleZ
* the angle to rotate about Z
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateYXZ(float angleY, float angleX, float angleZ, Matrix4f dest);
/**
* Apply rotation of angleY
radians about the Y axis, followed by a rotation of angleX
radians about the X axis and
* followed by a rotation of angleZ
radians about the Z axis and store the result in dest
.
*
* 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 method assumes that this
matrix represents an {@link #isAffine() affine} transformation (i.e. its last row is equal to (0, 0, 0, 1)
)
* and can be used to speed up matrix multiplication if the matrix only represents affine transformations, such as translation, rotation, scaling and shearing (in any combination).
*
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* rotation will be applied first!
*
* @param angleY
* the angle to rotate about Y
* @param angleX
* the angle to rotate about X
* @param angleZ
* the angle to rotate about Z
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateAffineYXZ(float angleY, float angleX, float angleZ, Matrix4f dest);
/**
* Apply rotation to this matrix by rotating the given amount of radians
* about the specified (x, y, z)
axis and store the result in dest
.
*
* The axis described by the three components needs to be a unit vector.
*
* 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.
*
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* rotation will be applied first!
*
* Reference: http://en.wikipedia.org
*
* @param ang
* the angle in radians
* @param x
* the x component of the axis
* @param y
* the y component of the axis
* @param z
* the z component of the axis
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotate(float ang, float x, float y, float z, Matrix4f dest);
/**
* Apply rotation to this matrix, which is assumed to only contain a translation, by rotating the given amount of radians
* about the specified (x, y, z)
axis and store the result in dest
.
*
* This method assumes this
to only contain a translation.
*
* The axis described by the three components needs to be a unit vector.
*
* 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.
*
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* rotation will be applied first!
*
* Reference: http://en.wikipedia.org
*
* @param ang
* the angle in radians
* @param x
* the x component of the axis
* @param y
* the y component of the axis
* @param z
* the z component of the axis
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateTranslation(float ang, float x, float y, float z, Matrix4f dest);
/**
* Apply rotation to this {@link #isAffine() affine} matrix by rotating the given amount of radians
* about the specified (x, y, z)
axis and store the result in dest
.
*
* This method assumes this
to be {@link #isAffine() affine}.
*
* The axis described by the three components needs to be a unit vector.
*
* 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.
*
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* rotation will be applied first!
*
* Reference: http://en.wikipedia.org
*
* @param ang
* the angle in radians
* @param x
* the x component of the axis
* @param y
* the y component of the axis
* @param z
* the z component of the axis
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateAffine(float ang, float x, float y, float z, Matrix4f dest);
/**
* Pre-multiply a rotation to this matrix by rotating the given amount of radians
* about the specified (x, y, z)
axis and store the result in dest
.
*
* The axis described by the three components needs to be a unit vector.
*
* 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.
*
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be R * M
. So when transforming a
* vector v
with the new matrix by using R * M * v
, the
* rotation will be applied last!
*
* Reference: http://en.wikipedia.org
*
* @param ang
* the angle in radians
* @param x
* the x component of the axis
* @param y
* the y component of the axis
* @param z
* the z component of the axis
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateLocal(float ang, float x, float y, float z, Matrix4f dest);
/**
* Pre-multiply a rotation around the X axis to this matrix by rotating the given amount of radians
* about the X axis and store the result in dest
.
*
* 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.
*
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be R * M
. So when transforming a
* vector v
with the new matrix by using R * M * v
, the
* rotation will be applied last!
*
* Reference: http://en.wikipedia.org
*
* @param ang
* the angle in radians to rotate about the X axis
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateLocalX(float ang, Matrix4f dest);
/**
* Pre-multiply a rotation around the Y axis to this matrix by rotating the given amount of radians
* about the Y axis and store the result in dest
.
*
* 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.
*
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be R * M
. So when transforming a
* vector v
with the new matrix by using R * M * v
, the
* rotation will be applied last!
*
* Reference: http://en.wikipedia.org
*
* @param ang
* the angle in radians to rotate about the Y axis
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateLocalY(float ang, Matrix4f dest);
/**
* Pre-multiply a rotation around the Z axis to this matrix by rotating the given amount of radians
* about the Z axis and store the result in dest
.
*
* 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.
*
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be R * M
. So when transforming a
* vector v
with the new matrix by using R * M * v
, the
* rotation will be applied last!
*
* Reference: http://en.wikipedia.org
*
* @param ang
* the angle in radians to rotate about the Z axis
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateLocalZ(float ang, Matrix4f dest);
/**
* Apply a translation to this matrix by translating by the given number of
* units in x, y and z and store the result in dest
.
*
* If M
is this
matrix and T
the translation
* matrix, then the new matrix will be M * T
. So when
* transforming a vector v
with the new matrix by using
* M * T * v
, the translation will be applied first!
*
* @param offset
* the number of units in x, y and z by which to translate
* @param dest
* will hold the result
* @return dest
*/
Matrix4f translate(Vector3fc offset, Matrix4f dest);
/**
* Apply a translation to this matrix by translating by the given number of
* units in x, y and z and store the result in dest
.
*
* If M
is this
matrix and T
the translation
* matrix, then the new matrix will be M * T
. So when
* transforming a vector v
with the new matrix by using
* M * T * v
, the translation will be applied first!
*
* @param x
* the offset to translate in x
* @param y
* the offset to translate in y
* @param z
* the offset to translate in z
* @param dest
* will hold the result
* @return dest
*/
Matrix4f translate(float x, float y, float z, Matrix4f dest);
/**
* Pre-multiply a translation to this matrix by translating by the given number of
* units in x, y and z and store the result in dest
.
*
* If M
is this
matrix and T
the translation
* matrix, then the new matrix will be T * M
. So when
* transforming a vector v
with the new matrix by using
* T * M * v
, the translation will be applied last!
*
* @param offset
* the number of units in x, y and z by which to translate
* @param dest
* will hold the result
* @return dest
*/
Matrix4f translateLocal(Vector3fc offset, Matrix4f dest);
/**
* Pre-multiply a translation to this matrix by translating by the given number of
* units in x, y and z and store the result in dest
.
*
* If M
is this
matrix and T
the translation
* matrix, then the new matrix will be T * M
. So when
* transforming a vector v
with the new matrix by using
* T * M * v
, the translation will be applied last!
*
* @param x
* the offset to translate in x
* @param y
* the offset to translate in y
* @param z
* the offset to translate in z
* @param dest
* will hold the result
* @return dest
*/
Matrix4f translateLocal(float x, float y, float z, Matrix4f dest);
/**
* Apply an orthographic projection transformation for a right-handed coordinate system
* using the given NDC z range to this matrix and store the result in dest
.
*
* If M
is this
matrix and O
the orthographic projection matrix,
* then the new matrix will be M * O
. So when transforming a
* vector v
with the new matrix by using M * O * v
, the
* orthographic projection transformation will be applied first!
* Reference: http://www.songho.ca
*
* @param left
* the distance from the center to the left frustum edge
* @param right
* the distance from the center to the right frustum edge
* @param bottom
* the distance from the center to the bottom frustum edge
* @param top
* the distance from the center to the top frustum edge
* @param zNear
* near clipping plane distance
* @param zFar
* far clipping plane distance
* @param zZeroToOne
* whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
* or whether to use OpenGL's NDC z range of [-1..+1]
when false
* @param dest
* will hold the result
* @return dest
*/
Matrix4f ortho(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
/**
* Apply an orthographic projection transformation for a right-handed coordinate system
* using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
*
* If M
is this
matrix and O
the orthographic projection matrix,
* then the new matrix will be M * O
. So when transforming a
* vector v
with the new matrix by using M * O * v
, the
* orthographic projection transformation will be applied first!
*
* Reference: http://www.songho.ca
*
* @param left
* the distance from the center to the left frustum edge
* @param right
* the distance from the center to the right frustum edge
* @param bottom
* the distance from the center to the bottom frustum edge
* @param top
* the distance from the center to the top frustum edge
* @param zNear
* near clipping plane distance
* @param zFar
* far clipping plane distance
* @param dest
* will hold the result
* @return dest
*/
Matrix4f ortho(float left, float right, float bottom, float top, float zNear, float zFar, Matrix4f dest);
/**
* Apply an orthographic projection transformation for a left-handed coordiante system
* using the given NDC z range to this matrix and store the result in dest
.
*
* If M
is this
matrix and O
the orthographic projection matrix,
* then the new matrix will be M * O
. So when transforming a
* vector v
with the new matrix by using M * O * v
, the
* orthographic projection transformation will be applied first!
*
* Reference: http://www.songho.ca
*
* @param left
* the distance from the center to the left frustum edge
* @param right
* the distance from the center to the right frustum edge
* @param bottom
* the distance from the center to the bottom frustum edge
* @param top
* the distance from the center to the top frustum edge
* @param zNear
* near clipping plane distance
* @param zFar
* far clipping plane distance
* @param zZeroToOne
* whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
* or whether to use OpenGL's NDC z range of [-1..+1]
when false
* @param dest
* will hold the result
* @return dest
*/
Matrix4f orthoLH(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
/**
* Apply an orthographic projection transformation for a left-handed coordiante system
* using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
*
* If M
is this
matrix and O
the orthographic projection matrix,
* then the new matrix will be M * O
. So when transforming a
* vector v
with the new matrix by using M * O * v
, the
* orthographic projection transformation will be applied first!
*
* Reference: http://www.songho.ca
*
* @param left
* the distance from the center to the left frustum edge
* @param right
* the distance from the center to the right frustum edge
* @param bottom
* the distance from the center to the bottom frustum edge
* @param top
* the distance from the center to the top frustum edge
* @param zNear
* near clipping plane distance
* @param zFar
* far clipping plane distance
* @param dest
* will hold the result
* @return dest
*/
Matrix4f orthoLH(float left, float right, float bottom, float top, float zNear, float zFar, Matrix4f dest);
/**
* Apply a symmetric orthographic projection transformation for a right-handed coordinate system
* using the given NDC z range to this matrix and store the result in dest
.
*
* This method is equivalent to calling {@link #ortho(float, float, float, float, float, float, boolean, Matrix4f) ortho()} with
* left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
*
* If M
is this
matrix and O
the orthographic projection matrix,
* then the new matrix will be M * O
. So when transforming a
* vector v
with the new matrix by using M * O * v
, the
* orthographic projection transformation will be applied first!
*
* Reference: http://www.songho.ca
*
* @param width
* the distance between the right and left frustum edges
* @param height
* the distance between the top and bottom frustum edges
* @param zNear
* near clipping plane distance
* @param zFar
* far clipping plane distance
* @param dest
* will hold the result
* @param zZeroToOne
* whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
* or whether to use OpenGL's NDC z range of [-1..+1]
when false
* @return dest
*/
Matrix4f orthoSymmetric(float width, float height, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
/**
* Apply a symmetric orthographic projection transformation for a right-handed coordinate system
* using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
*
* This method is equivalent to calling {@link #ortho(float, float, float, float, float, float, Matrix4f) ortho()} with
* left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
*
* If M
is this
matrix and O
the orthographic projection matrix,
* then the new matrix will be M * O
. So when transforming a
* vector v
with the new matrix by using M * O * v
, the
* orthographic projection transformation will be applied first!
*
* Reference: http://www.songho.ca
*
* @param width
* the distance between the right and left frustum edges
* @param height
* the distance between the top and bottom frustum edges
* @param zNear
* near clipping plane distance
* @param zFar
* far clipping plane distance
* @param dest
* will hold the result
* @return dest
*/
Matrix4f orthoSymmetric(float width, float height, float zNear, float zFar, Matrix4f dest);
/**
* Apply a symmetric orthographic projection transformation for a left-handed coordinate system
* using the given NDC z range to this matrix and store the result in dest
.
*
* This method is equivalent to calling {@link #orthoLH(float, float, float, float, float, float, boolean, Matrix4f) orthoLH()} with
* left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
*
* If M
is this
matrix and O
the orthographic projection matrix,
* then the new matrix will be M * O
. So when transforming a
* vector v
with the new matrix by using M * O * v
, the
* orthographic projection transformation will be applied first!
*
* Reference: http://www.songho.ca
*
* @param width
* the distance between the right and left frustum edges
* @param height
* the distance between the top and bottom frustum edges
* @param zNear
* near clipping plane distance
* @param zFar
* far clipping plane distance
* @param dest
* will hold the result
* @param zZeroToOne
* whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
* or whether to use OpenGL's NDC z range of [-1..+1]
when false
* @return dest
*/
Matrix4f orthoSymmetricLH(float width, float height, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
/**
* Apply a symmetric orthographic projection transformation for a left-handed coordinate system
* using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
*
* This method is equivalent to calling {@link #orthoLH(float, float, float, float, float, float, Matrix4f) orthoLH()} with
* left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
*
* If M
is this
matrix and O
the orthographic projection matrix,
* then the new matrix will be M * O
. So when transforming a
* vector v
with the new matrix by using M * O * v
, the
* orthographic projection transformation will be applied first!
*
* Reference: http://www.songho.ca
*
* @param width
* the distance between the right and left frustum edges
* @param height
* the distance between the top and bottom frustum edges
* @param zNear
* near clipping plane distance
* @param zFar
* far clipping plane distance
* @param dest
* will hold the result
* @return dest
*/
Matrix4f orthoSymmetricLH(float width, float height, float zNear, float zFar, Matrix4f dest);
/**
* Apply an orthographic projection transformation for a right-handed coordinate system to this matrix
* and store the result in dest
.
*
* This method is equivalent to calling {@link #ortho(float, float, float, float, float, float, Matrix4f) ortho()} with
* zNear=-1
and zFar=+1
.
*
* If M
is this
matrix and O
the orthographic projection matrix,
* then the new matrix will be M * O
. So when transforming a
* vector v
with the new matrix by using M * O * v
, the
* orthographic projection transformation will be applied first!
*
* Reference: http://www.songho.ca
*
* @see #ortho(float, float, float, float, float, float, Matrix4f)
*
* @param left
* the distance from the center to the left frustum edge
* @param right
* the distance from the center to the right frustum edge
* @param bottom
* the distance from the center to the bottom frustum edge
* @param top
* the distance from the center to the top frustum edge
* @param dest
* will hold the result
* @return dest
*/
Matrix4f ortho2D(float left, float right, float bottom, float top, Matrix4f dest);
/**
* Apply an orthographic projection transformation for a left-handed coordinate system to this matrix and store the result in dest
.
*
* This method is equivalent to calling {@link #orthoLH(float, float, float, float, float, float, Matrix4f) orthoLH()} with
* zNear=-1
and zFar=+1
.
*
* If M
is this
matrix and O
the orthographic projection matrix,
* then the new matrix will be M * O
. So when transforming a
* vector v
with the new matrix by using M * O * v
, the
* orthographic projection transformation will be applied first!
*
* Reference: http://www.songho.ca
*
* @see #orthoLH(float, float, float, float, float, float, Matrix4f)
*
* @param left
* the distance from the center to the left frustum edge
* @param right
* the distance from the center to the right frustum edge
* @param bottom
* the distance from the center to the bottom frustum edge
* @param top
* the distance from the center to the top frustum edge
* @param dest
* will hold the result
* @return dest
*/
Matrix4f ortho2DLH(float left, float right, float bottom, float top, Matrix4f dest);
/**
* Apply a rotation transformation to this matrix to make -z
point along dir
* and store the result in dest
.
*
* If M
is this
matrix and L
the lookalong rotation matrix,
* then the new matrix will be M * L
. So when transforming a
* vector v
with the new matrix by using M * L * v
, the
* lookalong rotation transformation will be applied first!
*
* This is equivalent to calling
* {@link #lookAt(Vector3fc, Vector3fc, Vector3fc, Matrix4f) lookAt}
* with eye = (0, 0, 0)
and center = dir
.
*
* @see #lookAlong(float, float, float, float, float, float, Matrix4f)
* @see #lookAt(Vector3fc, Vector3fc, Vector3fc, Matrix4f)
*
* @param dir
* the direction in space to look along
* @param up
* the direction of 'up'
* @param dest
* will hold the result
* @return dest
*/
Matrix4f lookAlong(Vector3fc dir, Vector3fc up, Matrix4f dest);
/**
* Apply a rotation transformation to this matrix to make -z
point along dir
* and store the result in dest
.
*
* If M
is this
matrix and L
the lookalong rotation matrix,
* then the new matrix will be M * L
. So when transforming a
* vector v
with the new matrix by using M * L * v
, the
* lookalong rotation transformation will be applied first!
*
* This is equivalent to calling
* {@link #lookAt(float, float, float, float, float, float, float, float, float, Matrix4f) lookAt()}
* with eye = (0, 0, 0)
and center = dir
.
*
* @see #lookAt(float, float, float, float, float, float, float, float, float, Matrix4f)
*
* @param dirX
* the x-coordinate of the direction to look along
* @param dirY
* the y-coordinate of the direction to look along
* @param dirZ
* the z-coordinate of the direction to look along
* @param upX
* the x-coordinate of the up vector
* @param upY
* the y-coordinate of the up vector
* @param upZ
* the z-coordinate of the up vector
* @param dest
* will hold the result
* @return dest
*/
Matrix4f lookAlong(float dirX, float dirY, float dirZ, float upX, float upY, float upZ, Matrix4f dest);
/**
* Apply a "lookat" transformation to this matrix for a right-handed coordinate system,
* that aligns -z
with center - eye
and store the result in dest
.
*
* If M
is this
matrix and L
the lookat matrix,
* then the new matrix will be M * L
. So when transforming a
* vector v
with the new matrix by using M * L * v
,
* the lookat transformation will be applied first!
*
* @see #lookAt(float, float, float, float, float, float, float, float, float, Matrix4f)
*
* @param eye
* the position of the camera
* @param center
* the point in space to look at
* @param up
* the direction of 'up'
* @param dest
* will hold the result
* @return dest
*/
Matrix4f lookAt(Vector3fc eye, Vector3fc center, Vector3fc up, Matrix4f dest);
/**
* Apply a "lookat" transformation to this matrix for a right-handed coordinate system,
* that aligns -z
with center - eye
and store the result in dest
.
*
* If M
is this
matrix and L
the lookat matrix,
* then the new matrix will be M * L
. So when transforming a
* vector v
with the new matrix by using M * L * v
,
* the lookat transformation will be applied first!
*
* @see #lookAt(Vector3fc, Vector3fc, Vector3fc, Matrix4f)
*
* @param eyeX
* the x-coordinate of the eye/camera location
* @param eyeY
* the y-coordinate of the eye/camera location
* @param eyeZ
* the z-coordinate of the eye/camera location
* @param centerX
* the x-coordinate of the point to look at
* @param centerY
* the y-coordinate of the point to look at
* @param centerZ
* the z-coordinate of the point to look at
* @param upX
* the x-coordinate of the up vector
* @param upY
* the y-coordinate of the up vector
* @param upZ
* the z-coordinate of the up vector
* @param dest
* will hold the result
* @return dest
*/
Matrix4f lookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ, Matrix4f dest);
/**
* Apply a "lookat" transformation to this matrix for a right-handed coordinate system,
* that aligns -z
with center - eye
and store the result in dest
.
*
* This method assumes this
to be a perspective transformation, obtained via
* {@link #frustum(float, float, float, float, float, float, Matrix4f) frustum()} or {@link #perspective(float, float, float, float, Matrix4f) perspective()} or
* one of their overloads.
*
* If M
is this
matrix and L
the lookat matrix,
* then the new matrix will be M * L
. So when transforming a
* vector v
with the new matrix by using M * L * v
,
* the lookat transformation will be applied first!
*
* @param eyeX
* the x-coordinate of the eye/camera location
* @param eyeY
* the y-coordinate of the eye/camera location
* @param eyeZ
* the z-coordinate of the eye/camera location
* @param centerX
* the x-coordinate of the point to look at
* @param centerY
* the y-coordinate of the point to look at
* @param centerZ
* the z-coordinate of the point to look at
* @param upX
* the x-coordinate of the up vector
* @param upY
* the y-coordinate of the up vector
* @param upZ
* the z-coordinate of the up vector
* @param dest
* will hold the result
* @return dest
*/
Matrix4f lookAtPerspective(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ, Matrix4f dest);
/**
* Apply a "lookat" transformation to this matrix for a left-handed coordinate system,
* that aligns +z
with center - eye
and store the result in dest
.
*
* If M
is this
matrix and L
the lookat matrix,
* then the new matrix will be M * L
. So when transforming a
* vector v
with the new matrix by using M * L * v
,
* the lookat transformation will be applied first!
*
* @see #lookAtLH(float, float, float, float, float, float, float, float, float, Matrix4f)
*
* @param eye
* the position of the camera
* @param center
* the point in space to look at
* @param up
* the direction of 'up'
* @param dest
* will hold the result
* @return dest
*/
Matrix4f lookAtLH(Vector3fc eye, Vector3fc center, Vector3fc up, Matrix4f dest);
/**
* Apply a "lookat" transformation to this matrix for a left-handed coordinate system,
* that aligns +z
with center - eye
and store the result in dest
.
*
* If M
is this
matrix and L
the lookat matrix,
* then the new matrix will be M * L
. So when transforming a
* vector v
with the new matrix by using M * L * v
,
* the lookat transformation will be applied first!
*
* @see #lookAtLH(Vector3fc, Vector3fc, Vector3fc, Matrix4f)
*
* @param eyeX
* the x-coordinate of the eye/camera location
* @param eyeY
* the y-coordinate of the eye/camera location
* @param eyeZ
* the z-coordinate of the eye/camera location
* @param centerX
* the x-coordinate of the point to look at
* @param centerY
* the y-coordinate of the point to look at
* @param centerZ
* the z-coordinate of the point to look at
* @param upX
* the x-coordinate of the up vector
* @param upY
* the y-coordinate of the up vector
* @param upZ
* the z-coordinate of the up vector
* @param dest
* will hold the result
* @return dest
*/
Matrix4f lookAtLH(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ, Matrix4f dest);
/**
* Apply a "lookat" transformation to this matrix for a left-handed coordinate system,
* that aligns +z
with center - eye
and store the result in dest
.
*
* This method assumes this
to be a perspective transformation, obtained via
* {@link #frustumLH(float, float, float, float, float, float, Matrix4f) frustumLH()} or {@link #perspectiveLH(float, float, float, float, Matrix4f) perspectiveLH()} or
* one of their overloads.
*
* If M
is this
matrix and L
the lookat matrix,
* then the new matrix will be M * L
. So when transforming a
* vector v
with the new matrix by using M * L * v
,
* the lookat transformation will be applied first!
*
* @param eyeX
* the x-coordinate of the eye/camera location
* @param eyeY
* the y-coordinate of the eye/camera location
* @param eyeZ
* the z-coordinate of the eye/camera location
* @param centerX
* the x-coordinate of the point to look at
* @param centerY
* the y-coordinate of the point to look at
* @param centerZ
* the z-coordinate of the point to look at
* @param upX
* the x-coordinate of the up vector
* @param upY
* the y-coordinate of the up vector
* @param upZ
* the z-coordinate of the up vector
* @param dest
* will hold the result
* @return dest
*/
Matrix4f lookAtPerspectiveLH(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ, Matrix4f dest);
/**
* Apply a symmetric perspective projection frustum transformation for a right-handed coordinate system
* using the given NDC z range to this matrix and store the result in dest
.
*
* If M
is this
matrix and P
the perspective projection matrix,
* then the new matrix will be M * P
. So when transforming a
* vector v
with the new matrix by using M * P * v
,
* the perspective projection will be applied first!
*
* @param fovy
* the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
* @param aspect
* the aspect ratio (i.e. width / height; must be greater than zero)
* @param zNear
* near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
* In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zFar
* far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
* In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
* @param dest
* will hold the result
* @param zZeroToOne
* whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
* or whether to use OpenGL's NDC z range of [-1..+1]
when false
* @return dest
*/
Matrix4f perspective(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
/**
* Apply a symmetric perspective projection frustum transformation for a right-handed coordinate system
* using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
*
* If M
is this
matrix and P
the perspective projection matrix,
* then the new matrix will be M * P
. So when transforming a
* vector v
with the new matrix by using M * P * v
,
* the perspective projection will be applied first!
*
* @param fovy
* the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
* @param aspect
* the aspect ratio (i.e. width / height; must be greater than zero)
* @param zNear
* near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
* In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zFar
* far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
* In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
* @param dest
* will hold the result
* @return dest
*/
Matrix4f perspective(float fovy, float aspect, float zNear, float zFar, Matrix4f dest);
/**
* Apply a symmetric perspective projection frustum transformation for a right-handed coordinate system
* using the given NDC z range to this matrix and store the result in dest
.
*
* If M
is this
matrix and P
the perspective projection matrix,
* then the new matrix will be M * P
. So when transforming a
* vector v
with the new matrix by using M * P * v
,
* the perspective projection will be applied first!
*
* @param width
* the width of the near frustum plane
* @param height
* the height of the near frustum plane
* @param zNear
* near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
* In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zFar
* far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
* In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
* @param dest
* will hold the result
* @param zZeroToOne
* whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
* or whether to use OpenGL's NDC z range of [-1..+1]
when false
* @return dest
*/
Matrix4f perspectiveRect(float width, float height, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
/**
* Apply a symmetric perspective projection frustum transformation for a right-handed coordinate system
* using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
*
* If M
is this
matrix and P
the perspective projection matrix,
* then the new matrix will be M * P
. So when transforming a
* vector v
with the new matrix by using M * P * v
,
* the perspective projection will be applied first!
*
* @param width
* the width of the near frustum plane
* @param height
* the height of the near frustum plane
* @param zNear
* near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
* In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zFar
* far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
* In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
* @param dest
* will hold the result
* @return dest
*/
Matrix4f perspectiveRect(float width, float height, float zNear, float zFar, Matrix4f dest);
/**
* Apply a symmetric perspective projection frustum transformation using for a right-handed coordinate system
* the given NDC z range to this matrix.
*
* If M
is this
matrix and P
the perspective projection matrix,
* then the new matrix will be M * P
. So when transforming a
* vector v
with the new matrix by using M * P * v
,
* the perspective projection will be applied first!
*
* @param width
* the width of the near frustum plane
* @param height
* the height of the near frustum plane
* @param zNear
* near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
* In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zFar
* far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
* In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zZeroToOne
* whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
* or whether to use OpenGL's NDC z range of [-1..+1]
when false
* @return a matrix holding the result
*/
Matrix4f perspectiveRect(float width, float height, float zNear, float zFar, boolean zZeroToOne);
/**
* Apply a symmetric perspective projection frustum transformation for a right-handed coordinate system
* using OpenGL's NDC z range of [-1..+1]
to this matrix.
*
* If M
is this
matrix and P
the perspective projection matrix,
* then the new matrix will be M * P
. So when transforming a
* vector v
with the new matrix by using M * P * v
,
* the perspective projection will be applied first!
*
* @param width
* the width of the near frustum plane
* @param height
* the height of the near frustum plane
* @param zNear
* near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
* In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zFar
* far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
* In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
* @return a matrix holding the result
*/
Matrix4f perspectiveRect(float width, float height, float zNear, float zFar);
/**
* Apply an asymmetric off-center perspective projection frustum transformation for a right-handed coordinate system
* using the given NDC z range to this matrix and store the result in dest
.
*
* The given angles offAngleX
and offAngleY
are the horizontal and vertical angles between
* the line of sight and the line given by the center of the near and far frustum planes. So, when offAngleY
* is just fovy/2
then the projection frustum is rotated towards +Y and the bottom frustum plane
* is parallel to the XZ-plane.
*
* If M
is this
matrix and P
the perspective projection matrix,
* then the new matrix will be M * P
. So when transforming a
* vector v
with the new matrix by using M * P * v
,
* the perspective projection will be applied first!
*
* @param fovy
* the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
* @param offAngleX
* the horizontal angle between the line of sight and the line crossing the center of the near and far frustum planes
* @param offAngleY
* the vertical angle between the line of sight and the line crossing the center of the near and far frustum planes
* @param aspect
* the aspect ratio (i.e. width / height; must be greater than zero)
* @param zNear
* near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
* In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zFar
* far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
* In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
* @param dest
* will hold the result
* @param zZeroToOne
* whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
* or whether to use OpenGL's NDC z range of [-1..+1]
when false
* @return dest
*/
Matrix4f perspectiveOffCenter(float fovy, float offAngleX, float offAngleY, float aspect, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
/**
* Apply an asymmetric off-center perspective projection frustum transformation for a right-handed coordinate system
* using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
*
* The given angles offAngleX
and offAngleY
are the horizontal and vertical angles between
* the line of sight and the line given by the center of the near and far frustum planes. So, when offAngleY
* is just fovy/2
then the projection frustum is rotated towards +Y and the bottom frustum plane
* is parallel to the XZ-plane.
*
* If M
is this
matrix and P
the perspective projection matrix,
* then the new matrix will be M * P
. So when transforming a
* vector v
with the new matrix by using M * P * v
,
* the perspective projection will be applied first!
*
* @param fovy
* the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
* @param offAngleX
* the horizontal angle between the line of sight and the line crossing the center of the near and far frustum planes
* @param offAngleY
* the vertical angle between the line of sight and the line crossing the center of the near and far frustum planes
* @param aspect
* the aspect ratio (i.e. width / height; must be greater than zero)
* @param zNear
* near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
* In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zFar
* far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
* In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
* @param dest
* will hold the result
* @return dest
*/
Matrix4f perspectiveOffCenter(float fovy, float offAngleX, float offAngleY, float aspect, float zNear, float zFar, Matrix4f dest);
/**
* Apply an asymmetric off-center perspective projection frustum transformation using for a right-handed coordinate system
* the given NDC z range to this matrix.
*
* The given angles offAngleX
and offAngleY
are the horizontal and vertical angles between
* the line of sight and the line given by the center of the near and far frustum planes. So, when offAngleY
* is just fovy/2
then the projection frustum is rotated towards +Y and the bottom frustum plane
* is parallel to the XZ-plane.
*
* If M
is this
matrix and P
the perspective projection matrix,
* then the new matrix will be M * P
. So when transforming a
* vector v
with the new matrix by using M * P * v
,
* the perspective projection will be applied first!
*
* @param fovy
* the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
* @param offAngleX
* the horizontal angle between the line of sight and the line crossing the center of the near and far frustum planes
* @param offAngleY
* the vertical angle between the line of sight and the line crossing the center of the near and far frustum planes
* @param aspect
* the aspect ratio (i.e. width / height; must be greater than zero)
* @param zNear
* near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
* In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zFar
* far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
* In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zZeroToOne
* whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
* or whether to use OpenGL's NDC z range of [-1..+1]
when false
* @return a matrix holding the result
*/
Matrix4f perspectiveOffCenter(float fovy, float offAngleX, float offAngleY, float aspect, float zNear, float zFar, boolean zZeroToOne);
/**
* Apply an asymmetric off-center perspective projection frustum transformation for a right-handed coordinate system
* using OpenGL's NDC z range of [-1..+1]
to this matrix.
*
* The given angles offAngleX
and offAngleY
are the horizontal and vertical angles between
* the line of sight and the line given by the center of the near and far frustum planes. So, when offAngleY
* is just fovy/2
then the projection frustum is rotated towards +Y and the bottom frustum plane
* is parallel to the XZ-plane.
*
* If M
is this
matrix and P
the perspective projection matrix,
* then the new matrix will be M * P
. So when transforming a
* vector v
with the new matrix by using M * P * v
,
* the perspective projection will be applied first!
*
* @param fovy
* the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
* @param offAngleX
* the horizontal angle between the line of sight and the line crossing the center of the near and far frustum planes
* @param offAngleY
* the vertical angle between the line of sight and the line crossing the center of the near and far frustum planes
* @param aspect
* the aspect ratio (i.e. width / height; must be greater than zero)
* @param zNear
* near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
* In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zFar
* far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
* In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
* @return a matrix holding the result
*/
Matrix4f perspectiveOffCenter(float fovy, float offAngleX, float offAngleY, float aspect, float zNear, float zFar);
/**
* Apply a symmetric perspective projection frustum transformation for a left-handed coordinate system
* using the given NDC z range to this matrix and store the result in dest
.
*
* If M
is this
matrix and P
the perspective projection matrix,
* then the new matrix will be M * P
. So when transforming a
* vector v
with the new matrix by using M * P * v
,
* the perspective projection will be applied first!
*
* @param fovy
* the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
* @param aspect
* the aspect ratio (i.e. width / height; must be greater than zero)
* @param zNear
* near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
* In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zFar
* far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
* In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zZeroToOne
* whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
* or whether to use OpenGL's NDC z range of [-1..+1]
when false
* @param dest
* will hold the result
* @return dest
*/
Matrix4f perspectiveLH(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
/**
* Apply a symmetric perspective projection frustum transformation for a left-handed coordinate system
* using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
*
* If M
is this
matrix and P
the perspective projection matrix,
* then the new matrix will be M * P
. So when transforming a
* vector v
with the new matrix by using M * P * v
,
* the perspective projection will be applied first!
*
* @param fovy
* the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
* @param aspect
* the aspect ratio (i.e. width / height; must be greater than zero)
* @param zNear
* near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
* In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zFar
* far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
* In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
* @param dest
* will hold the result
* @return dest
*/
Matrix4f perspectiveLH(float fovy, float aspect, float zNear, float zFar, Matrix4f dest);
/**
* Apply an arbitrary perspective projection frustum transformation for a right-handed coordinate system
* using the given NDC z range to this matrix and store the result in dest
.
*
* If M
is this
matrix and F
the frustum matrix,
* then the new matrix will be M * F
. So when transforming a
* vector v
with the new matrix by using M * F * v
,
* the frustum transformation will be applied first!
*
* Reference: http://www.songho.ca
*
* @param left
* the distance along the x-axis to the left frustum edge
* @param right
* the distance along the x-axis to the right frustum edge
* @param bottom
* the distance along the y-axis to the bottom frustum edge
* @param top
* the distance along the y-axis to the top frustum edge
* @param zNear
* near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
* In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zFar
* far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
* In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zZeroToOne
* whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
* or whether to use OpenGL's NDC z range of [-1..+1]
when false
* @param dest
* will hold the result
* @return dest
*/
Matrix4f frustum(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
/**
* Apply an arbitrary perspective projection frustum transformation for a right-handed coordinate system
* using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
*
* If M
is this
matrix and F
the frustum matrix,
* then the new matrix will be M * F
. So when transforming a
* vector v
with the new matrix by using M * F * v
,
* the frustum transformation will be applied first!
*
* Reference: http://www.songho.ca
*
* @param left
* the distance along the x-axis to the left frustum edge
* @param right
* the distance along the x-axis to the right frustum edge
* @param bottom
* the distance along the y-axis to the bottom frustum edge
* @param top
* the distance along the y-axis to the top frustum edge
* @param zNear
* near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
* In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zFar
* far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
* In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
* @param dest
* will hold the result
* @return dest
*/
Matrix4f frustum(float left, float right, float bottom, float top, float zNear, float zFar, Matrix4f dest);
/**
* Apply an arbitrary perspective projection frustum transformation for a left-handed coordinate system
* using the given NDC z range to this matrix and store the result in dest
.
*
* If M
is this
matrix and F
the frustum matrix,
* then the new matrix will be M * F
. So when transforming a
* vector v
with the new matrix by using M * F * v
,
* the frustum transformation will be applied first!
*
* Reference: http://www.songho.ca
*
* @param left
* the distance along the x-axis to the left frustum edge
* @param right
* the distance along the x-axis to the right frustum edge
* @param bottom
* the distance along the y-axis to the bottom frustum edge
* @param top
* the distance along the y-axis to the top frustum edge
* @param zNear
* near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
* In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zFar
* far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
* In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zZeroToOne
* whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
* or whether to use OpenGL's NDC z range of [-1..+1]
when false
* @param dest
* will hold the result
* @return dest
*/
Matrix4f frustumLH(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
/**
* Apply an arbitrary perspective projection frustum transformation for a left-handed coordinate system
* using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
*
* If M
is this
matrix and F
the frustum matrix,
* then the new matrix will be M * F
. So when transforming a
* vector v
with the new matrix by using M * F * v
,
* the frustum transformation will be applied first!
*
* Reference: http://www.songho.ca
*
* @param left
* the distance along the x-axis to the left frustum edge
* @param right
* the distance along the x-axis to the right frustum edge
* @param bottom
* the distance along the y-axis to the bottom frustum edge
* @param top
* the distance along the y-axis to the top frustum edge
* @param zNear
* near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
* In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
* @param zFar
* far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
* In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
* @param dest
* will hold the result
* @return dest
*/
Matrix4f frustumLH(float left, float right, float bottom, float top, float zNear, float zFar, Matrix4f dest);
/**
* Apply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this matrix and store
* the result in dest
.
*
* 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.
*
* If M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
* then the new matrix will be M * Q
. So when transforming a
* vector v
with the new matrix by using M * Q * v
,
* the quaternion rotation will be applied first!
*
* Reference: http://en.wikipedia.org
*
* @param quat
* the {@link Quaternionfc}
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotate(Quaternionfc quat, Matrix4f dest);
/**
* Apply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this {@link #isAffine() affine} matrix and store
* the result in dest
.
*
* This method assumes this
to be {@link #isAffine() affine}.
*
* 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.
*
* If M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
* then the new matrix will be M * Q
. So when transforming a
* vector v
with the new matrix by using M * Q * v
,
* the quaternion rotation will be applied first!
*
* Reference: http://en.wikipedia.org
*
* @param quat
* the {@link Quaternionfc}
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateAffine(Quaternionfc quat, Matrix4f dest);
/**
* Apply the rotation - and possibly scaling - ransformation of the given {@link Quaternionfc} to this matrix, which is assumed to only contain a translation, and store
* the result in dest
.
*
* This method assumes this
to only contain a translation.
*
* 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.
*
* If M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
* then the new matrix will be M * Q
. So when transforming a
* vector v
with the new matrix by using M * Q * v
,
* the quaternion rotation will be applied first!
*
* Reference: http://en.wikipedia.org
*
* @param quat
* the {@link Quaternionfc}
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateTranslation(Quaternionfc quat, Matrix4f dest);
/**
* Apply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this {@link #isAffine() affine}
* matrix while using (ox, oy, oz)
as the rotation origin, and store the result in dest
.
*
* 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.
*
* If M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
* then the new matrix will be M * Q
. So when transforming a
* vector v
with the new matrix by using M * Q * v
,
* the quaternion rotation will be applied first!
*
* This method is only applicable if this
is an {@link #isAffine() affine} matrix.
*
* This method is equivalent to calling: translate(ox, oy, oz, dest).rotate(quat).translate(-ox, -oy, -oz)
*
* Reference: http://en.wikipedia.org
*
* @param quat
* the {@link Quaternionfc}
* @param ox
* the x coordinate of the rotation origin
* @param oy
* the y coordinate of the rotation origin
* @param oz
* the z coordinate of the rotation origin
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateAroundAffine(Quaternionfc quat, float ox, float oy, float oz, Matrix4f dest);
/**
* Apply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this matrix while using (ox, oy, oz)
as the rotation origin,
* and store the result in dest
.
*
* 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.
*
* If M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
* then the new matrix will be M * Q
. So when transforming a
* vector v
with the new matrix by using M * Q * v
,
* the quaternion rotation will be applied first!
*
* This method is equivalent to calling: translate(ox, oy, oz, dest).rotate(quat).translate(-ox, -oy, -oz)
*
* Reference: http://en.wikipedia.org
*
* @param quat
* the {@link Quaternionfc}
* @param ox
* the x coordinate of the rotation origin
* @param oy
* the y coordinate of the rotation origin
* @param oz
* the z coordinate of the rotation origin
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateAround(Quaternionfc quat, float ox, float oy, float oz, Matrix4f dest);
/**
* Pre-multiply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this matrix and store
* the result in dest
.
*
* 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.
*
* If M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
* then the new matrix will be Q * M
. So when transforming a
* vector v
with the new matrix by using Q * M * v
,
* the quaternion rotation will be applied last!
*
* Reference: http://en.wikipedia.org
*
* @param quat
* the {@link Quaternionfc}
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateLocal(Quaternionfc quat, Matrix4f dest);
/**
* Pre-multiply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this matrix while using (ox, oy, oz)
* as the rotation origin, and store the result in dest
.
*
* 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.
*
* If M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
* then the new matrix will be Q * M
. So when transforming a
* vector v
with the new matrix by using Q * M * v
,
* the quaternion rotation will be applied last!
*
* This method is equivalent to calling: translateLocal(-ox, -oy, -oz, dest).rotateLocal(quat).translateLocal(ox, oy, oz)
*
* Reference: http://en.wikipedia.org
*
* @param quat
* the {@link Quaternionfc}
* @param ox
* the x coordinate of the rotation origin
* @param oy
* the y coordinate of the rotation origin
* @param oz
* the z coordinate of the rotation origin
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateAroundLocal(Quaternionfc quat, float ox, float oy, float oz, Matrix4f dest);
/**
* Apply a rotation transformation, rotating about the given {@link AxisAngle4f} and store the result in dest
.
*
* 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.
*
* If M
is this
matrix and A
the rotation matrix obtained from the given {@link AxisAngle4f},
* then the new matrix will be M * A
. So when transforming a
* vector v
with the new matrix by using M * A * v
,
* the {@link AxisAngle4f} rotation will be applied first!
*
* Reference: http://en.wikipedia.org
*
* @see #rotate(float, float, float, float, Matrix4f)
*
* @param axisAngle
* the {@link AxisAngle4f} (needs to be {@link AxisAngle4f#normalize() normalized})
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotate(AxisAngle4f axisAngle, Matrix4f dest);
/**
* Apply a rotation transformation, rotating the given radians about the specified axis and store the result in dest
.
*
* The axis described by the axis
vector needs to be a unit vector.
*
* 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.
*
* If M
is this
matrix and A
the rotation matrix obtained from the given axis-angle,
* then the new matrix will be M * A
. So when transforming a
* vector v
with the new matrix by using M * A * v
,
* the axis-angle rotation will be applied first!
*
* Reference: http://en.wikipedia.org
*
* @see #rotate(float, float, float, float, Matrix4f)
*
* @param angle
* the angle in radians
* @param axis
* the rotation axis (needs to be {@link Vector3fc#normalize(Vector3f) normalized})
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotate(float angle, Vector3fc axis, Matrix4f dest);
/**
* Unproject the given window coordinates (winX, winY, winZ)
by this
matrix using the specified viewport.
*
* This method first converts the given window coordinates to normalized device coordinates in the range [-1..1]
* and then transforms those NDC coordinates by the inverse of this
matrix.
*
* The depth range of winZ
is assumed to be [0..1]
, which is also the OpenGL default.
*
* As a necessary computation step for unprojecting, this method computes the inverse of this
matrix.
* In order to avoid computing the matrix inverse with every invocation, the inverse of this
matrix can be built
* once outside using {@link #invert(Matrix4f)} and then the method {@link #unprojectInv(float, float, float, int[], Vector4f) unprojectInv()} can be invoked on it.
*
* @see #unprojectInv(float, float, float, int[], Vector4f)
* @see #invert(Matrix4f)
*
* @param winX
* the x-coordinate in window coordinates (pixels)
* @param winY
* the y-coordinate in window coordinates (pixels)
* @param winZ
* the z-coordinate, which is the depth value in [0..1]
* @param viewport
* the viewport described by [x, y, width, height]
* @param dest
* will hold the unprojected position
* @return dest
*/
Vector4f unproject(float winX, float winY, float winZ, int[] viewport, Vector4f dest);
/**
* Unproject the given window coordinates (winX, winY, winZ)
by this
matrix using the specified viewport.
*
* This method first converts the given window coordinates to normalized device coordinates in the range [-1..1]
* and then transforms those NDC coordinates by the inverse of this
matrix.
*
* The depth range of winZ
is assumed to be [0..1]
, which is also the OpenGL default.
*
* As a necessary computation step for unprojecting, this method computes the inverse of this
matrix.
* In order to avoid computing the matrix inverse with every invocation, the inverse of this
matrix can be built
* once outside using {@link #invert(Matrix4f)} and then the method {@link #unprojectInv(float, float, float, int[], Vector3f) unprojectInv()} can be invoked on it.
*
* @see #unprojectInv(float, float, float, int[], Vector3f)
* @see #invert(Matrix4f)
*
* @param winX
* the x-coordinate in window coordinates (pixels)
* @param winY
* the y-coordinate in window coordinates (pixels)
* @param winZ
* the z-coordinate, which is the depth value in [0..1]
* @param viewport
* the viewport described by [x, y, width, height]
* @param dest
* will hold the unprojected position
* @return dest
*/
Vector3f unproject(float winX, float winY, float winZ, int[] viewport, Vector3f dest);
/**
* Unproject the given window coordinates winCoords
by this
matrix using the specified viewport.
*
* This method first converts the given window coordinates to normalized device coordinates in the range [-1..1]
* and then transforms those NDC coordinates by the inverse of this
matrix.
*
* The depth range of winCoords.z
is assumed to be [0..1]
, which is also the OpenGL default.
*
* As a necessary computation step for unprojecting, this method computes the inverse of this
matrix.
* In order to avoid computing the matrix inverse with every invocation, the inverse of this
matrix can be built
* once outside using {@link #invert(Matrix4f)} and then the method {@link #unprojectInv(float, float, float, int[], Vector4f) unprojectInv()} can be invoked on it.
*
* @see #unprojectInv(float, float, float, int[], Vector4f)
* @see #unproject(float, float, float, int[], Vector4f)
* @see #invert(Matrix4f)
*
* @param winCoords
* the window coordinates to unproject
* @param viewport
* the viewport described by [x, y, width, height]
* @param dest
* will hold the unprojected position
* @return dest
*/
Vector4f unproject(Vector3fc winCoords, int[] viewport, Vector4f dest);
/**
* Unproject the given window coordinates winCoords
by this
matrix using the specified viewport.
*
* This method first converts the given window coordinates to normalized device coordinates in the range [-1..1]
* and then transforms those NDC coordinates by the inverse of this
matrix.
*
* The depth range of winCoords.z
is assumed to be [0..1]
, which is also the OpenGL default.
*
* As a necessary computation step for unprojecting, this method computes the inverse of this
matrix.
* In order to avoid computing the matrix inverse with every invocation, the inverse of this
matrix can be built
* once outside using {@link #invert(Matrix4f)} and then the method {@link #unprojectInv(float, float, float, int[], Vector3f) unprojectInv()} can be invoked on it.
*
* @see #unprojectInv(float, float, float, int[], Vector3f)
* @see #unproject(float, float, float, int[], Vector3f)
* @see #invert(Matrix4f)
*
* @param winCoords
* the window coordinates to unproject
* @param viewport
* the viewport described by [x, y, width, height]
* @param dest
* will hold the unprojected position
* @return dest
*/
Vector3f unproject(Vector3fc winCoords, int[] viewport, Vector3f dest);
/**
* Unproject the given 2D window coordinates (winX, winY)
by this
matrix using the specified viewport
* and compute the origin and the direction of the resulting ray which starts at NDC z = -1.0
and goes through NDC z = +1.0
.
*
* This method first converts the given window coordinates to normalized device coordinates in the range [-1..1]
* and then transforms those NDC coordinates by the inverse of this
matrix.
*
* As a necessary computation step for unprojecting, this method computes the inverse of this
matrix.
* In order to avoid computing the matrix inverse with every invocation, the inverse of this
matrix can be built
* once outside using {@link #invert(Matrix4f)} and then the method {@link #unprojectInvRay(float, float, int[], Vector3f, Vector3f) unprojectInvRay()} can be invoked on it.
*
* @see #unprojectInvRay(float, float, int[], Vector3f, Vector3f)
* @see #invert(Matrix4f)
*
* @param winX
* the x-coordinate in window coordinates (pixels)
* @param winY
* the y-coordinate in window coordinates (pixels)
* @param viewport
* the viewport described by [x, y, width, height]
* @param originDest
* will hold the ray origin
* @param dirDest
* will hold the (unnormalized) ray direction
* @return this
*/
Matrix4f unprojectRay(float winX, float winY, int[] viewport, Vector3f originDest, Vector3f dirDest);
/**
* Unproject the given 2D window coordinates winCoords
by this
matrix using the specified viewport
* and compute the origin and the direction of the resulting ray which starts at NDC z = -1.0
and goes through NDC z = +1.0
.
*
* This method first converts the given window coordinates to normalized device coordinates in the range [-1..1]
* and then transforms those NDC coordinates by the inverse of this
matrix.
*
* As a necessary computation step for unprojecting, this method computes the inverse of this
matrix.
* In order to avoid computing the matrix inverse with every invocation, the inverse of this
matrix can be built
* once outside using {@link #invert(Matrix4f)} and then the method {@link #unprojectInvRay(float, float, int[], Vector3f, Vector3f) unprojectInvRay()} can be invoked on it.
*
* @see #unprojectInvRay(float, float, int[], Vector3f, Vector3f)
* @see #unprojectRay(float, float, int[], Vector3f, Vector3f)
* @see #invert(Matrix4f)
*
* @param winCoords
* the window coordinates to unproject
* @param viewport
* the viewport described by [x, y, width, height]
* @param originDest
* will hold the ray origin
* @param dirDest
* will hold the (unnormalized) ray direction
* @return this
*/
Matrix4f unprojectRay(Vector2fc winCoords, int[] viewport, Vector3f originDest, Vector3f dirDest);
/**
* Unproject the given window coordinates winCoords
by this
matrix using the specified viewport.
*
* This method differs from {@link #unproject(Vector3fc, int[], Vector4f) unproject()}
* in that it assumes that this
is already the inverse matrix of the original projection matrix.
* It exists to avoid recomputing the matrix inverse with every invocation.
*
* The depth range of winCoords.z
is assumed to be [0..1]
, which is also the OpenGL default.
*
* This method reads the four viewport parameters from the given int[].
*
* @see #unproject(Vector3fc, int[], Vector4f)
*
* @param winCoords
* the window coordinates to unproject
* @param viewport
* the viewport described by [x, y, width, height]
* @param dest
* will hold the unprojected position
* @return dest
*/
Vector4f unprojectInv(Vector3fc winCoords, int[] viewport, Vector4f dest);
/**
* Unproject the given window coordinates (winX, winY, winZ)
by this
matrix using the specified viewport.
*
* This method differs from {@link #unproject(float, float, float, int[], Vector4f) unproject()}
* in that it assumes that this
is already the inverse matrix of the original projection matrix.
* It exists to avoid recomputing the matrix inverse with every invocation.
*
* The depth range of winZ
is assumed to be [0..1]
, which is also the OpenGL default.
*
* @see #unproject(float, float, float, int[], Vector4f)
*
* @param winX
* the x-coordinate in window coordinates (pixels)
* @param winY
* the y-coordinate in window coordinates (pixels)
* @param winZ
* the z-coordinate, which is the depth value in [0..1]
* @param viewport
* the viewport described by [x, y, width, height]
* @param dest
* will hold the unprojected position
* @return dest
*/
Vector4f unprojectInv(float winX, float winY, float winZ, int[] viewport, Vector4f dest);
/**
* Unproject the given window coordinates winCoords
by this
matrix using the specified viewport
* and compute the origin and the direction of the resulting ray which starts at NDC z = -1.0
and goes through NDC z = +1.0
.
*
* This method differs from {@link #unprojectRay(Vector2fc, int[], Vector3f, Vector3f) unprojectRay()}
* in that it assumes that this
is already the inverse matrix of the original projection matrix.
* It exists to avoid recomputing the matrix inverse with every invocation.
*
* @see #unprojectRay(Vector2fc, int[], Vector3f, Vector3f)
*
* @param winCoords
* the window coordinates to unproject
* @param viewport
* the viewport described by [x, y, width, height]
* @param originDest
* will hold the ray origin
* @param dirDest
* will hold the (unnormalized) ray direction
* @return this
*/
Matrix4f unprojectInvRay(Vector2fc winCoords, int[] viewport, Vector3f originDest, Vector3f dirDest);
/**
* Unproject the given 2D window coordinates (winX, winY)
by this
matrix using the specified viewport
* and compute the origin and the direction of the resulting ray which starts at NDC z = -1.0
and goes through NDC z = +1.0
.
*
* This method differs from {@link #unprojectRay(float, float, int[], Vector3f, Vector3f) unprojectRay()}
* in that it assumes that this
is already the inverse matrix of the original projection matrix.
* It exists to avoid recomputing the matrix inverse with every invocation.
*
* @see #unprojectRay(float, float, int[], Vector3f, Vector3f)
*
* @param winX
* the x-coordinate in window coordinates (pixels)
* @param winY
* the y-coordinate in window coordinates (pixels)
* @param viewport
* the viewport described by [x, y, width, height]
* @param originDest
* will hold the ray origin
* @param dirDest
* will hold the (unnormalized) ray direction
* @return this
*/
Matrix4f unprojectInvRay(float winX, float winY, int[] viewport, Vector3f originDest, Vector3f dirDest);
/**
* Unproject the given window coordinates winCoords
by this
matrix using the specified viewport.
*
* This method differs from {@link #unproject(Vector3fc, int[], Vector3f) unproject()}
* in that it assumes that this
is already the inverse matrix of the original projection matrix.
* It exists to avoid recomputing the matrix inverse with every invocation.
*
* The depth range of winCoords.z
is assumed to be [0..1]
, which is also the OpenGL default.
*
* @see #unproject(Vector3fc, int[], Vector3f)
*
* @param winCoords
* the window coordinates to unproject
* @param viewport
* the viewport described by [x, y, width, height]
* @param dest
* will hold the unprojected position
* @return dest
*/
Vector3f unprojectInv(Vector3fc winCoords, int[] viewport, Vector3f dest);
/**
* Unproject the given window coordinates (winX, winY, winZ)
by this
matrix using the specified viewport.
*
* This method differs from {@link #unproject(float, float, float, int[], Vector3f) unproject()}
* in that it assumes that this
is already the inverse matrix of the original projection matrix.
* It exists to avoid recomputing the matrix inverse with every invocation.
*
* The depth range of winZ
is assumed to be [0..1]
, which is also the OpenGL default.
*
* @see #unproject(float, float, float, int[], Vector3f)
*
* @param winX
* the x-coordinate in window coordinates (pixels)
* @param winY
* the y-coordinate in window coordinates (pixels)
* @param winZ
* the z-coordinate, which is the depth value in [0..1]
* @param viewport
* the viewport described by [x, y, width, height]
* @param dest
* will hold the unprojected position
* @return dest
*/
Vector3f unprojectInv(float winX, float winY, float winZ, int[] viewport, Vector3f dest);
/**
* Project the given (x, y, z)
position via this
matrix using the specified viewport
* and store the resulting window coordinates in winCoordsDest
.
*
* This method transforms the given coordinates by this
matrix including perspective division to
* obtain normalized device coordinates, and then translates these into window coordinates by using the
* given viewport
settings [x, y, width, height]
.
*
* The depth range of the returned winCoordsDest.z
will be [0..1]
, which is also the OpenGL default.
*
* @param x
* the x-coordinate of the position to project
* @param y
* the y-coordinate of the position to project
* @param z
* the z-coordinate of the position to project
* @param viewport
* the viewport described by [x, y, width, height]
* @param winCoordsDest
* will hold the projected window coordinates
* @return winCoordsDest
*/
Vector4f project(float x, float y, float z, int[] viewport, Vector4f winCoordsDest);
/**
* Project the given (x, y, z)
position via this
matrix using the specified viewport
* and store the resulting window coordinates in winCoordsDest
.
*
* This method transforms the given coordinates by this
matrix including perspective division to
* obtain normalized device coordinates, and then translates these into window coordinates by using the
* given viewport
settings [x, y, width, height]
.
*
* The depth range of the returned winCoordsDest.z
will be [0..1]
, which is also the OpenGL default.
*
* @param x
* the x-coordinate of the position to project
* @param y
* the y-coordinate of the position to project
* @param z
* the z-coordinate of the position to project
* @param viewport
* the viewport described by [x, y, width, height]
* @param winCoordsDest
* will hold the projected window coordinates
* @return winCoordsDest
*/
Vector3f project(float x, float y, float z, int[] viewport, Vector3f winCoordsDest);
/**
* Project the given position
via this
matrix using the specified viewport
* and store the resulting window coordinates in winCoordsDest
.
*
* This method transforms the given coordinates by this
matrix including perspective division to
* obtain normalized device coordinates, and then translates these into window coordinates by using the
* given viewport
settings [x, y, width, height]
.
*
* The depth range of the returned winCoordsDest.z
will be [0..1]
, which is also the OpenGL default.
*
* @see #project(float, float, float, int[], Vector4f)
*
* @param position
* the position to project into window coordinates
* @param viewport
* the viewport described by [x, y, width, height]
* @param winCoordsDest
* will hold the projected window coordinates
* @return winCoordsDest
*/
Vector4f project(Vector3fc position, int[] viewport, Vector4f winCoordsDest);
/**
* Project the given position
via this
matrix using the specified viewport
* and store the resulting window coordinates in winCoordsDest
.
*
* This method transforms the given coordinates by this
matrix including perspective division to
* obtain normalized device coordinates, and then translates these into window coordinates by using the
* given viewport
settings [x, y, width, height]
.
*
* The depth range of the returned winCoordsDest.z
will be [0..1]
, which is also the OpenGL default.
*
* @see #project(float, float, float, int[], Vector4f)
*
* @param position
* the position to project into window coordinates
* @param viewport
* the viewport described by [x, y, width, height]
* @param winCoordsDest
* will hold the projected window coordinates
* @return winCoordsDest
*/
Vector3f project(Vector3fc position, int[] viewport, Vector3f winCoordsDest);
/**
* Apply a mirror/reflection transformation to this matrix that reflects about the given plane
* specified via the equation x*a + y*b + z*c + d = 0
and store the result in dest
.
*
* The vector (a, b, c)
must be a unit vector.
*
* If M
is this
matrix and R
the reflection matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* reflection will be applied first!
*
* Reference: msdn.microsoft.com
*
* @param a
* the x factor in the plane equation
* @param b
* the y factor in the plane equation
* @param c
* the z factor in the plane equation
* @param d
* the constant in the plane equation
* @param dest
* will hold the result
* @return dest
*/
Matrix4f reflect(float a, float b, float c, float d, Matrix4f dest);
/**
* Apply a mirror/reflection transformation to this matrix that reflects about the given plane
* specified via the plane normal and a point on the plane, and store the result in dest
.
*
* If M
is this
matrix and R
the reflection matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* reflection will be applied first!
*
* @param nx
* the x-coordinate of the plane normal
* @param ny
* the y-coordinate of the plane normal
* @param nz
* the z-coordinate of the plane normal
* @param px
* the x-coordinate of a point on the plane
* @param py
* the y-coordinate of a point on the plane
* @param pz
* the z-coordinate of a point on the plane
* @param dest
* will hold the result
* @return dest
*/
Matrix4f reflect(float nx, float ny, float nz, float px, float py, float pz, Matrix4f dest);
/**
* Apply a mirror/reflection transformation to this matrix that reflects about a plane
* specified via the plane orientation and a point on the plane, and store the result in dest
.
*
* This method can be used to build a reflection transformation based on the orientation of a mirror object in the scene.
* It is assumed that the default mirror plane's normal is (0, 0, 1)
. So, if the given {@link Quaternionfc} is
* the identity (does not apply any additional rotation), the reflection plane will be z=0
, offset by the given point
.
*
* If M
is this
matrix and R
the reflection matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* reflection will be applied first!
*
* @param orientation
* the plane orientation relative to an implied normal vector of (0, 0, 1)
* @param point
* a point on the plane
* @param dest
* will hold the result
* @return dest
*/
Matrix4f reflect(Quaternionfc orientation, Vector3fc point, Matrix4f dest);
/**
* Apply a mirror/reflection transformation to this matrix that reflects about the given plane
* specified via the plane normal and a point on the plane, and store the result in dest
.
*
* If M
is this
matrix and R
the reflection matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* reflection will be applied first!
*
* @param normal
* the plane normal
* @param point
* a point on the plane
* @param dest
* will hold the result
* @return dest
*/
Matrix4f reflect(Vector3fc normal, Vector3fc point, Matrix4f dest);
/**
* Get the row at the given row
index, starting with 0
.
*
* @param row
* the row index in [0..3]
* @param dest
* will hold the row components
* @return the passed in destination
* @throws IndexOutOfBoundsException if row
is not in [0..3]
*/
Vector4f getRow(int row, Vector4f dest) throws IndexOutOfBoundsException;
/**
* Get the first three components of the row at the given row
index, starting with 0
.
*
* @param row
* the row index in [0..3]
* @param dest
* will hold the first three row components
* @return the passed in destination
* @throws IndexOutOfBoundsException if row
is not in [0..3]
*/
Vector3f getRow(int row, Vector3f dest) throws IndexOutOfBoundsException;
/**
* Get the column at the given column
index, starting with 0
.
*
* @param column
* the column index in [0..3]
* @param dest
* will hold the column components
* @return the passed in destination
* @throws IndexOutOfBoundsException if column
is not in [0..3]
*/
Vector4f getColumn(int column, Vector4f dest) throws IndexOutOfBoundsException;
/**
* Get the first three components of the column at the given column
index, starting with 0
.
*
* @param column
* the column index in [0..3]
* @param dest
* will hold the first three column components
* @return the passed in destination
* @throws IndexOutOfBoundsException if column
is not in [0..3]
*/
Vector3f getColumn(int column, Vector3f dest) throws IndexOutOfBoundsException;
/**
* Compute a normal matrix from the upper left 3x3 submatrix of this
* and store it into the upper left 3x3 submatrix of dest
.
* All other values of dest
will be set to identity.
*
* The normal matrix of m
is the transpose of the inverse of m
.
*
* @param dest
* will hold the result
* @return dest
*/
Matrix4f normal(Matrix4f dest);
/**
* Compute a normal matrix from the upper left 3x3 submatrix of this
* and store it into dest
.
*
* The normal matrix of m
is the transpose of the inverse of m
.
*
* @see Matrix3f#set(Matrix4fc)
* @see #get3x3(Matrix3f)
*
* @param dest
* will hold the result
* @return dest
*/
Matrix3f normal(Matrix3f dest);
/**
* Compute the cofactor matrix of the upper left 3x3 submatrix of this
* and store it into dest
.
*
* The cofactor matrix can be used instead of {@link #normal(Matrix3f)} to transform normals
* when the orientation of the normals with respect to the surface should be preserved.
*
* @param dest
* will hold the result
* @return dest
*/
Matrix3f cofactor3x3(Matrix3f dest);
/**
* Compute the cofactor matrix of the upper left 3x3 submatrix of this
* and store it into dest
.
* All other values of dest
will be set to identity.
*
* The cofactor matrix can be used instead of {@link #normal(Matrix4f)} to transform normals
* when the orientation of the normals with respect to the surface should be preserved.
*
* @param dest
* will hold the result
* @return dest
*/
Matrix4f cofactor3x3(Matrix4f dest);
/**
* Normalize the upper left 3x3 submatrix of this matrix and store the result in dest
.
*
* The resulting matrix will map unit vectors to unit vectors, though a pair of orthogonal input unit
* vectors need not be mapped to a pair of orthogonal output vectors if the original matrix was not orthogonal itself
* (i.e. had skewing).
*
* @param dest
* will hold the result
* @return dest
*/
Matrix4f normalize3x3(Matrix4f dest);
/**
* Normalize the upper left 3x3 submatrix of this matrix and store the result in dest
.
*
* The resulting matrix will map unit vectors to unit vectors, though a pair of orthogonal input unit
* vectors need not be mapped to a pair of orthogonal output vectors if the original matrix was not orthogonal itself
* (i.e. had skewing).
*
* @param dest
* will hold the result
* @return dest
*/
Matrix3f normalize3x3(Matrix3f dest);
/**
* Calculate a frustum plane of this
matrix, which
* can be a projection matrix or a combined modelview-projection matrix, and store the result
* in the given planeEquation
.
*
* Generally, this method computes the frustum plane in the local frame of
* any coordinate system that existed before this
* transformation was applied to it in order to yield homogeneous clipping space.
*
* The frustum plane will be given in the form of a general plane equation:
* a*x + b*y + c*z + d = 0
, where the given {@link Vector4f} components will
* hold the (a, b, c, d)
values of the equation.
*
* The plane normal, which is (a, b, c)
, is directed "inwards" of the frustum.
* Any plane/point test using a*x + b*y + c*z + d
therefore will yield a result greater than zero
* if the point is within the frustum (i.e. at the positive side of the frustum plane).
*
* For performing frustum culling, the class {@link FrustumIntersection} should be used instead of
* manually obtaining the frustum planes and testing them against points, spheres or axis-aligned boxes.
*
* Reference:
* Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
*
* @param plane
* one of the six possible planes, given as numeric constants
* {@link #PLANE_NX}, {@link #PLANE_PX},
* {@link #PLANE_NY}, {@link #PLANE_PY},
* {@link #PLANE_NZ} and {@link #PLANE_PZ}
* @param planeEquation
* will hold the computed plane equation.
* The plane equation will be normalized, meaning that (a, b, c)
will be a unit vector
* @return planeEquation
*/
Vector4f frustumPlane(int plane, Vector4f planeEquation);
/**
* Calculate a frustum plane of this
matrix, which
* can be a projection matrix or a combined modelview-projection matrix, and store the result
* in the given plane
.
*
* Generally, this method computes the frustum plane in the local frame of
* any coordinate system that existed before this
* transformation was applied to it in order to yield homogeneous clipping space.
*
* The plane normal, which is (a, b, c)
, is directed "inwards" of the frustum.
* Any plane/point test using a*x + b*y + c*z + d
therefore will yield a result greater than zero
* if the point is within the frustum (i.e. at the positive side of the frustum plane).
*
* For performing frustum culling, the class {@link FrustumIntersection} should be used instead of
* manually obtaining the frustum planes and testing them against points, spheres or axis-aligned boxes.
*
* Reference:
* Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
*
* @param which
* one of the six possible planes, given as numeric constants
* {@link #PLANE_NX}, {@link #PLANE_PX},
* {@link #PLANE_NY}, {@link #PLANE_PY},
* {@link #PLANE_NZ} and {@link #PLANE_PZ}
* @param plane
* will hold the computed plane equation.
* The plane equation will be normalized, meaning that (a, b, c)
will be a unit vector
* @return planeEquation
*/
Planef frustumPlane(int which, Planef plane);
/**
* Compute the corner coordinates of the frustum defined by this
matrix, which
* can be a projection matrix or a combined modelview-projection matrix, and store the result
* in the given point
.
*
* Generally, this method computes the frustum corners in the local frame of
* any coordinate system that existed before this
* transformation was applied to it in order to yield homogeneous clipping space.
*
* Reference: http://geomalgorithms.com
*
* Reference:
* Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
*
* @param corner
* one of the eight possible corners, given as numeric constants
* {@link #CORNER_NXNYNZ}, {@link #CORNER_PXNYNZ}, {@link #CORNER_PXPYNZ}, {@link #CORNER_NXPYNZ},
* {@link #CORNER_PXNYPZ}, {@link #CORNER_NXNYPZ}, {@link #CORNER_NXPYPZ}, {@link #CORNER_PXPYPZ}
* @param point
* will hold the resulting corner point coordinates
* @return point
*/
Vector3f frustumCorner(int corner, Vector3f point);
/**
* Compute the eye/origin of the perspective frustum transformation defined by this
matrix,
* which can be a projection matrix or a combined modelview-projection matrix, and store the result
* in the given origin
.
*
* Note that this method will only work using perspective projections obtained via one of the
* perspective methods, such as {@link #perspective(float, float, float, float, Matrix4f) perspective()}
* or {@link #frustum(float, float, float, float, float, float, Matrix4f) frustum()}.
*
* Generally, this method computes the origin in the local frame of
* any coordinate system that existed before this
* transformation was applied to it in order to yield homogeneous clipping space.
*
* This method is equivalent to calling: invert(new Matrix4f()).transformProject(0, 0, -1, 0, origin)
* and in the case of an already available inverse of this
matrix, the method {@link #perspectiveInvOrigin(Vector3f)}
* on the inverse of the matrix should be used instead.
*
* Reference: http://geomalgorithms.com
*
* Reference:
* Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
*
* @param origin
* will hold the origin of the coordinate system before applying this
* perspective projection transformation
* @return origin
*/
Vector3f perspectiveOrigin(Vector3f origin);
/**
* Compute the eye/origin of the inverse of the perspective frustum transformation defined by this
matrix,
* which can be the inverse of a projection matrix or the inverse of a combined modelview-projection matrix, and store the result
* in the given dest
.
*
* Note that this method will only work using perspective projections obtained via one of the
* perspective methods, such as {@link #perspective(float, float, float, float, Matrix4f) perspective()}
* or {@link #frustum(float, float, float, float, float, float, Matrix4f) frustum()}.
*
* If the inverse of the modelview-projection matrix is not available, then calling {@link #perspectiveOrigin(Vector3f)}
* on the original modelview-projection matrix is preferred.
*
* @see #perspectiveOrigin(Vector3f)
*
* @param dest
* will hold the result
* @return dest
*/
Vector3f perspectiveInvOrigin(Vector3f dest);
/**
* Return the vertical field-of-view angle in radians of this perspective transformation matrix.
*
* Note that this method will only work using perspective projections obtained via one of the
* perspective methods, such as {@link #perspective(float, float, float, float, Matrix4f) perspective()}
* or {@link #frustum(float, float, float, float, float, float, Matrix4f) frustum()}.
*
* For orthogonal transformations this method will return 0.0
.
*
* Reference:
* Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
*
* @return the vertical field-of-view angle in radians
*/
float perspectiveFov();
/**
* Extract the near clip plane distance from this
perspective projection matrix.
*
* This method only works if this
is a perspective projection matrix, for example obtained via {@link #perspective(float, float, float, float, Matrix4f)}.
*
* @return the near clip plane distance
*/
float perspectiveNear();
/**
* Extract the far clip plane distance from this
perspective projection matrix.
*
* This method only works if this
is a perspective projection matrix, for example obtained via {@link #perspective(float, float, float, float, Matrix4f)}.
*
* @return the far clip plane distance
*/
float perspectiveFar();
/**
* Obtain the direction of a ray starting at the center of the coordinate system and going
* through the near frustum plane.
*
* This method computes the dir
vector in the local frame of
* any coordinate system that existed before this
* transformation was applied to it in order to yield homogeneous clipping space.
*
* The parameters x
and y
are used to interpolate the generated ray direction
* from the bottom-left to the top-right frustum corners.
*
* For optimal efficiency when building many ray directions over the whole frustum,
* it is recommended to use this method only in order to compute the four corner rays at
* (0, 0)
, (1, 0)
, (0, 1)
and (1, 1)
* and then bilinearly interpolating between them; or to use the {@link FrustumRayBuilder}.
*
* Reference:
* Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
*
* @param x
* the interpolation factor along the left-to-right frustum planes, within [0..1]
* @param y
* the interpolation factor along the bottom-to-top frustum planes, within [0..1]
* @param dir
* will hold the normalized ray direction in the local frame of the coordinate system before
* transforming to homogeneous clipping space using this
matrix
* @return dir
*/
Vector3f frustumRayDir(float x, float y, Vector3f dir);
/**
* Obtain the direction of +Z
before the transformation represented by this
matrix is applied.
*
* This method uses the rotation component of the upper left 3x3 submatrix to obtain the direction
* that is transformed to +Z
by this
matrix.
*
* This method is equivalent to the following code:
*
* Matrix4f inv = new Matrix4f(this).invert();
* inv.transformDirection(dir.set(0, 0, 1)).normalize();
*
* If this
is already an orthogonal matrix, then consider using {@link #normalizedPositiveZ(Vector3f)} instead.
*
* Reference: http://www.euclideanspace.com
*
* @param dir
* will hold the direction of +Z
* @return dir
*/
Vector3f positiveZ(Vector3f dir);
/**
* Obtain the direction of +Z
before the transformation represented by this
orthogonal matrix is applied.
* This method only produces correct results if this
is an orthogonal matrix.
*
* This method uses the rotation component of the upper left 3x3 submatrix to obtain the direction
* that is transformed to +Z
by this
matrix.
*
* This method is equivalent to the following code:
*
* Matrix4f inv = new Matrix4f(this).transpose();
* inv.transformDirection(dir.set(0, 0, 1));
*
*
* Reference: http://www.euclideanspace.com
*
* @param dir
* will hold the direction of +Z
* @return dir
*/
Vector3f normalizedPositiveZ(Vector3f dir);
/**
* Obtain the direction of +X
before the transformation represented by this
matrix is applied.
*
* This method uses the rotation component of the upper left 3x3 submatrix to obtain the direction
* that is transformed to +X
by this
matrix.
*
* This method is equivalent to the following code:
*
* Matrix4f inv = new Matrix4f(this).invert();
* inv.transformDirection(dir.set(1, 0, 0)).normalize();
*
* If this
is already an orthogonal matrix, then consider using {@link #normalizedPositiveX(Vector3f)} instead.
*
* Reference: http://www.euclideanspace.com
*
* @param dir
* will hold the direction of +X
* @return dir
*/
Vector3f positiveX(Vector3f dir);
/**
* Obtain the direction of +X
before the transformation represented by this
orthogonal matrix is applied.
* This method only produces correct results if this
is an orthogonal matrix.
*
* This method uses the rotation component of the upper left 3x3 submatrix to obtain the direction
* that is transformed to +X
by this
matrix.
*
* This method is equivalent to the following code:
*
* Matrix4f inv = new Matrix4f(this).transpose();
* inv.transformDirection(dir.set(1, 0, 0));
*
*
* Reference: http://www.euclideanspace.com
*
* @param dir
* will hold the direction of +X
* @return dir
*/
Vector3f normalizedPositiveX(Vector3f dir);
/**
* Obtain the direction of +Y
before the transformation represented by this
matrix is applied.
*
* This method uses the rotation component of the upper left 3x3 submatrix to obtain the direction
* that is transformed to +Y
by this
matrix.
*
* This method is equivalent to the following code:
*
* Matrix4f inv = new Matrix4f(this).invert();
* inv.transformDirection(dir.set(0, 1, 0)).normalize();
*
* If this
is already an orthogonal matrix, then consider using {@link #normalizedPositiveY(Vector3f)} instead.
*
* Reference: http://www.euclideanspace.com
*
* @param dir
* will hold the direction of +Y
* @return dir
*/
Vector3f positiveY(Vector3f dir);
/**
* Obtain the direction of +Y
before the transformation represented by this
orthogonal matrix is applied.
* This method only produces correct results if this
is an orthogonal matrix.
*
* This method uses the rotation component of the upper left 3x3 submatrix to obtain the direction
* that is transformed to +Y
by this
matrix.
*
* This method is equivalent to the following code:
*
* Matrix4f inv = new Matrix4f(this).transpose();
* inv.transformDirection(dir.set(0, 1, 0));
*
*
* Reference: http://www.euclideanspace.com
*
* @param dir
* will hold the direction of +Y
* @return dir
*/
Vector3f normalizedPositiveY(Vector3f dir);
/**
* Obtain the position that gets transformed to the origin by this
{@link #isAffine() affine} matrix.
* This can be used to get the position of the "camera" from a given view transformation matrix.
*
* This method only works with {@link #isAffine() affine} matrices.
*
* This method is equivalent to the following code:
*
* Matrix4f inv = new Matrix4f(this).invertAffine();
* inv.transformPosition(origin.set(0, 0, 0));
*
*
* @param origin
* will hold the position transformed to the origin
* @return origin
*/
Vector3f originAffine(Vector3f origin);
/**
* Obtain the position that gets transformed to the origin by this
matrix.
* This can be used to get the position of the "camera" from a given view/projection transformation matrix.
*
* This method is equivalent to the following code:
*
* Matrix4f inv = new Matrix4f(this).invert();
* inv.transformPosition(origin.set(0, 0, 0));
*
*
* @param origin
* will hold the position transformed to the origin
* @return origin
*/
Vector3f origin(Vector3f origin);
/**
* Apply a projection transformation to this matrix that projects onto the plane specified via the general plane equation
* x*a + y*b + z*c + d = 0
as if casting a shadow from a given light position/direction light
* and store the result in dest
.
*
* If light.w
is 0.0
the light is being treated as a directional light; if it is 1.0
it is a point light.
*
* If M
is this
matrix and S
the shadow matrix,
* then the new matrix will be M * S
. So when transforming a
* vector v
with the new matrix by using M * S * v
, the
* reflection will be applied first!
*
* Reference: ftp.sgi.com
*
* @param light
* the light's vector
* @param a
* the x factor in the plane equation
* @param b
* the y factor in the plane equation
* @param c
* the z factor in the plane equation
* @param d
* the constant in the plane equation
* @param dest
* will hold the result
* @return dest
*/
Matrix4f shadow(Vector4f light, float a, float b, float c, float d, Matrix4f dest);
/**
* Apply a projection transformation to this matrix that projects onto the plane specified via the general plane equation
* x*a + y*b + z*c + d = 0
as if casting a shadow from a given light position/direction (lightX, lightY, lightZ, lightW)
* and store the result in dest
.
*
* If lightW
is 0.0
the light is being treated as a directional light; if it is 1.0
it is a point light.
*
* If M
is this
matrix and S
the shadow matrix,
* then the new matrix will be M * S
. So when transforming a
* vector v
with the new matrix by using M * S * v
, the
* reflection will be applied first!
*
* Reference: ftp.sgi.com
*
* @param lightX
* the x-component of the light's vector
* @param lightY
* the y-component of the light's vector
* @param lightZ
* the z-component of the light's vector
* @param lightW
* the w-component of the light's vector
* @param a
* the x factor in the plane equation
* @param b
* the y factor in the plane equation
* @param c
* the z factor in the plane equation
* @param d
* the constant in the plane equation
* @param dest
* will hold the result
* @return dest
*/
Matrix4f shadow(float lightX, float lightY, float lightZ, float lightW, float a, float b, float c, float d, Matrix4f dest);
/**
* Apply a projection transformation to this matrix that projects onto the plane with the general plane equation
* y = 0
as if casting a shadow from a given light position/direction light
* and store the result in dest
.
*
* Before the shadow projection is applied, the plane is transformed via the specified planeTransformation
.
*
* If light.w
is 0.0
the light is being treated as a directional light; if it is 1.0
it is a point light.
*
* If M
is this
matrix and S
the shadow matrix,
* then the new matrix will be M * S
. So when transforming a
* vector v
with the new matrix by using M * S * v
, the
* reflection will be applied first!
*
* @param light
* the light's vector
* @param planeTransform
* the transformation to transform the implied plane y = 0
before applying the projection
* @param dest
* will hold the result
* @return dest
*/
Matrix4f shadow(Vector4f light, Matrix4fc planeTransform, Matrix4f dest);
/**
* Apply a projection transformation to this matrix that projects onto the plane with the general plane equation
* y = 0
as if casting a shadow from a given light position/direction (lightX, lightY, lightZ, lightW)
* and store the result in dest
.
*
* Before the shadow projection is applied, the plane is transformed via the specified planeTransformation
.
*
* If lightW
is 0.0
the light is being treated as a directional light; if it is 1.0
it is a point light.
*
* If M
is this
matrix and S
the shadow matrix,
* then the new matrix will be M * S
. So when transforming a
* vector v
with the new matrix by using M * S * v
, the
* reflection will be applied first!
*
* @param lightX
* the x-component of the light vector
* @param lightY
* the y-component of the light vector
* @param lightZ
* the z-component of the light vector
* @param lightW
* the w-component of the light vector
* @param planeTransform
* the transformation to transform the implied plane y = 0
before applying the projection
* @param dest
* will hold the result
* @return dest
*/
Matrix4f shadow(float lightX, float lightY, float lightZ, float lightW, Matrix4fc planeTransform, Matrix4f dest);
/**
* Apply a picking transformation to this matrix using the given window coordinates (x, y)
as the pick center
* and the given (width, height)
as the size of the picking region in window coordinates, and store the result
* in dest
.
*
* @param x
* the x coordinate of the picking region center in window coordinates
* @param y
* the y coordinate of the picking region center in window coordinates
* @param width
* the width of the picking region in window coordinates
* @param height
* the height of the picking region in window coordinates
* @param viewport
* the viewport described by [x, y, width, height]
* @param dest
* the destination matrix, which will hold the result
* @return dest
*/
Matrix4f pick(float x, float y, float width, float height, int[] viewport, Matrix4f dest);
/**
* Determine whether this matrix describes an affine transformation. This is the case iff its last row is equal to (0, 0, 0, 1)
.
*
* @return true
iff this matrix is affine; false
otherwise
*/
boolean isAffine();
/**
* Apply an arcball view transformation to this matrix with the given radius
and center (centerX, centerY, centerZ)
* position of the arcball and the specified X and Y rotation angles, and store the result in dest
.
*
* This method is equivalent to calling: translate(0, 0, -radius).rotateX(angleX).rotateY(angleY).translate(-centerX, -centerY, -centerZ)
*
* @param radius
* the arcball radius
* @param centerX
* the x coordinate of the center position of the arcball
* @param centerY
* the y coordinate of the center position of the arcball
* @param centerZ
* the z coordinate of the center position of the arcball
* @param angleX
* the rotation angle around the X axis in radians
* @param angleY
* the rotation angle around the Y axis in radians
* @param dest
* will hold the result
* @return dest
*/
Matrix4f arcball(float radius, float centerX, float centerY, float centerZ, float angleX, float angleY, Matrix4f dest);
/**
* Apply an arcball view transformation to this matrix with the given radius
and center
* position of the arcball and the specified X and Y rotation angles, and store the result in dest
.
*
* This method is equivalent to calling: translate(0, 0, -radius).rotateX(angleX).rotateY(angleY).translate(-center.x, -center.y, -center.z)
*
* @param radius
* the arcball radius
* @param center
* the center position of the arcball
* @param angleX
* the rotation angle around the X axis in radians
* @param angleY
* the rotation angle around the Y axis in radians
* @param dest
* will hold the result
* @return dest
*/
Matrix4f arcball(float radius, Vector3fc center, float angleX, float angleY, Matrix4f dest);
/**
* Compute the axis-aligned bounding box of the frustum described by this
matrix and store the minimum corner
* coordinates in the given min
and the maximum corner coordinates in the given max
vector.
*
* The matrix this
is assumed to be the {@link #invert(Matrix4f) inverse} of the origial view-projection matrix
* for which to compute the axis-aligned bounding box in world-space.
*
* The axis-aligned bounding box of the unit frustum is (-1, -1, -1)
, (1, 1, 1)
.
*
* @param min
* will hold the minimum corner coordinates of the axis-aligned bounding box
* @param max
* will hold the maximum corner coordinates of the axis-aligned bounding box
* @return this
*/
Matrix4f frustumAabb(Vector3f min, Vector3f max);
/**
* Compute the range matrix for the Projected Grid transformation as described in chapter "2.4.2 Creating the range conversion matrix"
* of the paper Real-time water rendering - Introducing the projected grid concept
* based on the inverse of the view-projection matrix which is assumed to be this
, and store that range matrix into dest
.
*
* If the projected grid will not be visible then this method returns null
.
*
* This method uses the y = 0
plane for the projection.
*
* @param projector
* the projector view-projection transformation
* @param sLower
* the lower (smallest) Y-coordinate which any transformed vertex might have while still being visible on the projected grid
* @param sUpper
* the upper (highest) Y-coordinate which any transformed vertex might have while still being visible on the projected grid
* @param dest
* will hold the resulting range matrix
* @return the computed range matrix; or null
if the projected grid will not be visible
*/
Matrix4f projectedGridRange(Matrix4fc projector, float sLower, float sUpper, Matrix4f dest);
/**
* Change the near and far clip plane distances of this
perspective frustum transformation matrix
* and store the result in dest
.
*
* This method only works if this
is a perspective projection frustum transformation, for example obtained
* via {@link #perspective(float, float, float, float, Matrix4f) perspective()} or {@link #frustum(float, float, float, float, float, float, Matrix4f) frustum()}.
*
* @see #perspective(float, float, float, float, Matrix4f)
* @see #frustum(float, float, float, float, float, float, Matrix4f)
*
* @param near
* the new near clip plane distance
* @param far
* the new far clip plane distance
* @param dest
* will hold the resulting matrix
* @return dest
*/
Matrix4f perspectiveFrustumSlice(float near, float far, Matrix4f dest);
/**
* Build an ortographic projection transformation that fits the view-projection transformation represented by this
* into the given affine view
transformation.
*
* The transformation represented by this
must be given as the {@link #invert(Matrix4f) inverse} of a typical combined camera view-projection
* transformation, whose projection can be either orthographic or perspective.
*
* The view
must be an {@link #isAffine() affine} transformation which in the application of Cascaded Shadow Maps is usually the light view transformation.
* It be obtained via any affine transformation or for example via {@link #lookAt(float, float, float, float, float, float, float, float, float, Matrix4f) lookAt()}.
*
* Reference: OpenGL SDK - Cascaded Shadow Maps
*
* @param view
* the view transformation to build a corresponding orthographic projection to fit the frustum of this
* @param dest
* will hold the crop projection transformation
* @return dest
*/
Matrix4f orthoCrop(Matrix4fc view, Matrix4f dest);
/**
* Transform the axis-aligned box given as the minimum corner (minX, minY, minZ)
and maximum corner (maxX, maxY, maxZ)
* by this
{@link #isAffine() affine} matrix and compute the axis-aligned box of the result whose minimum corner is stored in outMin
* and maximum corner stored in outMax
.
*
* Reference: http://dev.theomader.com
*
* @param minX
* the x coordinate of the minimum corner of the axis-aligned box
* @param minY
* the y coordinate of the minimum corner of the axis-aligned box
* @param minZ
* the z coordinate of the minimum corner of the axis-aligned box
* @param maxX
* the x coordinate of the maximum corner of the axis-aligned box
* @param maxY
* the y coordinate of the maximum corner of the axis-aligned box
* @param maxZ
* the y coordinate of the maximum corner of the axis-aligned box
* @param outMin
* will hold the minimum corner of the resulting axis-aligned box
* @param outMax
* will hold the maximum corner of the resulting axis-aligned box
* @return this
*/
Matrix4f transformAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ, Vector3f outMin, Vector3f outMax);
/**
* Transform the axis-aligned box given as the minimum corner min
and maximum corner max
* by this
{@link #isAffine() affine} matrix and compute the axis-aligned box of the result whose minimum corner is stored in outMin
* and maximum corner stored in outMax
.
*
* @param min
* the minimum corner of the axis-aligned box
* @param max
* the maximum corner of the axis-aligned box
* @param outMin
* will hold the minimum corner of the resulting axis-aligned box
* @param outMax
* will hold the maximum corner of the resulting axis-aligned box
* @return this
*/
Matrix4f transformAab(Vector3fc min, Vector3fc max, Vector3f outMin, Vector3f outMax);
/**
* Linearly interpolate this
and other
using the given interpolation factor t
* and store the result in dest
.
*
* If t
is 0.0
then the result is this
. If the interpolation factor is 1.0
* then the result is other
.
*
* @param other
* the other matrix
* @param t
* the interpolation factor between 0.0 and 1.0
* @param dest
* will hold the result
* @return dest
*/
Matrix4f lerp(Matrix4fc other, float t, Matrix4f dest);
/**
* Apply a model transformation to this matrix for a right-handed coordinate system,
* that aligns the local +Z
axis with dir
* and store the result in dest
.
*
* If M
is this
matrix and L
the lookat matrix,
* then the new matrix will be M * L
. So when transforming a
* vector v
with the new matrix by using M * L * v
,
* the lookat transformation will be applied first!
*
* This method is equivalent to calling: mulAffine(new Matrix4f().lookAt(new Vector3f(), new Vector3f(dir).negate(), up).invertAffine(), dest)
*
* @see #rotateTowards(float, float, float, float, float, float, Matrix4f)
*
* @param dir
* the direction to rotate towards
* @param up
* the up vector
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateTowards(Vector3fc dir, Vector3fc up, Matrix4f dest);
/**
* Apply a model transformation to this matrix for a right-handed coordinate system,
* that aligns the local +Z
axis with (dirX, dirY, dirZ)
* and store the result in dest
.
*
* If M
is this
matrix and L
the lookat matrix,
* then the new matrix will be M * L
. So when transforming a
* vector v
with the new matrix by using M * L * v
,
* the lookat transformation will be applied first!
*
* This method is equivalent to calling: mulAffine(new Matrix4f().lookAt(0, 0, 0, -dirX, -dirY, -dirZ, upX, upY, upZ).invertAffine(), dest)
*
* @see #rotateTowards(Vector3fc, Vector3fc, Matrix4f)
*
* @param dirX
* the x-coordinate of the direction to rotate towards
* @param dirY
* the y-coordinate of the direction to rotate towards
* @param dirZ
* the z-coordinate of the direction to rotate towards
* @param upX
* the x-coordinate of the up vector
* @param upY
* the y-coordinate of the up vector
* @param upZ
* the z-coordinate of the up vector
* @param dest
* will hold the result
* @return dest
*/
Matrix4f rotateTowards(float dirX, float dirY, float dirZ, float upX, float upY, float upZ, Matrix4f dest);
/**
* Extract the Euler angles from the rotation represented by the upper left 3x3 submatrix of this
* and store the extracted Euler angles in dest
.
*
* This method assumes that the upper left of this
only represents a rotation without scaling.
*
* Note that the returned Euler angles must be applied in the order Z * Y * X
to obtain the identical matrix.
* This means that calling {@link Matrix4fc#rotateZYX(float, float, float, Matrix4f)} using the obtained Euler angles will yield
* the same rotation as the original matrix from which the Euler angles were obtained, so in the below code the matrix
* m2
should be identical to m
(disregarding possible floating-point inaccuracies).
*
* Matrix4f m = ...; // <- matrix only representing rotation
* Matrix4f n = new Matrix4f();
* n.rotateZYX(m.getEulerAnglesZYX(new Vector3f()));
*
*
* Reference: http://nghiaho.com/
*
* @param dest
* will hold the extracted Euler angles
* @return dest
*/
Vector3f getEulerAnglesZYX(Vector3f dest);
/**
* Test whether the given point (x, y, z)
is within the frustum defined by this
matrix.
*
* This method assumes this
matrix to be a transformation from any arbitrary coordinate system/space M
* into standard OpenGL clip space and tests whether the given point with the coordinates (x, y, z)
given
* in space M
is within the clip space.
*
* When testing multiple points using the same transformation matrix, {@link FrustumIntersection} should be used instead.
*
* Reference:
* Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
*
* @param x
* the x-coordinate of the point
* @param y
* the y-coordinate of the point
* @param z
* the z-coordinate of the point
* @return true
if the given point is inside the frustum; false
otherwise
*/
boolean testPoint(float x, float y, float z);
/**
* Test whether the given sphere is partly or completely within or outside of the frustum defined by this
matrix.
*
* This method assumes this
matrix to be a transformation from any arbitrary coordinate system/space M
* into standard OpenGL clip space and tests whether the given sphere with the coordinates (x, y, z)
given
* in space M
is within the clip space.
*
* When testing multiple spheres using the same transformation matrix, or more sophisticated/optimized intersection algorithms are required,
* {@link FrustumIntersection} should be used instead.
*
* The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
* can occur, when the method returns true
for spheres that are actually not visible.
* See iquilezles.org for an examination of this problem.
*
* Reference:
* Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
*
* @param x
* the x-coordinate of the sphere's center
* @param y
* the y-coordinate of the sphere's center
* @param z
* the z-coordinate of the sphere's center
* @param r
* the sphere's radius
* @return true
if the given sphere is partly or completely inside the frustum; false
otherwise
*/
boolean testSphere(float x, float y, float z, float r);
/**
* Test whether the given axis-aligned box is partly or completely within or outside of the frustum defined by this
matrix.
* The box is specified via its min and max corner coordinates.
*
* This method assumes this
matrix to be a transformation from any arbitrary coordinate system/space M
* into standard OpenGL clip space and tests whether the given axis-aligned box with its minimum corner coordinates (minX, minY, minZ)
* and maximum corner coordinates (maxX, maxY, maxZ)
given in space M
is within the clip space.
*
* When testing multiple axis-aligned boxes using the same transformation matrix, or more sophisticated/optimized intersection algorithms are required,
* {@link FrustumIntersection} should be used instead.
*
* The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
* can occur, when the method returns -1
for boxes that are actually not visible/do not intersect the frustum.
* See iquilezles.org for an examination of this problem.
*
* Reference: Efficient View Frustum Culling
*
* Reference:
* Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
*
* @param minX
* the x-coordinate of the minimum corner
* @param minY
* the y-coordinate of the minimum corner
* @param minZ
* the z-coordinate of the minimum corner
* @param maxX
* the x-coordinate of the maximum corner
* @param maxY
* the y-coordinate of the maximum corner
* @param maxZ
* the z-coordinate of the maximum corner
* @return true
if the axis-aligned box is completely or partly inside of the frustum; false
otherwise
*/
boolean testAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ);
/**
* Apply an oblique projection transformation to this matrix with the given values for a
and
* b
and store the result in dest
.
*
* If M
is this
matrix and O
the oblique transformation matrix,
* then the new matrix will be M * O
. So when transforming a
* vector v
with the new matrix by using M * O * v
, the
* oblique transformation will be applied first!
*
* The oblique transformation is defined as:
*
* x' = x + a*z
* y' = y + a*z
* z' = z
*
* or in matrix form:
*
* 1 0 a 0
* 0 1 b 0
* 0 0 1 0
* 0 0 0 1
*
*
* @param a
* the value for the z factor that applies to x
* @param b
* the value for the z factor that applies to y
* @param dest
* will hold the result
* @return dest
*/
Matrix4f obliqueZ(float a, float b, Matrix4f dest);
/**
* Apply a transformation to this matrix to ensure that the local Y axis (as obtained by {@link #positiveY(Vector3f)})
* will be coplanar to the plane spanned by the local Z axis (as obtained by {@link #positiveZ(Vector3f)}) and the
* given vector up
, and store the result in dest
.
*
* This effectively ensures that the resulting matrix will be equal to the one obtained from calling
* {@link Matrix4f#setLookAt(Vector3fc, Vector3fc, Vector3fc)} with the current
* local origin of this matrix (as obtained by {@link #originAffine(Vector3f)}), the sum of this position and the
* negated local Z axis as well as the given vector up
.
*
* This method must only be called on {@link #isAffine()} matrices.
*
* @param up
* the up vector
* @param dest
* will hold the result
* @return this
*/
Matrix4f withLookAtUp(Vector3fc up, Matrix4f dest);
/**
* Apply a transformation to this matrix to ensure that the local Y axis (as obtained by {@link #positiveY(Vector3f)})
* will be coplanar to the plane spanned by the local Z axis (as obtained by {@link #positiveZ(Vector3f)}) and the
* given vector (upX, upY, upZ)
, and store the result in dest
.
*
* This effectively ensures that the resulting matrix will be equal to the one obtained from calling
* {@link Matrix4f#setLookAt(float, float, float, float, float, float, float, float, float)} called with the current
* local origin of this matrix (as obtained by {@link #originAffine(Vector3f)}), the sum of this position and the
* negated local Z axis as well as the given vector (upX, upY, upZ)
.
*
* This method must only be called on {@link #isAffine()} matrices.
*
* @param upX
* the x coordinate of the up vector
* @param upY
* the y coordinate of the up vector
* @param upZ
* the z coordinate of the up vector
* @param dest
* will hold the result
* @return this
*/
Matrix4f withLookAtUp(float upX, float upY, float upZ, Matrix4f dest);
/**
* Compare the matrix elements of this
matrix with the given matrix using the given delta
* and return whether all of them are equal within a maximum difference of delta
.
*
* Please note that this method is not used by any data structure such as {@link ArrayList} {@link HashSet} or {@link HashMap}
* and their operations, such as {@link ArrayList#contains(Object)} or {@link HashSet#remove(Object)}, since those
* data structures only use the {@link Object#equals(Object)} and {@link Object#hashCode()} methods.
*
* @param m
* the other matrix
* @param delta
* the allowed maximum difference
* @return true
whether all of the matrix elements are equal; false
otherwise
*/
boolean equals(Matrix4fc m, float delta);
}