/* * The MIT License * * Copyright (c) 2020-2021 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 com.jozufozu.flywheel.repack.joml; import java.nio.ByteBuffer; import java.nio.DoubleBuffer; import java.util.*; /** * Interface to a read-only view of a 2x2 matrix of double-precision floats. * * @author Joseph Burton */ public interface Matrix2dc { /** * Return the value of the matrix element at column 0 and row 0. * * @return the value of the matrix element */ double m00(); /** * Return the value of the matrix element at column 0 and row 1. * * @return the value of the matrix element */ double m01(); /** * Return the value of the matrix element at column 1 and row 0. * * @return the value of the matrix element */ double m10(); /** * Return the value of the matrix element at column 1 and row 1. * * @return the value of the matrix element */ double m11(); /** * 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 * will hold the result * @return dest */ Matrix2d mul(Matrix2dc right, Matrix2d 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 * will hold the result * @return dest */ Matrix2d mul(Matrix2fc right, Matrix2d 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 */ Matrix2d mulLocal(Matrix2dc left, Matrix2d dest); /** * Return the determinant of this matrix. * * @return the determinant */ double determinant(); /** * Invert the this matrix and store the result in dest. * * @param dest * will hold the result * @return dest */ Matrix2d invert(Matrix2d dest); /** * Transpose this matrix and store the result in dest. * * @param dest * will hold the result * @return dest */ Matrix2d transpose(Matrix2d dest); /** * Get the current values of this matrix and store them into * dest. * * @param dest * the destination matrix * @return the passed in destination */ Matrix2d get(Matrix2d dest); /** * Get the current values of this matrix and store them as * the rotational component of dest. All other values of dest will * be set to 0. * * @see Matrix3x2d#set(Matrix2dc) * * @param dest * the destination matrix * @return the passed in destination */ Matrix3x2d get(Matrix3x2d dest); /** * Get the current values of this matrix and store them as * the rotational component of dest. All other values of dest will * be set to identity. * * @see Matrix3d#set(Matrix2dc) * * @param dest * the destination matrix * @return the passed in destination */ Matrix3d get(Matrix3d dest); /** * Get the angle of the rotation component of this matrix. *

* This method assumes that there is a valid rotation to be returned, i.e. that * atan2(-m10, m00) == atan2(m01, m11). * * @return the angle */ double getRotation(); /** * Store this matrix in column-major order into the supplied {@link DoubleBuffer} at the current * buffer {@link DoubleBuffer#position() position}. *

* This method will not increment the position of the given DoubleBuffer. *

* In order to specify the offset into the DoubleBuffer at which * the matrix is stored, use {@link #get(int, DoubleBuffer)}, taking * the absolute position as parameter. * * @see #get(int, DoubleBuffer) * * @param buffer * will receive the values of this matrix in column-major order at its current position * @return the passed in buffer */ DoubleBuffer get(DoubleBuffer buffer); /** * Store this matrix in column-major order into the supplied {@link DoubleBuffer} starting at the specified * absolute buffer position/index. *

* This method will not increment the position of the given DoubleBuffer. * * @param index * the absolute position into the DoubleBuffer * @param buffer * will receive the values of this matrix in column-major order * @return the passed in buffer */ DoubleBuffer get(int index, DoubleBuffer 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 transpose of this matrix in column-major order into the supplied {@link DoubleBuffer} at the current * buffer {@link DoubleBuffer#position() position}. *

* This method will not increment the position of the given DoubleBuffer. *

* In order to specify the offset into the DoubleBuffer at which * the matrix is stored, use {@link #getTransposed(int, DoubleBuffer)}, taking * the absolute position as parameter. * * @see #getTransposed(int, DoubleBuffer) * * @param buffer * will receive the values of this matrix in column-major order at its current position * @return the passed in buffer */ DoubleBuffer getTransposed(DoubleBuffer buffer); /** * Store the transpose of this matrix in column-major order into the supplied {@link DoubleBuffer} starting at the specified * absolute buffer position/index. *

* This method will not increment the position of the given DoubleBuffer. * * @param index * the absolute position into the DoubleBuffer * @param buffer * will receive the values of this matrix in column-major order * @return the passed in buffer */ DoubleBuffer getTransposed(int index, DoubleBuffer 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 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 */ Matrix2dc getToAddress(long address); /** * Store this matrix into the supplied double 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 */ double[] get(double[] arr, int offset); /** * Store this matrix into the supplied double array in column-major order. *

* In order to specify an explicit offset into the array, use the method {@link #get(double[], int)}. * * @see #get(double[], int) * * @param arr * the array to write the matrix values into * @return the passed in array */ double[] get(double[] arr); /** * Apply scaling to this matrix by scaling the base axes by the given xy.x and * xy.y 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 xy * the factors of the x and y component, respectively * @param dest * will hold the result * @return dest */ Matrix2d scale(Vector2dc xy, Matrix2d dest); /** * Apply scaling to this matrix by scaling the base axes by the given x and * y 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 dest * will hold the result * @return dest */ Matrix2d scale(double x, double y, Matrix2d dest); /** * Apply scaling to this matrix by uniformly scaling all base axes by the given xy 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! * * @see #scale(double, double, Matrix2d) * * @param xy * the factor for all components * @param dest * will hold the result * @return dest */ Matrix2d scale(double xy, Matrix2d dest); /** * Pre-multiply scaling to this matrix by scaling the base axes by the given x and * y 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 dest * will hold the result * @return dest */ Matrix2d scaleLocal(double x, double y, Matrix2d dest); /** * Transform the given vector by this matrix. * * @param v * the vector to transform * @return v */ Vector2d transform(Vector2d v); /** * Transform the given vector by this matrix and store the result in dest. * * @param v * the vector to transform * @param dest * will hold the result * @return dest */ Vector2d transform(Vector2dc v, Vector2d dest); /** * Transform the vector (x, y) 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 dest * will hold the result * @return dest */ Vector2d transform(double x, double y, Vector2d dest); /** * Transform the given vector by the transpose of this matrix. * * @param v * the vector to transform * @return v */ Vector2d transformTranspose(Vector2d v); /** * Transform the given vector by the transpose of this matrix and store the result in dest. * * @param v * the vector to transform * @param dest * will hold the result * @return dest */ Vector2d transformTranspose(Vector2dc v, Vector2d dest); /** * Transform the vector (x, y) by the transpose of 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 dest * will hold the result * @return dest */ Vector2d transformTranspose(double x, double y, Vector2d dest); /** * Apply rotation to this matrix by rotating the given amount of radians * and store the result in dest. *

* The produced rotation will rotate a vector counter-clockwise around the origin. *

* 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 */ Matrix2d rotate(double ang, Matrix2d dest); /** * Pre-multiply a rotation to this matrix by rotating the given amount of radians * and store the result in dest. *

* The produced rotation will rotate a vector counter-clockwise around the origin. *

* 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 dest * will hold the result * @return dest */ Matrix2d rotateLocal(double ang, Matrix2d dest); /** * Get the row at the given row index, starting with 0. * * @param row * the row index in [0..1] * @param dest * will hold the row components * @return the passed in destination * @throws IndexOutOfBoundsException if row is not in [0..1] */ Vector2d getRow(int row, Vector2d dest) throws IndexOutOfBoundsException; /** * Get the column at the given column index, starting with 0. * * @param column * the column index in [0..1] * @param dest * will hold the column components * @return the passed in destination * @throws IndexOutOfBoundsException if column is not in [0..1] */ Vector2d getColumn(int column, Vector2d dest) throws IndexOutOfBoundsException; /** * Get the matrix element value at the given column and row. * * @param column * the colum index in [0..1] * @param row * the row index in [0..1] * @return the element value */ double get(int column, int row); /** * Compute a normal matrix from this matrix and store it into dest. * * @param dest * will hold the result * @return dest */ Matrix2d normal(Matrix2d dest); /** * Get the scaling factors of this matrix for the three base axes. * * @param dest * will hold the scaling factors for x and y * @return dest */ Vector2d getScale(Vector2d dest); /** * Obtain the direction of +X before the transformation represented by this matrix is applied. *

* This method is equivalent to the following code: *

     * Matrix2d inv = new Matrix2d(this).invert();
     * inv.transform(dir.set(1, 0)).normalize();
     * 
* If this is already an orthogonal matrix, then consider using {@link #normalizedPositiveX(Vector2d)} instead. * * @param dest * will hold the direction of +X * @return dest */ Vector2d positiveX(Vector2d dest); /** * 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 is equivalent to the following code: *

     * Matrix2d inv = new Matrix2d(this).transpose();
     * inv.transform(dir.set(1, 0));
     * 
* * @param dest * will hold the direction of +X * @return dest */ Vector2d normalizedPositiveX(Vector2d dest); /** * Obtain the direction of +Y before the transformation represented by this matrix is applied. *

* This method is equivalent to the following code: *

     * Matrix2d inv = new Matrix2d(this).invert();
     * inv.transform(dir.set(0, 1)).normalize();
     * 
* If this is already an orthogonal matrix, then consider using {@link #normalizedPositiveY(Vector2d)} instead. * * @param dest * will hold the direction of +Y * @return dest */ Vector2d positiveY(Vector2d dest); /** * 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 is equivalent to the following code: *

     * Matrix2d inv = new Matrix2d(this).transpose();
     * inv.transform(dir.set(0, 1));
     * 
* * @param dest * will hold the direction of +Y * @return dest */ Vector2d normalizedPositiveY(Vector2d 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 */ Matrix2d add(Matrix2dc other, Matrix2d 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 */ Matrix2d sub(Matrix2dc subtrahend, Matrix2d 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 */ Matrix2d mulComponentWise(Matrix2dc other, Matrix2d dest); /** * 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 */ Matrix2d lerp(Matrix2dc other, double t, Matrix2d 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(Matrix2dc m, double delta); /** * Determine whether all matrix elements are finite floating-point values, that * is, they are not {@link Double#isNaN() NaN} and not * {@link Double#isInfinite() infinity}. * * @return {@code true} if all components are finite floating-point values; * {@code false} otherwise */ boolean isFinite(); }