Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.badlogic.gdx.math;
import java.io.Serializable;
/** Encapsulates a column major 4 by 4 matrix. Like
* the {@link Vector3} class it allows the chaining of methods by returning a reference to itself. For example:
*
*
* Matrix4 mat = new Matrix4().trn(position).mul(camera.combined);
*
*
* @author [email protected] */
public class Matrix4 implements Serializable {
private static final long serialVersionUID = -2717655254359579617L;
/** XX: Typically the unrotated X component for scaling, also the cosine of the angle when rotated on the Y and/or Z axis. On
* Vector3 multiplication this value is multiplied with the source X component and added to the target X component. */
public static final int M00 = 0;
/** XY: Typically the negative sine of the angle when rotated on the Z axis. On Vector3 multiplication this value is multiplied
* with the source Y component and added to the target X component. */
public static final int M01 = 4;
/** XZ: Typically the sine of the angle when rotated on the Y axis. On Vector3 multiplication this value is multiplied with the
* source Z component and added to the target X component. */
public static final int M02 = 8;
/** XW: Typically the translation of the X component. On Vector3 multiplication this value is added to the target X component. */
public static final int M03 = 12;
/** YX: Typically the sine of the angle when rotated on the Z axis. On Vector3 multiplication this value is multiplied with the
* source X component and added to the target Y component. */
public static final int M10 = 1;
/** YY: Typically the unrotated Y component for scaling, also the cosine of the angle when rotated on the X and/or Z axis. On
* Vector3 multiplication this value is multiplied with the source Y component and added to the target Y component. */
public static final int M11 = 5;
/** YZ: Typically the negative sine of the angle when rotated on the X axis. On Vector3 multiplication this value is multiplied
* with the source Z component and added to the target Y component. */
public static final int M12 = 9;
/** YW: Typically the translation of the Y component. On Vector3 multiplication this value is added to the target Y component. */
public static final int M13 = 13;
/** ZX: Typically the negative sine of the angle when rotated on the Y axis. On Vector3 multiplication this value is multiplied
* with the source X component and added to the target Z component. */
public static final int M20 = 2;
/** ZY: Typical the sine of the angle when rotated on the X axis. On Vector3 multiplication this value is multiplied with the
* source Y component and added to the target Z component. */
public static final int M21 = 6;
/** ZZ: Typically the unrotated Z component for scaling, also the cosine of the angle when rotated on the X and/or Y axis. On
* Vector3 multiplication this value is multiplied with the source Z component and added to the target Z component. */
public static final int M22 = 10;
/** ZW: Typically the translation of the Z component. On Vector3 multiplication this value is added to the target Z component. */
public static final int M23 = 14;
/** WX: Typically the value zero. On Vector3 multiplication this value is ignored. */
public static final int M30 = 3;
/** WY: Typically the value zero. On Vector3 multiplication this value is ignored. */
public static final int M31 = 7;
/** WZ: Typically the value zero. On Vector3 multiplication this value is ignored. */
public static final int M32 = 11;
/** WW: Typically the value one. On Vector3 multiplication this value is ignored. */
public static final int M33 = 15;
static final Quaternion quat = new Quaternion();
static final Quaternion quat2 = new Quaternion();
static final Vector3 l_vez = new Vector3();
static final Vector3 l_vex = new Vector3();
static final Vector3 l_vey = new Vector3();
static final Vector3 tmpVec = new Vector3();
static final Matrix4 tmpMat = new Matrix4();
static final Vector3 right = new Vector3();
static final Vector3 tmpForward = new Vector3();
static final Vector3 tmpUp = new Vector3();
public final float val[] = new float[16];
/** Constructs an identity matrix */
public Matrix4 () {
val[M00] = 1f;
val[M11] = 1f;
val[M22] = 1f;
val[M33] = 1f;
}
/** Constructs a matrix from the given matrix.
* @param matrix The matrix to copy. (This matrix is not modified) */
public Matrix4 (Matrix4 matrix) {
set(matrix);
}
/** Constructs a matrix from the given float array. The array must have at least 16 elements; the first 16 will be copied.
* @param values The float array to copy. Remember that this matrix is in column major order. (The float array is not modified) */
public Matrix4 (float[] values) {
set(values);
}
/** Constructs a rotation matrix from the given {@link Quaternion}.
* @param quaternion The quaternion to be copied. (The quaternion is not modified) */
public Matrix4 (Quaternion quaternion) {
set(quaternion);
}
/** Construct a matrix from the given translation, rotation and scale.
* @param position The translation
* @param rotation The rotation, must be normalized
* @param scale The scale */
public Matrix4 (Vector3 position, Quaternion rotation, Vector3 scale) {
set(position, rotation, scale);
}
/** Sets the matrix to the given matrix.
* @param matrix The matrix that is to be copied. (The given matrix is not modified)
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 set (Matrix4 matrix) {
return set(matrix.val);
}
/** Sets the matrix to the given matrix as a float array. The float array must have at least 16 elements; the first 16 will be
* copied.
*
* @param values The matrix, in float form, that is to be copied. Remember that this matrix is in column major order.
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 set (float[] values) {
System.arraycopy(values, 0, val, 0, val.length);
return this;
}
/** Sets the matrix to a rotation matrix representing the quaternion.
* @param quaternion The quaternion that is to be used to set this matrix.
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 set (Quaternion quaternion) {
return set(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
}
/** Sets the matrix to a rotation matrix representing the quaternion.
*
* @param quaternionX The X component of the quaternion that is to be used to set this matrix.
* @param quaternionY The Y component of the quaternion that is to be used to set this matrix.
* @param quaternionZ The Z component of the quaternion that is to be used to set this matrix.
* @param quaternionW The W component of the quaternion that is to be used to set this matrix.
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 set (float quaternionX, float quaternionY, float quaternionZ, float quaternionW) {
return set(0f, 0f, 0f, quaternionX, quaternionY, quaternionZ, quaternionW);
}
/** Set this matrix to the specified translation and rotation.
* @param position The translation
* @param orientation The rotation, must be normalized
* @return This matrix for chaining */
public Matrix4 set (Vector3 position, Quaternion orientation) {
return set(position.x, position.y, position.z, orientation.x, orientation.y, orientation.z, orientation.w);
}
/** Sets the matrix to a rotation matrix representing the translation and quaternion.
* @param translationX The X component of the translation that is to be used to set this matrix.
* @param translationY The Y component of the translation that is to be used to set this matrix.
* @param translationZ The Z component of the translation that is to be used to set this matrix.
* @param quaternionX The X component of the quaternion that is to be used to set this matrix.
* @param quaternionY The Y component of the quaternion that is to be used to set this matrix.
* @param quaternionZ The Z component of the quaternion that is to be used to set this matrix.
* @param quaternionW The W component of the quaternion that is to be used to set this matrix.
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 set (float translationX, float translationY, float translationZ, float quaternionX, float quaternionY,
float quaternionZ, float quaternionW) {
final float xs = quaternionX * 2f, ys = quaternionY * 2f, zs = quaternionZ * 2f;
final float wx = quaternionW * xs, wy = quaternionW * ys, wz = quaternionW * zs;
final float xx = quaternionX * xs, xy = quaternionX * ys, xz = quaternionX * zs;
final float yy = quaternionY * ys, yz = quaternionY * zs, zz = quaternionZ * zs;
val[M00] = 1f - (yy + zz);
val[M01] = xy - wz;
val[M02] = xz + wy;
val[M03] = translationX;
val[M10] = xy + wz;
val[M11] = 1f - (xx + zz);
val[M12] = yz - wx;
val[M13] = translationY;
val[M20] = xz - wy;
val[M21] = yz + wx;
val[M22] = 1f - (xx + yy);
val[M23] = translationZ;
val[M30] = 0f;
val[M31] = 0f;
val[M32] = 0f;
val[M33] = 1f;
return this;
}
/** Set this matrix to the specified translation, rotation and scale.
* @param position The translation
* @param orientation The rotation, must be normalized
* @param scale The scale
* @return This matrix for chaining */
public Matrix4 set (Vector3 position, Quaternion orientation, Vector3 scale) {
return set(position.x, position.y, position.z, orientation.x, orientation.y, orientation.z, orientation.w, scale.x,
scale.y, scale.z);
}
/** Sets the matrix to a rotation matrix representing the translation and quaternion.
* @param translationX The X component of the translation that is to be used to set this matrix.
* @param translationY The Y component of the translation that is to be used to set this matrix.
* @param translationZ The Z component of the translation that is to be used to set this matrix.
* @param quaternionX The X component of the quaternion that is to be used to set this matrix.
* @param quaternionY The Y component of the quaternion that is to be used to set this matrix.
* @param quaternionZ The Z component of the quaternion that is to be used to set this matrix.
* @param quaternionW The W component of the quaternion that is to be used to set this matrix.
* @param scaleX The X component of the scaling that is to be used to set this matrix.
* @param scaleY The Y component of the scaling that is to be used to set this matrix.
* @param scaleZ The Z component of the scaling that is to be used to set this matrix.
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 set (float translationX, float translationY, float translationZ, float quaternionX, float quaternionY,
float quaternionZ, float quaternionW, float scaleX, float scaleY, float scaleZ) {
final float xs = quaternionX * 2f, ys = quaternionY * 2f, zs = quaternionZ * 2f;
final float wx = quaternionW * xs, wy = quaternionW * ys, wz = quaternionW * zs;
final float xx = quaternionX * xs, xy = quaternionX * ys, xz = quaternionX * zs;
final float yy = quaternionY * ys, yz = quaternionY * zs, zz = quaternionZ * zs;
val[M00] = scaleX * (1.0f - (yy + zz));
val[M01] = scaleY * (xy - wz);
val[M02] = scaleZ * (xz + wy);
val[M03] = translationX;
val[M10] = scaleX * (xy + wz);
val[M11] = scaleY * (1.0f - (xx + zz));
val[M12] = scaleZ * (yz - wx);
val[M13] = translationY;
val[M20] = scaleX * (xz - wy);
val[M21] = scaleY * (yz + wx);
val[M22] = scaleZ * (1.0f - (xx + yy));
val[M23] = translationZ;
val[M30] = 0f;
val[M31] = 0f;
val[M32] = 0f;
val[M33] = 1f;
return this;
}
/** Sets the four columns of the matrix which correspond to the x-, y- and z-axis of the vector space this matrix creates as
* well as the 4th column representing the translation of any point that is multiplied by this matrix.
* @param xAxis The x-axis.
* @param yAxis The y-axis.
* @param zAxis The z-axis.
* @param pos The translation vector. */
public Matrix4 set (Vector3 xAxis, Vector3 yAxis, Vector3 zAxis, Vector3 pos) {
val[M00] = xAxis.x;
val[M01] = xAxis.y;
val[M02] = xAxis.z;
val[M10] = yAxis.x;
val[M11] = yAxis.y;
val[M12] = yAxis.z;
val[M20] = zAxis.x;
val[M21] = zAxis.y;
val[M22] = zAxis.z;
val[M03] = pos.x;
val[M13] = pos.y;
val[M23] = pos.z;
val[M30] = 0f;
val[M31] = 0f;
val[M32] = 0f;
val[M33] = 1f;
return this;
}
/** @return a copy of this matrix */
public Matrix4 cpy () {
return new Matrix4(this);
}
/** Adds a translational component to the matrix in the 4th column. The other columns are untouched.
* @param vector The translation vector to add to the current matrix. (This vector is not modified)
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 trn (Vector3 vector) {
val[M03] += vector.x;
val[M13] += vector.y;
val[M23] += vector.z;
return this;
}
/** Adds a translational component to the matrix in the 4th column. The other columns are untouched.
* @param x The x-component of the translation vector.
* @param y The y-component of the translation vector.
* @param z The z-component of the translation vector.
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 trn (float x, float y, float z) {
val[M03] += x;
val[M13] += y;
val[M23] += z;
return this;
}
/** @return the backing float array */
public float[] getValues () {
return val;
}
/** Postmultiplies this matrix with the given matrix, storing the result in this matrix. For example:
*
*
* A.mul(B) results in A := AB.
*
*
* @param matrix The other matrix to multiply by.
* @return This matrix for the purpose of chaining operations together. */
public Matrix4 mul (Matrix4 matrix) {
mul(val, matrix.val);
return this;
}
/** Premultiplies this matrix with the given matrix, storing the result in this matrix. For example:
*
*
* A.mulLeft(B) results in A := BA.
*
*
* @param matrix The other matrix to multiply by.
* @return This matrix for the purpose of chaining operations together. */
public Matrix4 mulLeft (Matrix4 matrix) {
tmpMat.set(matrix);
mul(tmpMat.val, val);
return set(tmpMat);
}
/** Transposes the matrix.
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 tra () {
float m01 = val[M01];
float m02 = val[M02];
float m03 = val[M03];
float m12 = val[M12];
float m13 = val[M13];
float m23 = val[M23];
val[M01] = val[M10];
val[M02] = val[M20];
val[M03] = val[M30];
val[M10] = m01;
val[M12] = val[M21];
val[M13] = val[M31];
val[M20] = m02;
val[M21] = m12;
val[M23] = val[M32];
val[M30] = m03;
val[M31] = m13;
val[M32] = m23;
return this;
}
/** Sets the matrix to an identity matrix.
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 idt () {
val[M00] = 1f;
val[M01] = 0f;
val[M02] = 0f;
val[M03] = 0f;
val[M10] = 0f;
val[M11] = 1f;
val[M12] = 0f;
val[M13] = 0f;
val[M20] = 0f;
val[M21] = 0f;
val[M22] = 1f;
val[M23] = 0f;
val[M30] = 0f;
val[M31] = 0f;
val[M32] = 0f;
val[M33] = 1f;
return this;
}
/** Inverts the matrix. Stores the result in this matrix.
* @return This matrix for the purpose of chaining methods together.
* @throws RuntimeException if the matrix is singular (not invertible) */
public Matrix4 inv () {
float l_det = val[M30] * val[M21] * val[M12] * val[M03] - val[M20] * val[M31] * val[M12] * val[M03] - val[M30] * val[M11]
* val[M22] * val[M03] + val[M10] * val[M31] * val[M22] * val[M03] + val[M20] * val[M11] * val[M32] * val[M03] - val[M10]
* val[M21] * val[M32] * val[M03] - val[M30] * val[M21] * val[M02] * val[M13] + val[M20] * val[M31] * val[M02] * val[M13]
+ val[M30] * val[M01] * val[M22] * val[M13] - val[M00] * val[M31] * val[M22] * val[M13] - val[M20] * val[M01] * val[M32]
* val[M13] + val[M00] * val[M21] * val[M32] * val[M13] + val[M30] * val[M11] * val[M02] * val[M23] - val[M10] * val[M31]
* val[M02] * val[M23] - val[M30] * val[M01] * val[M12] * val[M23] + val[M00] * val[M31] * val[M12] * val[M23] + val[M10]
* val[M01] * val[M32] * val[M23] - val[M00] * val[M11] * val[M32] * val[M23] - val[M20] * val[M11] * val[M02] * val[M33]
+ val[M10] * val[M21] * val[M02] * val[M33] + val[M20] * val[M01] * val[M12] * val[M33] - val[M00] * val[M21] * val[M12]
* val[M33] - val[M10] * val[M01] * val[M22] * val[M33] + val[M00] * val[M11] * val[M22] * val[M33];
if (l_det == 0f) throw new RuntimeException("non-invertible matrix");
float m00 = val[M12] * val[M23] * val[M31] - val[M13] * val[M22] * val[M31] + val[M13] * val[M21] * val[M32]
- val[M11] * val[M23] * val[M32] - val[M12] * val[M21] * val[M33] + val[M11] * val[M22] * val[M33];
float m01 = val[M03] * val[M22] * val[M31] - val[M02] * val[M23] * val[M31] - val[M03] * val[M21] * val[M32]
+ val[M01] * val[M23] * val[M32] + val[M02] * val[M21] * val[M33] - val[M01] * val[M22] * val[M33];
float m02 = val[M02] * val[M13] * val[M31] - val[M03] * val[M12] * val[M31] + val[M03] * val[M11] * val[M32]
- val[M01] * val[M13] * val[M32] - val[M02] * val[M11] * val[M33] + val[M01] * val[M12] * val[M33];
float m03 = val[M03] * val[M12] * val[M21] - val[M02] * val[M13] * val[M21] - val[M03] * val[M11] * val[M22]
+ val[M01] * val[M13] * val[M22] + val[M02] * val[M11] * val[M23] - val[M01] * val[M12] * val[M23];
float m10 = val[M13] * val[M22] * val[M30] - val[M12] * val[M23] * val[M30] - val[M13] * val[M20] * val[M32]
+ val[M10] * val[M23] * val[M32] + val[M12] * val[M20] * val[M33] - val[M10] * val[M22] * val[M33];
float m11 = val[M02] * val[M23] * val[M30] - val[M03] * val[M22] * val[M30] + val[M03] * val[M20] * val[M32]
- val[M00] * val[M23] * val[M32] - val[M02] * val[M20] * val[M33] + val[M00] * val[M22] * val[M33];
float m12 = val[M03] * val[M12] * val[M30] - val[M02] * val[M13] * val[M30] - val[M03] * val[M10] * val[M32]
+ val[M00] * val[M13] * val[M32] + val[M02] * val[M10] * val[M33] - val[M00] * val[M12] * val[M33];
float m13 = val[M02] * val[M13] * val[M20] - val[M03] * val[M12] * val[M20] + val[M03] * val[M10] * val[M22]
- val[M00] * val[M13] * val[M22] - val[M02] * val[M10] * val[M23] + val[M00] * val[M12] * val[M23];
float m20 = val[M11] * val[M23] * val[M30] - val[M13] * val[M21] * val[M30] + val[M13] * val[M20] * val[M31]
- val[M10] * val[M23] * val[M31] - val[M11] * val[M20] * val[M33] + val[M10] * val[M21] * val[M33];
float m21 = val[M03] * val[M21] * val[M30] - val[M01] * val[M23] * val[M30] - val[M03] * val[M20] * val[M31]
+ val[M00] * val[M23] * val[M31] + val[M01] * val[M20] * val[M33] - val[M00] * val[M21] * val[M33];
float m22 = val[M01] * val[M13] * val[M30] - val[M03] * val[M11] * val[M30] + val[M03] * val[M10] * val[M31]
- val[M00] * val[M13] * val[M31] - val[M01] * val[M10] * val[M33] + val[M00] * val[M11] * val[M33];
float m23 = val[M03] * val[M11] * val[M20] - val[M01] * val[M13] * val[M20] - val[M03] * val[M10] * val[M21]
+ val[M00] * val[M13] * val[M21] + val[M01] * val[M10] * val[M23] - val[M00] * val[M11] * val[M23];
float m30 = val[M12] * val[M21] * val[M30] - val[M11] * val[M22] * val[M30] - val[M12] * val[M20] * val[M31]
+ val[M10] * val[M22] * val[M31] + val[M11] * val[M20] * val[M32] - val[M10] * val[M21] * val[M32];
float m31 = val[M01] * val[M22] * val[M30] - val[M02] * val[M21] * val[M30] + val[M02] * val[M20] * val[M31]
- val[M00] * val[M22] * val[M31] - val[M01] * val[M20] * val[M32] + val[M00] * val[M21] * val[M32];
float m32 = val[M02] * val[M11] * val[M30] - val[M01] * val[M12] * val[M30] - val[M02] * val[M10] * val[M31]
+ val[M00] * val[M12] * val[M31] + val[M01] * val[M10] * val[M32] - val[M00] * val[M11] * val[M32];
float m33 = val[M01] * val[M12] * val[M20] - val[M02] * val[M11] * val[M20] + val[M02] * val[M10] * val[M21]
- val[M00] * val[M12] * val[M21] - val[M01] * val[M10] * val[M22] + val[M00] * val[M11] * val[M22];
float inv_det = 1.0f / l_det;
val[M00] = m00 * inv_det;
val[M10] = m10 * inv_det;
val[M20] = m20 * inv_det;
val[M30] = m30 * inv_det;
val[M01] = m01 * inv_det;
val[M11] = m11 * inv_det;
val[M21] = m21 * inv_det;
val[M31] = m31 * inv_det;
val[M02] = m02 * inv_det;
val[M12] = m12 * inv_det;
val[M22] = m22 * inv_det;
val[M32] = m32 * inv_det;
val[M03] = m03 * inv_det;
val[M13] = m13 * inv_det;
val[M23] = m23 * inv_det;
val[M33] = m33 * inv_det;
return this;
}
/** @return The determinant of this matrix */
public float det () {
return val[M30] * val[M21] * val[M12] * val[M03] - val[M20] * val[M31] * val[M12] * val[M03] - val[M30] * val[M11]
* val[M22] * val[M03] + val[M10] * val[M31] * val[M22] * val[M03] + val[M20] * val[M11] * val[M32] * val[M03] - val[M10]
* val[M21] * val[M32] * val[M03] - val[M30] * val[M21] * val[M02] * val[M13] + val[M20] * val[M31] * val[M02] * val[M13]
+ val[M30] * val[M01] * val[M22] * val[M13] - val[M00] * val[M31] * val[M22] * val[M13] - val[M20] * val[M01] * val[M32]
* val[M13] + val[M00] * val[M21] * val[M32] * val[M13] + val[M30] * val[M11] * val[M02] * val[M23] - val[M10] * val[M31]
* val[M02] * val[M23] - val[M30] * val[M01] * val[M12] * val[M23] + val[M00] * val[M31] * val[M12] * val[M23] + val[M10]
* val[M01] * val[M32] * val[M23] - val[M00] * val[M11] * val[M32] * val[M23] - val[M20] * val[M11] * val[M02] * val[M33]
+ val[M10] * val[M21] * val[M02] * val[M33] + val[M20] * val[M01] * val[M12] * val[M33] - val[M00] * val[M21] * val[M12]
* val[M33] - val[M10] * val[M01] * val[M22] * val[M33] + val[M00] * val[M11] * val[M22] * val[M33];
}
/** @return The determinant of the 3x3 upper left matrix */
public float det3x3 () {
return val[M00] * val[M11] * val[M22] + val[M01] * val[M12] * val[M20] + val[M02] * val[M10] * val[M21] - val[M00]
* val[M12] * val[M21] - val[M01] * val[M10] * val[M22] - val[M02] * val[M11] * val[M20];
}
/** Sets the matrix to a projection matrix with a near- and far plane, a field of view in degrees and an aspect ratio. Note that
* the field of view specified is the angle in degrees for the height, the field of view for the width will be calculated
* according to the aspect ratio.
* @param near The near plane
* @param far The far plane
* @param fovy The field of view of the height in degrees
* @param aspectRatio The "width over height" aspect ratio
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 setToProjection (float near, float far, float fovy, float aspectRatio) {
idt();
float l_fd = (float)(1.0 / Math.tan((fovy * (Math.PI / 180)) / 2.0));
float l_a1 = (far + near) / (near - far);
float l_a2 = (2 * far * near) / (near - far);
val[M00] = l_fd / aspectRatio;
val[M10] = 0;
val[M20] = 0;
val[M30] = 0;
val[M01] = 0;
val[M11] = l_fd;
val[M21] = 0;
val[M31] = 0;
val[M02] = 0;
val[M12] = 0;
val[M22] = l_a1;
val[M32] = -1;
val[M03] = 0;
val[M13] = 0;
val[M23] = l_a2;
val[M33] = 0;
return this;
}
/** Sets the matrix to a projection matrix with a near/far plane, and left, bottom, right and top specifying the points on the
* near plane that are mapped to the lower left and upper right corners of the viewport. This allows to create projection
* matrix with off-center vanishing point.
* @param left
* @param right
* @param bottom
* @param top
* @param near The near plane
* @param far The far plane
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 setToProjection (float left, float right, float bottom, float top, float near, float far) {
float x = 2.0f * near / (right - left);
float y = 2.0f * near / (top - bottom);
float a = (right + left) / (right - left);
float b = (top + bottom) / (top - bottom);
float l_a1 = (far + near) / (near - far);
float l_a2 = (2 * far * near) / (near - far);
val[M00] = x;
val[M10] = 0;
val[M20] = 0;
val[M30] = 0;
val[M01] = 0;
val[M11] = y;
val[M21] = 0;
val[M31] = 0;
val[M02] = a;
val[M12] = b;
val[M22] = l_a1;
val[M32] = -1;
val[M03] = 0;
val[M13] = 0;
val[M23] = l_a2;
val[M33] = 0;
return this;
}
/** Sets this matrix to an orthographic projection matrix with the origin at (x,y) extending by width and height. The near plane
* is set to 0, the far plane is set to 1.
* @param x The x-coordinate of the origin
* @param y The y-coordinate of the origin
* @param width The width
* @param height The height
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 setToOrtho2D (float x, float y, float width, float height) {
setToOrtho(x, x + width, y, y + height, 0, 1);
return this;
}
/** Sets this matrix to an orthographic projection matrix with the origin at (x,y) extending by width and height, having a near
* and far plane.
* @param x The x-coordinate of the origin
* @param y The y-coordinate of the origin
* @param width The width
* @param height The height
* @param near The near plane
* @param far The far plane
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 setToOrtho2D (float x, float y, float width, float height, float near, float far) {
setToOrtho(x, x + width, y, y + height, near, far);
return this;
}
/** Sets the matrix to an orthographic projection like glOrtho (http://www.opengl.org/sdk/docs/man/xhtml/glOrtho.xml) following
* the OpenGL equivalent
* @param left The left clipping plane
* @param right The right clipping plane
* @param bottom The bottom clipping plane
* @param top The top clipping plane
* @param near The near clipping plane
* @param far The far clipping plane
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 setToOrtho (float left, float right, float bottom, float top, float near, float far) {
float x_orth = 2 / (right - left);
float y_orth = 2 / (top - bottom);
float z_orth = -2 / (far - near);
float tx = -(right + left) / (right - left);
float ty = -(top + bottom) / (top - bottom);
float tz = -(far + near) / (far - near);
val[M00] = x_orth;
val[M10] = 0;
val[M20] = 0;
val[M30] = 0;
val[M01] = 0;
val[M11] = y_orth;
val[M21] = 0;
val[M31] = 0;
val[M02] = 0;
val[M12] = 0;
val[M22] = z_orth;
val[M32] = 0;
val[M03] = tx;
val[M13] = ty;
val[M23] = tz;
val[M33] = 1;
return this;
}
/** Sets the 4th column to the translation vector.
* @param vector The translation vector
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 setTranslation (Vector3 vector) {
val[M03] = vector.x;
val[M13] = vector.y;
val[M23] = vector.z;
return this;
}
/** Sets the 4th column to the translation vector.
* @param x The X coordinate of the translation vector
* @param y The Y coordinate of the translation vector
* @param z The Z coordinate of the translation vector
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 setTranslation (float x, float y, float z) {
val[M03] = x;
val[M13] = y;
val[M23] = z;
return this;
}
/** Sets this matrix to a translation matrix, overwriting it first by an identity matrix and then setting the 4th column to the
* translation vector.
* @param vector The translation vector
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 setToTranslation (Vector3 vector) {
idt();
val[M03] = vector.x;
val[M13] = vector.y;
val[M23] = vector.z;
return this;
}
/** Sets this matrix to a translation matrix, overwriting it first by an identity matrix and then setting the 4th column to the
* translation vector.
* @param x The x-component of the translation vector.
* @param y The y-component of the translation vector.
* @param z The z-component of the translation vector.
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 setToTranslation (float x, float y, float z) {
idt();
val[M03] = x;
val[M13] = y;
val[M23] = z;
return this;
}
/** Sets this matrix to a translation and scaling matrix by first overwriting it with an identity and then setting the
* translation vector in the 4th column and the scaling vector in the diagonal.
* @param translation The translation vector
* @param scaling The scaling vector
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 setToTranslationAndScaling (Vector3 translation, Vector3 scaling) {
idt();
val[M03] = translation.x;
val[M13] = translation.y;
val[M23] = translation.z;
val[M00] = scaling.x;
val[M11] = scaling.y;
val[M22] = scaling.z;
return this;
}
/** Sets this matrix to a translation and scaling matrix by first overwriting it with an identity and then setting the
* translation vector in the 4th column and the scaling vector in the diagonal.
* @param translationX The x-component of the translation vector
* @param translationY The y-component of the translation vector
* @param translationZ The z-component of the translation vector
* @param scalingX The x-component of the scaling vector
* @param scalingY The x-component of the scaling vector
* @param scalingZ The x-component of the scaling vector
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 setToTranslationAndScaling (float translationX, float translationY, float translationZ, float scalingX,
float scalingY, float scalingZ) {
idt();
val[M03] = translationX;
val[M13] = translationY;
val[M23] = translationZ;
val[M00] = scalingX;
val[M11] = scalingY;
val[M22] = scalingZ;
return this;
}
/** Sets the matrix to a rotation matrix around the given axis.
* @param axis The axis
* @param degrees The angle in degrees
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 setToRotation (Vector3 axis, float degrees) {
if (degrees == 0) {
idt();
return this;
}
return set(quat.set(axis, degrees));
}
/** Sets the matrix to a rotation matrix around the given axis.
* @param axis The axis
* @param radians The angle in radians
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 setToRotationRad (Vector3 axis, float radians) {
if (radians == 0) {
idt();
return this;
}
return set(quat.setFromAxisRad(axis, radians));
}
/** Sets the matrix to a rotation matrix around the given axis.
* @param axisX The x-component of the axis
* @param axisY The y-component of the axis
* @param axisZ The z-component of the axis
* @param degrees The angle in degrees
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 setToRotation (float axisX, float axisY, float axisZ, float degrees) {
if (degrees == 0) {
idt();
return this;
}
return set(quat.setFromAxis(axisX, axisY, axisZ, degrees));
}
/** Sets the matrix to a rotation matrix around the given axis.
* @param axisX The x-component of the axis
* @param axisY The y-component of the axis
* @param axisZ The z-component of the axis
* @param radians The angle in radians
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 setToRotationRad (float axisX, float axisY, float axisZ, float radians) {
if (radians == 0) {
idt();
return this;
}
return set(quat.setFromAxisRad(axisX, axisY, axisZ, radians));
}
/** Set the matrix to a rotation matrix between two vectors.
* @param v1 The base vector
* @param v2 The target vector
* @return This matrix for the purpose of chaining methods together */
public Matrix4 setToRotation (final Vector3 v1, final Vector3 v2) {
return set(quat.setFromCross(v1, v2));
}
/** Set the matrix to a rotation matrix between two vectors.
* @param x1 The base vectors x value
* @param y1 The base vectors y value
* @param z1 The base vectors z value
* @param x2 The target vector x value
* @param y2 The target vector y value
* @param z2 The target vector z value
* @return This matrix for the purpose of chaining methods together */
public Matrix4 setToRotation (final float x1, final float y1, final float z1, final float x2, final float y2, final float z2) {
return set(quat.setFromCross(x1, y1, z1, x2, y2, z2));
}
/** Sets this matrix to a rotation matrix from the given euler angles.
* @param yaw the yaw in degrees
* @param pitch the pitch in degrees
* @param roll the roll in degrees
* @return This matrix */
public Matrix4 setFromEulerAngles (float yaw, float pitch, float roll) {
quat.setEulerAngles(yaw, pitch, roll);
return set(quat);
}
/** Sets this matrix to a rotation matrix from the given euler angles.
* @param yaw the yaw in radians
* @param pitch the pitch in radians
* @param roll the roll in radians
* @return This matrix */
public Matrix4 setFromEulerAnglesRad (float yaw, float pitch, float roll) {
quat.setEulerAnglesRad(yaw, pitch, roll);
return set(quat);
}
/** Sets this matrix to a scaling matrix
* @param vector The scaling vector
* @return This matrix for chaining. */
public Matrix4 setToScaling (Vector3 vector) {
idt();
val[M00] = vector.x;
val[M11] = vector.y;
val[M22] = vector.z;
return this;
}
/** Sets this matrix to a scaling matrix
* @param x The x-component of the scaling vector
* @param y The y-component of the scaling vector
* @param z The z-component of the scaling vector
* @return This matrix for chaining. */
public Matrix4 setToScaling (float x, float y, float z) {
idt();
val[M00] = x;
val[M11] = y;
val[M22] = z;
return this;
}
/** Sets the matrix to a look at matrix with a direction and an up vector. Multiply with a translation matrix to get a camera
* model view matrix.
* @param direction The direction vector
* @param up The up vector
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 setToLookAt (Vector3 direction, Vector3 up) {
l_vez.set(direction).nor();
l_vex.set(direction).crs(up).nor();
l_vey.set(l_vex).crs(l_vez).nor();
idt();
val[M00] = l_vex.x;
val[M01] = l_vex.y;
val[M02] = l_vex.z;
val[M10] = l_vey.x;
val[M11] = l_vey.y;
val[M12] = l_vey.z;
val[M20] = -l_vez.x;
val[M21] = -l_vez.y;
val[M22] = -l_vez.z;
return this;
}
/** Sets this matrix to a look at matrix with the given position, target and up vector.
* @param position the position
* @param target the target
* @param up the up vector
* @return This matrix */
public Matrix4 setToLookAt (Vector3 position, Vector3 target, Vector3 up) {
tmpVec.set(target).sub(position);
setToLookAt(tmpVec, up);
mul(tmpMat.setToTranslation(-position.x, -position.y, -position.z));
return this;
}
public Matrix4 setToWorld (Vector3 position, Vector3 forward, Vector3 up) {
tmpForward.set(forward).nor();
right.set(tmpForward).crs(up).nor();
tmpUp.set(right).crs(tmpForward).nor();
set(right, tmpUp, tmpForward.scl(-1), position);
return this;
}
/** Linearly interpolates between this matrix and the given matrix mixing by alpha
* @param matrix the matrix
* @param alpha the alpha value in the range [0,1]
* @return This matrix for the purpose of chaining methods together. */
public Matrix4 lerp (Matrix4 matrix, float alpha) {
for (int i = 0; i < 16; i++)
val[i] = val[i] * (1 - alpha) + matrix.val[i] * alpha;
return this;
}
/** Averages the given transform with this one and stores the result in this matrix. Translations and scales are lerped while
* rotations are slerped.
* @param other The other transform
* @param w Weight of this transform; weight of the other transform is (1 - w)
* @return This matrix for chaining */
public Matrix4 avg (Matrix4 other, float w) {
getScale(tmpVec);
other.getScale(tmpForward);
getRotation(quat);
other.getRotation(quat2);
getTranslation(tmpUp);
other.getTranslation(right);
setToScaling(tmpVec.scl(w).add(tmpForward.scl(1 - w)));
rotate(quat.slerp(quat2, 1 - w));
setTranslation(tmpUp.scl(w).add(right.scl(1 - w)));
return this;
}
/** Averages the given transforms and stores the result in this matrix. Translations and scales are lerped while rotations are
* slerped. Does not destroy the data contained in t.
* @param t List of transforms
* @return This matrix for chaining */
public Matrix4 avg (Matrix4[] t) {
final float w = 1.0f / t.length;
tmpVec.set(t[0].getScale(tmpUp).scl(w));
quat.set(t[0].getRotation(quat2).exp(w));
tmpForward.set(t[0].getTranslation(tmpUp).scl(w));
for (int i = 1; i < t.length; i++) {
tmpVec.add(t[i].getScale(tmpUp).scl(w));
quat.mul(t[i].getRotation(quat2).exp(w));
tmpForward.add(t[i].getTranslation(tmpUp).scl(w));
}
quat.nor();
setToScaling(tmpVec);
rotate(quat);
setTranslation(tmpForward);
return this;
}
/** Averages the given transforms with the given weights and stores the result in this matrix. Translations and scales are
* lerped while rotations are slerped. Does not destroy the data contained in t or w; Sum of w_i must be equal to 1, or
* unexpected results will occur.
* @param t List of transforms
* @param w List of weights
* @return This matrix for chaining */
public Matrix4 avg (Matrix4[] t, float[] w) {
tmpVec.set(t[0].getScale(tmpUp).scl(w[0]));
quat.set(t[0].getRotation(quat2).exp(w[0]));
tmpForward.set(t[0].getTranslation(tmpUp).scl(w[0]));
for (int i = 1; i < t.length; i++) {
tmpVec.add(t[i].getScale(tmpUp).scl(w[i]));
quat.mul(t[i].getRotation(quat2).exp(w[i]));
tmpForward.add(t[i].getTranslation(tmpUp).scl(w[i]));
}
quat.nor();
setToScaling(tmpVec);
rotate(quat);
setTranslation(tmpForward);
return this;
}
/** Sets this matrix to the given 3x3 matrix. The third column of this matrix is set to (0,0,1,0).
* @param mat the matrix */
public Matrix4 set (Matrix3 mat) {
val[0] = mat.val[0];
val[1] = mat.val[1];
val[2] = mat.val[2];
val[3] = 0;
val[4] = mat.val[3];
val[5] = mat.val[4];
val[6] = mat.val[5];
val[7] = 0;
val[8] = 0;
val[9] = 0;
val[10] = 1;
val[11] = 0;
val[12] = mat.val[6];
val[13] = mat.val[7];
val[14] = 0;
val[15] = mat.val[8];
return this;
}
/** Sets this matrix to the given affine matrix. The values are mapped as follows:
*
*