All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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); }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy