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

com.badlogic.gdx.math.Matrix4 Maven / Gradle / Ivy

The newest version!
/**
 * *****************************************************************************
 * 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. You can access the linear array for use with OpenGL via the public {@link Matrix4#val} member. Like the {@link Vector3} class it
 * allows to chain methods by returning a reference to itself.
 *
 * @author [email protected]
 */
public final class Matrix4 implements Serializable {

	private static final long serialVersionUID = -2718655254359579617L;
	public static final int M00 = 0;// 0;
	public static final int M01 = 4;// 1;
	public static final int M02 = 8;// 2;
	public static final int M03 = 12;// 3;
	public static final int M10 = 1;// 4;
	public static final int M11 = 5;// 5;
	public static final int M12 = 9;// 6;
	public static final int M13 = 13;// 7;
	public static final int M20 = 2;// 8;
	public static final int M21 = 6;// 9;
	public static final int M22 = 10;// 10;
	public static final int M23 = 14;// 11;
	public static final int M30 = 3;// 12;
	public static final int M31 = 7;// 13;
	public static final int M32 = 11;// 14;
	public static final int M33 = 15;// 15;
	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
	 */
	public Matrix4(Matrix4 matrix) {
		this.set(matrix);
	}

	/**
	 * Constructs a matrix from the given float array. The array must have at least 16 elements
	 *
	 * @param values The float array
	 */
	public Matrix4(float[] values) {
		this.set(values);
	}

	/**
	 * Constructs a rotation matrix from the given {@link Quaternion}
	 *
	 * @param quaternion The quaternion
	 */
	public Matrix4(Quaternion quaternion) {
		this.set(quaternion);
	}

	/**
	 * Sets the matrix to the given matrix.
	 *
	 * @param matrix The matrix
	 * @return This matrix for chaining
	 */
	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.
	 *
	 * @param values The matrix
	 * @return This matrix for chaining
	 */
	public Matrix4 set(float[] values) {
		val[M00] = values[M00];
		val[M10] = values[M10];
		val[M20] = values[M20];
		val[M30] = values[M30];
		val[M01] = values[M01];
		val[M11] = values[M11];
		val[M21] = values[M21];
		val[M31] = values[M31];
		val[M02] = values[M02];
		val[M12] = values[M12];
		val[M22] = values[M22];
		val[M32] = values[M32];
		val[M03] = values[M03];
		val[M13] = values[M13];
		val[M23] = values[M23];
		val[M33] = values[M33];
		return this;
	}

	/**
	 * Sets the matrix to a rotation matrix representing the quaternion.
	 *
	 * @param quaternion The quaternion
	 * @return This matrix for chaining
	 */
	public Matrix4 set(Quaternion quaternion) {
		// Compute quaternion factors
		float l_xx = quaternion.x * quaternion.x;
		float l_xy = quaternion.x * quaternion.y;
		float l_xz = quaternion.x * quaternion.z;
		float l_xw = quaternion.x * quaternion.w;
		float l_yy = quaternion.y * quaternion.y;
		float l_yz = quaternion.y * quaternion.z;
		float l_yw = quaternion.y * quaternion.w;
		float l_zz = quaternion.z * quaternion.z;
		float l_zw = quaternion.z * quaternion.w;
		// Set matrix from quaternion
		val[M00] = 1 - 2 * (l_yy + l_zz);
		val[M01] = 2 * (l_xy - l_zw);
		val[M02] = 2 * (l_xz + l_yw);
		val[M03] = 0;
		val[M10] = 2 * (l_xy + l_zw);
		val[M11] = 1 - 2 * (l_xx + l_zz);
		val[M12] = 2 * (l_yz - l_xw);
		val[M13] = 0;
		val[M20] = 2 * (l_xz - l_yw);
		val[M21] = 2 * (l_yz + l_xw);
		val[M22] = 1 - 2 * (l_xx + l_yy);
		val[M23] = 0;
		val[M30] = 0;
		val[M31] = 0;
		val[M32] = 0;
		val[M33] = 1;
		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 void 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] = 0;
		val[M31] = 0;
		val[M32] = 0;
		val[M33] = 1;
	}

	/**
	 * @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
	 * @return This matrix for chaining
	 */
	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 chaining
	 */
	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;
	}

	/**
	 * Multiplies this matrix with the given matrix, storing the result in this matrix.
	 *
	 * @param matrix The other matrix
	 * @return This matrix for chaining.
	 */
	public Matrix4 mul(Matrix4 matrix) {
		final float tmp[] = new float[16];
		tmp[M00] = val[M00] * matrix.val[M00] + val[M01] * matrix.val[M10] + val[M02] * matrix.val[M20] + val[M03]
				* matrix.val[M30];
		tmp[M01] = val[M00] * matrix.val[M01] + val[M01] * matrix.val[M11] + val[M02] * matrix.val[M21] + val[M03]
				* matrix.val[M31];
		tmp[M02] = val[M00] * matrix.val[M02] + val[M01] * matrix.val[M12] + val[M02] * matrix.val[M22] + val[M03]
				* matrix.val[M32];
		tmp[M03] = val[M00] * matrix.val[M03] + val[M01] * matrix.val[M13] + val[M02] * matrix.val[M23] + val[M03]
				* matrix.val[M33];
		tmp[M10] = val[M10] * matrix.val[M00] + val[M11] * matrix.val[M10] + val[M12] * matrix.val[M20] + val[M13]
				* matrix.val[M30];
		tmp[M11] = val[M10] * matrix.val[M01] + val[M11] * matrix.val[M11] + val[M12] * matrix.val[M21] + val[M13]
				* matrix.val[M31];
		tmp[M12] = val[M10] * matrix.val[M02] + val[M11] * matrix.val[M12] + val[M12] * matrix.val[M22] + val[M13]
				* matrix.val[M32];
		tmp[M13] = val[M10] * matrix.val[M03] + val[M11] * matrix.val[M13] + val[M12] * matrix.val[M23] + val[M13]
				* matrix.val[M33];
		tmp[M20] = val[M20] * matrix.val[M00] + val[M21] * matrix.val[M10] + val[M22] * matrix.val[M20] + val[M23]
				* matrix.val[M30];
		tmp[M21] = val[M20] * matrix.val[M01] + val[M21] * matrix.val[M11] + val[M22] * matrix.val[M21] + val[M23]
				* matrix.val[M31];
		tmp[M22] = val[M20] * matrix.val[M02] + val[M21] * matrix.val[M12] + val[M22] * matrix.val[M22] + val[M23]
				* matrix.val[M32];
		tmp[M23] = val[M20] * matrix.val[M03] + val[M21] * matrix.val[M13] + val[M22] * matrix.val[M23] + val[M23]
				* matrix.val[M33];
		tmp[M30] = val[M30] * matrix.val[M00] + val[M31] * matrix.val[M10] + val[M32] * matrix.val[M20] + val[M33]
				* matrix.val[M30];
		tmp[M31] = val[M30] * matrix.val[M01] + val[M31] * matrix.val[M11] + val[M32] * matrix.val[M21] + val[M33]
				* matrix.val[M31];
		tmp[M32] = val[M30] * matrix.val[M02] + val[M31] * matrix.val[M12] + val[M32] * matrix.val[M22] + val[M33]
				* matrix.val[M32];
		tmp[M33] = val[M30] * matrix.val[M03] + val[M31] * matrix.val[M13] + val[M32] * matrix.val[M23] + val[M33]
				* matrix.val[M33];
		return this.set(tmp);
	}

	/**
	 * Transposes the matrix
	 *
	 * @return This matrix for chaining
	 */
	public Matrix4 tra() {
		final float tmp[] = new float[16];
		tmp[M00] = val[M00];
		tmp[M01] = val[M10];
		tmp[M02] = val[M20];
		tmp[M03] = val[M30];
		tmp[M10] = val[M01];
		tmp[M11] = val[M11];
		tmp[M12] = val[M21];
		tmp[M13] = val[M31];
		tmp[M20] = val[M02];
		tmp[M21] = val[M12];
		tmp[M22] = val[M22];
		tmp[M23] = val[M32];
		tmp[M30] = val[M03];
		tmp[M31] = val[M13];
		tmp[M32] = val[M23];
		tmp[M33] = val[M33];
		return this.set(tmp);
	}

	/**
	 * Sets the matrix to an identity matrix
	 *
	 * @return This matrix for chaining
	 */
	public Matrix4 idt() {
		val[M00] = 1;
		val[M01] = 0;
		val[M02] = 0;
		val[M03] = 0;
		val[M10] = 0;
		val[M11] = 1;
		val[M12] = 0;
		val[M13] = 0;
		val[M20] = 0;
		val[M21] = 0;
		val[M22] = 1;
		val[M23] = 0;
		val[M30] = 0;
		val[M31] = 0;
		val[M32] = 0;
		val[M33] = 1;
		return this;
	}

	/**
	 * Inverts the matrix. Throws a RuntimeException in case the matrix is not invertible. Stores the result in this matrix
	 *
	 * @return This matrix for chaining
	 */
	public Matrix4 inv() {
		final float tmp[] = new float[16];
		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 inv_det = 1.0f / l_det;
		tmp[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];
		tmp[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];
		tmp[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];
		tmp[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];
		tmp[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];
		tmp[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];
		tmp[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];
		tmp[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];
		tmp[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];
		tmp[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];
		tmp[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];
		tmp[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];
		tmp[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];
		tmp[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];
		tmp[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];
		tmp[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];
		val[M00] = tmp[M00] * inv_det;
		val[M01] = tmp[M01] * inv_det;
		val[M02] = tmp[M02] * inv_det;
		val[M03] = tmp[M03] * inv_det;
		val[M10] = tmp[M10] * inv_det;
		val[M11] = tmp[M11] * inv_det;
		val[M12] = tmp[M12] * inv_det;
		val[M13] = tmp[M13] * inv_det;
		val[M20] = tmp[M20] * inv_det;
		val[M21] = tmp[M21] * inv_det;
		val[M22] = tmp[M22] * inv_det;
		val[M23] = tmp[M23] * inv_det;
		val[M30] = tmp[M30] * inv_det;
		val[M31] = tmp[M31] * inv_det;
		val[M32] = tmp[M32] * inv_det;
		val[M33] = tmp[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];
	}

	/**
	 * Sets the matrix to a projection matrix with a near- and far plane, a field of view in degrees and an aspect ratio.
	 *
	 * @param near The near plane
	 * @param far The far plane
	 * @param fov The field of view in degrees
	 * @param aspectRatio The aspect ratio
	 * @return This matrix for chaining
	 */
	public Matrix4 setToProjection(float near, float far, float fov, float aspectRatio) {
		this.idt();
		float l_fd = (float) (1.0 / Math.tan((fov * (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 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 chaining
	 */
	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 chaining
	 */
	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 chaining
	 */
	public Matrix4 setToOrtho(float left, float right, float bottom, float top, float near, float far) {

		this.idt();
		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 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 chaining
	 */
	public Matrix4 setToTranslation(Vector3 vector) {
		this.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 chaining
	 */
	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 overwritting 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 chaining
	 */
	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 overwritting 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 chaining
	 */
	public Matrix4 setToTranslationAndScaling(float translationX, float translationY, float translationZ, float scalingX,
			float scalingY, float scalingZ) {
		this.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 angle The angle in degrees
	 * @return This matrix for chaining
	 */
	public Matrix4 setToRotation(Vector3 axis, float angle) {
		idt();
		if (angle == 0) {
			return this;
		}
		return this.set(new Quaternion().set(axis, angle));
	}

	/**
	 * 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 angle The angle in degrees
	 * @return This matrix for chaining
	 */
	public Matrix4 setToRotation(float axisX, float axisY, float axisZ, float angle) {
		final Vector3 tmpV = new Vector3();
		idt();
		if (angle == 0) {
			return this;
		}
		return this.set(new Quaternion().set(tmpV.set(axisX, axisY, axisZ), angle));
	}

	/**
	 * Sets this matrix to a rotation matrix from the given euler angles.
	 *
	 * @param yaw the yaw in degrees
	 * @param pitch the pitch in degress
	 * @param roll the roll in degrees
	 * @return this matrix
	 */
	public Matrix4 setFromEulerAngles(float yaw, float pitch, float roll) {
		idt();
		final Quaternion quat = new Quaternion();
		quat.setEulerAngles(yaw, pitch, roll);
		return this.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 chaining
	 */
	public Matrix4 setToLookAt(Vector3 direction, Vector3 up) {
		final Vector3 l_vez = new Vector3();
		final Vector3 l_vex = new Vector3();
		final Vector3 l_vey = new Vector3();

		l_vez.set(direction).nor();
		l_vex.set(direction).nor();
		l_vex.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) {
		final Vector3 tmpVec = new Vector3();
		final Matrix4 tmpMat = new Matrix4();

		tmpVec.set(target).sub(position);
		setToLookAt(tmpVec, up);
		this.mul(tmpMat.setToTranslation(position.tmp().mul(-1)));

		return this;
	}

	public Matrix4 setToWorld(Vector3 position, Vector3 forward, Vector3 up) {
		final Vector3 right = new Vector3();
		final Vector3 tmpForward = new Vector3();
		final Vector3 tmpUp = new Vector3();

		tmpForward.set(forward).nor();
		right.set(tmpForward).crs(up).nor();
		tmpUp.set(right).crs(tmpForward).nor();

		this.set(right, tmpUp, tmpForward, position);
		return this;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String toString() {
		return "[" + val[M00] + "|" + val[M01] + "|" + val[M02] + "|" + val[M03] + "]\n" +//
				"[" + val[M10] + "|" + val[M11] + "|" + val[M12] + "|" + val[M13] + "]\n" +//
				"[" + val[M20] + "|" + val[M21] + "|" + val[M22] + "|" + val[M23] + "]\n" +//
				"[" + val[M30] + "|" + val[M31] + "|" + val[M32] + "|" + val[M33] + "]\n";
	}

	/**
	 * 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]
	 */
	public void lerp(Matrix4 matrix, float alpha) {
		for (int i = 0; i < 16; i++) {
			this.val[i] = this.val[i] * (1 - alpha) + matrix.val[i] * alpha;
		}
	}

	/**
	 * 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;
	}

	public Matrix4 scl(Vector3 scale) {
		val[M00] *= scale.x;
		val[M11] *= scale.y;
		val[M22] *= scale.z;
		return this;
	}

	public Matrix4 scl(float scale) {
		val[M00] *= scale;
		val[M11] *= scale;
		val[M22] *= scale;
		return this;
	}

	public void getTranslation(Vector3 position) {
		position.x = val[M03];
		position.y = val[M13];
		position.z = val[M23];
	}

	public void getRotation(Quaternion rotation) {
		rotation.setFromMatrix(this);
	}

	/**
	 * removes the translational part and transposes the matrix.
	 */
	public Matrix4 toNormalMatrix() {
		val[M03] = 0;
		val[M13] = 0;
		val[M23] = 0;
		inv();
		return tra();
	}

	/*JNI
	 #include 
	 #include 
	 #include 
	
	 #define M00 0
	 #define M01 4
	 #define M02 8
	 #define M03 12
	 #define M10 1
	 #define M11 5
	 #define M12 9
	 #define M13 13
	 #define M20 2
	 #define M21 6
	 #define M22 10
	 #define M23 14
	 #define M30 3
	 #define M31 7
	 #define M32 11
	 #define M33 15
	
	 static inline void matrix4_mul(float* mata, float* matb) {
	 float tmp[16];
	 tmp[M00] = mata[M00] * matb[M00] + mata[M01] * matb[M10] + mata[M02] * matb[M20] + mata[M03] * matb[M30];
	 tmp[M01] = mata[M00] * matb[M01] + mata[M01] * matb[M11] + mata[M02] * matb[M21] + mata[M03] * matb[M31];
	 tmp[M02] = mata[M00] * matb[M02] + mata[M01] * matb[M12] + mata[M02] * matb[M22] + mata[M03] * matb[M32];
	 tmp[M03] = mata[M00] * matb[M03] + mata[M01] * matb[M13] + mata[M02] * matb[M23] + mata[M03] * matb[M33];
	 tmp[M10] = mata[M10] * matb[M00] + mata[M11] * matb[M10] + mata[M12] * matb[M20] + mata[M13] * matb[M30];
	 tmp[M11] = mata[M10] * matb[M01] + mata[M11] * matb[M11] + mata[M12] * matb[M21] + mata[M13] * matb[M31];
	 tmp[M12] = mata[M10] * matb[M02] + mata[M11] * matb[M12] + mata[M12] * matb[M22] + mata[M13] * matb[M32];
	 tmp[M13] = mata[M10] * matb[M03] + mata[M11] * matb[M13] + mata[M12] * matb[M23] + mata[M13] * matb[M33];
	 tmp[M20] = mata[M20] * matb[M00] + mata[M21] * matb[M10] + mata[M22] * matb[M20] + mata[M23] * matb[M30];
	 tmp[M21] = mata[M20] * matb[M01] + mata[M21] * matb[M11] + mata[M22] * matb[M21] + mata[M23] * matb[M31];
	 tmp[M22] = mata[M20] * matb[M02] + mata[M21] * matb[M12] + mata[M22] * matb[M22] + mata[M23] * matb[M32];
	 tmp[M23] = mata[M20] * matb[M03] + mata[M21] * matb[M13] + mata[M22] * matb[M23] + mata[M23] * matb[M33];
	 tmp[M30] = mata[M30] * matb[M00] + mata[M31] * matb[M10] + mata[M32] * matb[M20] + mata[M33] * matb[M30];
	 tmp[M31] = mata[M30] * matb[M01] + mata[M31] * matb[M11] + mata[M32] * matb[M21] + mata[M33] * matb[M31];
	 tmp[M32] = mata[M30] * matb[M02] + mata[M31] * matb[M12] + mata[M32] * matb[M22] + mata[M33] * matb[M32];
	 tmp[M33] = mata[M30] * matb[M03] + mata[M31] * matb[M13] + mata[M32] * matb[M23] + mata[M33] * matb[M33];
	 memcpy(mata, tmp, sizeof(float) *  16);
	 }
	
	 static inline float matrix4_det(float* val) {
	 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];
	 }
	
	 static inline bool matrix4_inv(float* val) {
	 float tmp[16];
	 float l_det = matrix4_det(val);
	 if (l_det == 0) return false;
	 tmp[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];
	 tmp[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];
	 tmp[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];
	 tmp[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];
	 tmp[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];
	 tmp[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];
	 tmp[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];
	 tmp[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];
	 tmp[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];
	 tmp[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];
	 tmp[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];
	 tmp[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];
	 tmp[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];
	 tmp[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];
	 tmp[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];
	 tmp[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] = tmp[M00] * inv_det;
	 val[M01] = tmp[M01] * inv_det;
	 val[M02] = tmp[M02] * inv_det;
	 val[M03] = tmp[M03] * inv_det;
	 val[M10] = tmp[M10] * inv_det;
	 val[M11] = tmp[M11] * inv_det;
	 val[M12] = tmp[M12] * inv_det;
	 val[M13] = tmp[M13] * inv_det;
	 val[M20] = tmp[M20] * inv_det;
	 val[M21] = tmp[M21] * inv_det;
	 val[M22] = tmp[M22] * inv_det;
	 val[M23] = tmp[M23] * inv_det;
	 val[M30] = tmp[M30] * inv_det;
	 val[M31] = tmp[M31] * inv_det;
	 val[M32] = tmp[M32] * inv_det;
	 val[M33] = tmp[M33] * inv_det;
	 return true;
	 }
	
	 static inline void matrix4_mulVec(float* mat, float* vec) {
	 float x = vec[0] * mat[M00] + vec[1] * mat[M01] + vec[2] * mat[M02] + mat[M03];
	 float y = vec[0] * mat[M10] + vec[1] * mat[M11] + vec[2] * mat[M12] + mat[M13];
	 float z = vec[0] * mat[M20] + vec[1] * mat[M21] + vec[2] * mat[M22] + mat[M23];
	 vec[0] = x;
	 vec[1] = y;
	 vec[2] = z;
	 }
	
	 static inline void matrix4_proj(float* mat, float* vec) {
	 float inv_w = 1.0f / (vec[0] * mat[M30] + vec[1] * mat[M31] + vec[2] * mat[M32] + mat[M33]);
	 float x = (vec[0] * mat[M00] + vec[1] * mat[M01] + vec[2] * mat[M02] + mat[M03]) * inv_w;
	 float y = (vec[0] * mat[M10] + vec[1] * mat[M11] + vec[2] * mat[M12] + mat[M13]) * inv_w; 
	 float z = (vec[0] * mat[M20] + vec[1] * mat[M21] + vec[2] * mat[M22] + mat[M23]) * inv_w;
	 vec[0] = x;
	 vec[1] = y;
	 vec[2] = z;
	 }
	
	 static inline void matrix4_rot(float* mat, float* vec) {
	 float x = vec[0] * mat[M00] + vec[1] * mat[M01] + vec[2] * mat[M02];
	 float y = vec[0] * mat[M10] + vec[1] * mat[M11] + vec[2] * mat[M12];
	 float z = vec[0] * mat[M20] + vec[1] * mat[M21] + vec[2] * mat[M22];
	 vec[0] = x;
	 vec[1] = y;
	 vec[2] = z;
	 }
	 */
	/**
	 * Multiplies the matrix mata with matrix matb, storing the result in mata. The arrays are assumed to hold 4x4 column major matrices as you can get from {@link Matrix4#val}.
	 * This is the same as {@link Matrix4#mul(Matrix4)}.
	 *
	 * @param mata the first matrix.
	 * @param matb the second matrix.
	 */
	public static void mul(float[] mata, float[] matb) {
		final Matrix4 result = new Matrix4(mata);
		result.mul(new Matrix4(matb));

		System.arraycopy(result.val, 0, mata, 0, mata.length);
	}

	/**
	 * Multiplies the vector with the given matrix. The matrix array is assumed to hold a 4x4 column major matrix as you can get from {@link Matrix4#val}. The vector array is
	 * assumed to hold a 3-component vector, with x being the first element, y being the second and z being the last component. The result is stored in the vector array. This is
	 * the same as {@link Vector3#mul(Matrix4)}.
	 *
	 * @param mat the matrix
	 * @param vec the vector.
	 */
	public static void mulVec(float[] mat, float[] vec) {
		Matrix4.mulVec(mat, vec, 0, 1, 3);
	}

	/**
	 * Multiplies the vectors with the given matrix. The matrix array is assumed to hold a 4x4 column major matrix as you can get from {@link Matrix4#val}. The vectors array is
	 * assumed to hold 3-component vectors. Offset specifies the offset into the array where the x-component of the first vector is located. The numVecs parameter specifies the
	 * number of vectors stored in the vectors array. The stride parameter specifies the number of floats between subsequent vectors and must be >= 3. This is the same as
	 * {@link Vector3#mul(Matrix4)} applied to multiple vectors.
	 *
	 * @param mat the matrix
	 * @param vecs the vectors
	 * @param offset the offset into the vectors array
	 * @param numVecs the number of vectors
	 * @param stride the stride between vectors in floats
	 */
	public static native void mulVec(float[] mat, float[] vecs, int offset, int numVecs, int stride) /*-{ }-*/; /*
	 float* vecPtr = vecs + offset;
	 for(int i = 0; i < numVecs; i++) {
	 matrix4_mulVec(mat, vecPtr);
	 vecPtr += stride;
	 }
	 */


	/**
	 * Multiplies the vector with the given matrix, performing a division by w. The matrix array is assumed to hold a 4x4 column major matrix as you can get from
	 * {@link Matrix4#val}. The vector array is assumed to hold a 3-component vector, with x being the first element, y being the second and z being the last component. The result
	 * is stored in the vector array. This is the same as {@link Vector3#prj(Matrix4)}.
	 *
	 * @param mat the matrix
	 * @param vec the vector.
	 */
	public static void prj(float[] mat, float[] vec) {
		prj(mat, vec, 0, 1, 3);
	}

	/**
	 * Multiplies the vectors with the given matrix, , performing a division by w. The matrix array is assumed to hold a 4x4 column major matrix as you can get from
	 * {@link Matrix4#val}. The vectors array is assumed to hold 3-component vectors. Offset specifies the offset into the array where the x-component of the first vector is
	 * located. The numVecs parameter specifies the number of vectors stored in the vectors array. The stride parameter specifies the number of floats between subsequent vectors
	 * and must be >= 3. This is the same as {@link Vector3#prj(Matrix4)} applied to multiple vectors.
	 *
	 * @param mat the matrix
	 * @param vecs the vectors
	 * @param offset the offset into the vectors array
	 * @param numVecs the number of vectors
	 * @param stride the stride between vectors in floats
	 */
	public static native void prj(float[] mat, float[] vecs, int offset, int numVecs, int stride) /*-{ }-*/; /*
	 float* vecPtr = vecs + offset;
	 for(int i = 0; i < numVecs; i++) {
	 matrix4_proj(mat, vecPtr);
	 vecPtr += stride;
	 }
	 */


	/**
	 * Multiplies the vector with the top most 3x3 sub-matrix of the given matrix. The matrix array is assumed to hold a 4x4 column major matrix as you can get from
	 * {@link Matrix4#val}. The vector array is assumed to hold a 3-component vector, with x being the first element, y being the second and z being the last component. The result
	 * is stored in the vector array. This is the same as {@link Vector3#rot(Matrix4)}.
	 *
	 * @param mat the matrix
	 * @param vec the vector.
	 */
	public static void rot(float[] mat, float[] vec) {
		rot(mat, vec, 0, 1, 3);
	}

	/**
	 * Multiplies the vectors with the top most 3x3 sub-matrix of the given matrix. The matrix array is assumed to hold a 4x4 column major matrix as you can get from
	 * {@link Matrix4#val}. The vectors array is assumed to hold 3-component vectors. Offset specifies the offset into the array where the x-component of the first vector is
	 * located. The numVecs parameter specifies the number of vectors stored in the vectors array. The stride parameter specifies the number of floats between subsequent vectors
	 * and must be >= 3. This is the same as {@link Vector3#rot(Matrix4)} applied to multiple vectors.
	 *
	 * @param mat the matrix
	 * @param vecs the vectors
	 * @param offset the offset into the vectors array
	 * @param numVecs the number of vectors
	 * @param stride the stride between vectors in floats
	 */
	public static native void rot(float[] mat, float[] vecs, int offset, int numVecs, int stride) /*-{ }-*/; /*
	 float* vecPtr = vecs + offset;
	 for(int i = 0; i < numVecs; i++) {
	 matrix4_rot(mat, vecPtr);
	 vecPtr += stride;
	 }
	 */


	/**
	 * Computes the inverse of the given matrix. The matrix array is assumed to hold a 4x4 column major matrix as you can get from {@link Matrix4#val}.
	 *
	 * @param values the matrix values.
	 * @return false in case the inverse could not be calculated, true otherwise.
	 */
	public static native boolean inv(float[] values) /*-{ }-*/; /*
	 return matrix4_inv(values);
	 */


	/**
	 * Computes the determinante of the given matrix. The matrix array is assumed to hold a 4x4 column major matrix as you can get from {@link Matrix4#val}.
	 *
	 * @param values the matrix values.
	 * @return the determinante.
	 */
	public static native float det(float[] values) /*-{ }-*/; /*
	 return matrix4_det(values);
	 */


	/**
	 * Postmultiplies this matrix by a translation matrix. Postmultiplication is also used by OpenGL ES' glTranslate/glRotate/glScale
	 *
	 * @param translation
	 * @return this matrix for chaining
	 */
	public Matrix4 translate(Vector3 translation) {
		return translate(translation.x, translation.y, translation.z);
	}

	/**
	 * Postmultiplies this matrix by a translation matrix. Postmultiplication is also used by OpenGL ES' glTranslate/glRotate/glScale
	 *
	 * @param x
	 * @param y
	 * @param z
	 * @return this matrix for chaining
	 */
	public Matrix4 translate(float x, float y, float z) {
		final float tmp[] = new float[16];
		tmp[M00] = 1;
		tmp[M01] = 0;
		tmp[M02] = 0;
		tmp[M03] = x;
		tmp[M10] = 0;
		tmp[M11] = 1;
		tmp[M12] = 0;
		tmp[M13] = y;
		tmp[M20] = 0;
		tmp[M21] = 0;
		tmp[M22] = 1;
		tmp[M23] = z;
		tmp[M30] = 0;
		tmp[M31] = 0;
		tmp[M32] = 0;
		tmp[M33] = 1;

		mul(val, tmp);
		return this;
	}

	/**
	 * Postmultiplies this matrix with a (counter-clockwise) rotation matrix. Postmultiplication is also used by OpenGL ES' glTranslate/glRotate/glScale
	 *
	 * @param axis
	 * @param angle the angle in degrees
	 * @return this matrix for chaining
	 */
	public Matrix4 rotate(Vector3 axis, float angle) {
		if (angle == 0) {
			return this;
		}
		return rotate(new Quaternion().set(axis, angle));
	}

	/**
	 * Postmultiplies this matrix with a (counter-clockwise) rotation matrix. Postmultiplication is also used by OpenGL ES' glTranslate/glRotate/glScale
	 *
	 * @param axisX
	 * @param axisY
	 * @param axisZ
	 * @param angle the angle in degrees
	 * @return this matrix for chaining
	 */
	public Matrix4 rotate(float axisX, float axisY, float axisZ, float angle) {
		if (angle == 0) {
			return this;
		}

		final Vector3 tmpV = new Vector3();

		return rotate(new Quaternion().set(tmpV.set(axisX, axisY, axisZ), angle));
	}

	/**
	 * Postmultiplies this matrix with a (counter-clockwise) rotation matrix. Postmultiplication is also used by OpenGL ES' glTranslate/glRotate/glScale
	 *
	 * @param rotation
	 * @return this matrix for chaining
	 */
	public Matrix4 rotate(Quaternion rotation) {
		final float tmp[] = new float[16];
		rotation.toMatrix(tmp);
		mul(val, tmp);
		return this;
	}

	/**
	 * Postmultiplies this matrix with a scale matrix. Postmultiplication is also used by OpenGL ES' glTranslate/glRotate/glScale.
	 *
	 * @param scaleX
	 * @param scaleY
	 * @param scaleZ
	 * @return this matrix for chaining
	 */
	public Matrix4 scale(float scaleX, float scaleY, float scaleZ) {
		final float tmp[] = new float[16];
		tmp[M00] = scaleX;
		tmp[M01] = 0;
		tmp[M02] = 0;
		tmp[M03] = 0;
		tmp[M10] = 0;
		tmp[M11] = scaleY;
		tmp[M12] = 0;
		tmp[M13] = 0;
		tmp[M20] = 0;
		tmp[M21] = 0;
		tmp[M22] = scaleZ;
		tmp[M23] = 0;
		tmp[M30] = 0;
		tmp[M31] = 0;
		tmp[M32] = 0;
		tmp[M33] = 1;

		mul(val, tmp);
		return this;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy