/*******************************************************************************
* 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.erlei.gdx.math;
import java.io.Serializable;
/** Encapsulates a <a href="http://en.wikipedia.org/wiki/Row-major_order#Column-major_order">column major</a> 4 by 4 matrix. Like
* the {@link Vector3} class it allows the chaining of methods by returning a reference to itself. For example:
*
* <pre>
* Matrix4 mat = new Matrix4().trn(position).mul(camera.combined);
* </pre>
*
* @author badlogicgames@gmail.com */
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;
private static final float tmp[] = new float[16];
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) {
this.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 <a
* href="http://en.wikipedia.org/wiki/Row-major_order">column major</a> order. (The float array is not modified) */
public Matrix4 (float[] values) {
this.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) {
this.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 this.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 <a
* href="http://en.wikipedia.org/wiki/Row-major_order">column major</a> 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, posi