--- /dev/null
+/*******************************************************************************\r
+ * Copyright 2011 See AUTHORS file.\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ ******************************************************************************/\r
+\r
+package com.badlogic.gdx.math;\r
+\r
+import java.io.Serializable;\r
+\r
+/** Encapsulates a column major 4 by 4 matrix. You can access the linear array for use with OpenGL via the public\r
+ * {@link Matrix4#val} member. Like the {@link Vector3} class it allows to chain methods by returning a reference to itself.\r
+ * \r
+ * @author badlogicgames@gmail.com */\r
+public class Matrix4 implements Serializable {\r
+ private static final long serialVersionUID = -2717655254359579617L;\r
+ public static final int M00 = 0;// 0;\r
+ public static final int M01 = 4;// 1;\r
+ public static final int M02 = 8;// 2;\r
+ public static final int M03 = 12;// 3;\r
+ public static final int M10 = 1;// 4;\r
+ public static final int M11 = 5;// 5;\r
+ public static final int M12 = 9;// 6;\r
+ public static final int M13 = 13;// 7;\r
+ public static final int M20 = 2;// 8;\r
+ public static final int M21 = 6;// 9;\r
+ public static final int M22 = 10;// 10;\r
+ public static final int M23 = 14;// 11;\r
+ public static final int M30 = 3;// 12;\r
+ public static final int M31 = 7;// 13;\r
+ public static final int M32 = 11;// 14;\r
+ public static final int M33 = 15;// 15;\r
+\r
+ public final float tmp[] = new float[16];\r
+ public final float val[] = new float[16];\r
+\r
+ /** Constructs an identity matrix */\r
+ public Matrix4 () {\r
+ val[M00] = 1f;\r
+ val[M11] = 1f;\r
+ val[M22] = 1f;\r
+ val[M33] = 1f;\r
+ }\r
+\r
+ /** Constructs a matrix from the given matrix\r
+ * \r
+ * @param matrix The matrix */\r
+ public Matrix4 (Matrix4 matrix) {\r
+ this.set(matrix);\r
+ }\r
+\r
+ /** Constructs a matrix from the given float array. The array must have at least 16 elements\r
+ * @param values The float array */\r
+ public Matrix4 (float[] values) {\r
+ this.set(values);\r
+ }\r
+\r
+ /** Constructs a rotation matrix from the given {@link Quaternion}\r
+ * @param quaternion The quaternion */\r
+ public Matrix4 (Quaternion quaternion) {\r
+ this.set(quaternion);\r
+ }\r
+\r
+ /** Sets the matrix to the given matrix.\r
+ * \r
+ * @param matrix The matrix\r
+ * @return This matrix for chaining */\r
+ public Matrix4 set (Matrix4 matrix) {\r
+ return this.set(matrix.val);\r
+ }\r
+\r
+ /** Sets the matrix to the given matrix as a float array. The float array must have at least 16 elements.\r
+ * \r
+ * @param values The matrix\r
+ * @return This matrix for chaining */\r
+ public Matrix4 set (float[] values) {\r
+ val[M00] = values[M00];\r
+ val[M10] = values[M10];\r
+ val[M20] = values[M20];\r
+ val[M30] = values[M30];\r
+ val[M01] = values[M01];\r
+ val[M11] = values[M11];\r
+ val[M21] = values[M21];\r
+ val[M31] = values[M31];\r
+ val[M02] = values[M02];\r
+ val[M12] = values[M12];\r
+ val[M22] = values[M22];\r
+ val[M32] = values[M32];\r
+ val[M03] = values[M03];\r
+ val[M13] = values[M13];\r
+ val[M23] = values[M23];\r
+ val[M33] = values[M33];\r
+ return this;\r
+ }\r
+\r
+ /** Sets the matrix to a rotation matrix representing the quaternion.\r
+ * \r
+ * @param quaternion The quaternion\r
+ * @return This matrix for chaining */\r
+ public Matrix4 set (Quaternion quaternion) {\r
+ // Compute quaternion factors\r
+ float l_xx = quaternion.x * quaternion.x;\r
+ float l_xy = quaternion.x * quaternion.y;\r
+ float l_xz = quaternion.x * quaternion.z;\r
+ float l_xw = quaternion.x * quaternion.w;\r
+ float l_yy = quaternion.y * quaternion.y;\r
+ float l_yz = quaternion.y * quaternion.z;\r
+ float l_yw = quaternion.y * quaternion.w;\r
+ float l_zz = quaternion.z * quaternion.z;\r
+ float l_zw = quaternion.z * quaternion.w;\r
+ // Set matrix from quaternion\r
+ val[M00] = 1 - 2 * (l_yy + l_zz);\r
+ val[M01] = 2 * (l_xy - l_zw);\r
+ val[M02] = 2 * (l_xz + l_yw);\r
+ val[M03] = 0;\r
+ val[M10] = 2 * (l_xy + l_zw);\r
+ val[M11] = 1 - 2 * (l_xx + l_zz);\r
+ val[M12] = 2 * (l_yz - l_xw);\r
+ val[M13] = 0;\r
+ val[M20] = 2 * (l_xz - l_yw);\r
+ val[M21] = 2 * (l_yz + l_xw);\r
+ val[M22] = 1 - 2 * (l_xx + l_yy);\r
+ val[M23] = 0;\r
+ val[M30] = 0;\r
+ val[M31] = 0;\r
+ val[M32] = 0;\r
+ val[M33] = 1;\r
+ return this;\r
+ }\r
+\r
+ /** Sets the four columns of the matrix which correspond to the x-, y- and z-axis of the vector space this matrix creates as\r
+ * well as the 4th column representing the translation of any point that is multiplied by this matrix.\r
+ * \r
+ * @param xAxis The x-axis\r
+ * @param yAxis The y-axis\r
+ * @param zAxis The z-axis\r
+ * @param pos The translation vector */\r
+ public void set (Vector3 xAxis, Vector3 yAxis, Vector3 zAxis, Vector3 pos) {\r
+ val[M00] = xAxis.x;\r
+ val[M01] = xAxis.y;\r
+ val[M02] = xAxis.z;\r
+ val[M10] = yAxis.x;\r
+ val[M11] = yAxis.y;\r
+ val[M12] = yAxis.z;\r
+ val[M20] = -zAxis.x;\r
+ val[M21] = -zAxis.y;\r
+ val[M22] = -zAxis.z;\r
+ val[M03] = pos.x;\r
+ val[M13] = pos.y;\r
+ val[M23] = pos.z;\r
+ val[M30] = 0;\r
+ val[M31] = 0;\r
+ val[M32] = 0;\r
+ val[M33] = 1;\r
+ }\r
+\r
+ /** @return a copy of this matrix */\r
+ public Matrix4 cpy () {\r
+ return new Matrix4(this);\r
+ }\r
+\r
+ /** Adds a translational component to the matrix in the 4th column. The other columns are untouched.\r
+ * \r
+ * @param vector The translation vector\r
+ * @return This matrix for chaining */\r
+ public Matrix4 trn (Vector3 vector) {\r
+ val[M03] += vector.x;\r
+ val[M13] += vector.y;\r
+ val[M23] += vector.z;\r
+ return this;\r
+ }\r
+\r
+ /** Adds a translational component to the matrix in the 4th column. The other columns are untouched.\r
+ * \r
+ * @param x The x-component of the translation vector\r
+ * @param y The y-component of the translation vector\r
+ * @param z The z-component of the translation vector\r
+ * @return This matrix for chaining */\r
+ public Matrix4 trn (float x, float y, float z) {\r
+ val[M03] += x;\r
+ val[M13] += y;\r
+ val[M23] += z;\r
+ return this;\r
+ }\r
+\r
+ /** @return the backing float array */\r
+ public float[] getValues () {\r
+ return val;\r
+ }\r
+\r
+ /** Multiplies this matrix with the given matrix, storing the result in this matrix.\r
+ * \r
+ * @param matrix The other matrix\r
+ * @return This matrix for chaining. */\r
+ public Matrix4 mul (Matrix4 matrix) {\r
+ tmp[M00] = val[M00] * matrix.val[M00] + val[M01] * matrix.val[M10] + val[M02] * matrix.val[M20] + val[M03]\r
+ * matrix.val[M30];\r
+ tmp[M01] = val[M00] * matrix.val[M01] + val[M01] * matrix.val[M11] + val[M02] * matrix.val[M21] + val[M03]\r
+ * matrix.val[M31];\r
+ tmp[M02] = val[M00] * matrix.val[M02] + val[M01] * matrix.val[M12] + val[M02] * matrix.val[M22] + val[M03]\r
+ * matrix.val[M32];\r
+ tmp[M03] = val[M00] * matrix.val[M03] + val[M01] * matrix.val[M13] + val[M02] * matrix.val[M23] + val[M03]\r
+ * matrix.val[M33];\r
+ tmp[M10] = val[M10] * matrix.val[M00] + val[M11] * matrix.val[M10] + val[M12] * matrix.val[M20] + val[M13]\r
+ * matrix.val[M30];\r
+ tmp[M11] = val[M10] * matrix.val[M01] + val[M11] * matrix.val[M11] + val[M12] * matrix.val[M21] + val[M13]\r
+ * matrix.val[M31];\r
+ tmp[M12] = val[M10] * matrix.val[M02] + val[M11] * matrix.val[M12] + val[M12] * matrix.val[M22] + val[M13]\r
+ * matrix.val[M32];\r
+ tmp[M13] = val[M10] * matrix.val[M03] + val[M11] * matrix.val[M13] + val[M12] * matrix.val[M23] + val[M13]\r
+ * matrix.val[M33];\r
+ tmp[M20] = val[M20] * matrix.val[M00] + val[M21] * matrix.val[M10] + val[M22] * matrix.val[M20] + val[M23]\r
+ * matrix.val[M30];\r
+ tmp[M21] = val[M20] * matrix.val[M01] + val[M21] * matrix.val[M11] + val[M22] * matrix.val[M21] + val[M23]\r
+ * matrix.val[M31];\r
+ tmp[M22] = val[M20] * matrix.val[M02] + val[M21] * matrix.val[M12] + val[M22] * matrix.val[M22] + val[M23]\r
+ * matrix.val[M32];\r
+ tmp[M23] = val[M20] * matrix.val[M03] + val[M21] * matrix.val[M13] + val[M22] * matrix.val[M23] + val[M23]\r
+ * matrix.val[M33];\r
+ tmp[M30] = val[M30] * matrix.val[M00] + val[M31] * matrix.val[M10] + val[M32] * matrix.val[M20] + val[M33]\r
+ * matrix.val[M30];\r
+ tmp[M31] = val[M30] * matrix.val[M01] + val[M31] * matrix.val[M11] + val[M32] * matrix.val[M21] + val[M33]\r
+ * matrix.val[M31];\r
+ tmp[M32] = val[M30] * matrix.val[M02] + val[M31] * matrix.val[M12] + val[M32] * matrix.val[M22] + val[M33]\r
+ * matrix.val[M32];\r
+ tmp[M33] = val[M30] * matrix.val[M03] + val[M31] * matrix.val[M13] + val[M32] * matrix.val[M23] + val[M33]\r
+ * matrix.val[M33];\r
+ return this.set(tmp);\r
+ }\r
+\r
+ /** Transposes the matrix\r
+ * \r
+ * @return This matrix for chaining */\r
+ public Matrix4 tra () {\r
+ tmp[M00] = val[M00];\r
+ tmp[M01] = val[M10];\r
+ tmp[M02] = val[M20];\r
+ tmp[M03] = val[M30];\r
+ tmp[M10] = val[M01];\r
+ tmp[M11] = val[M11];\r
+ tmp[M12] = val[M21];\r
+ tmp[M13] = val[M31];\r
+ tmp[M20] = val[M02];\r
+ tmp[M21] = val[M12];\r
+ tmp[M22] = val[M22];\r
+ tmp[M23] = val[M32];\r
+ tmp[M30] = val[M03];\r
+ tmp[M31] = val[M13];\r
+ tmp[M32] = val[M23];\r
+ tmp[M33] = val[M33];\r
+ return this.set(tmp);\r
+ }\r
+\r
+ /** Sets the matrix to an identity matrix\r
+ * \r
+ * @return This matrix for chaining */\r
+ public Matrix4 idt () {\r
+ val[M00] = 1;\r
+ val[M01] = 0;\r
+ val[M02] = 0;\r
+ val[M03] = 0;\r
+ val[M10] = 0;\r
+ val[M11] = 1;\r
+ val[M12] = 0;\r
+ val[M13] = 0;\r
+ val[M20] = 0;\r
+ val[M21] = 0;\r
+ val[M22] = 1;\r
+ val[M23] = 0;\r
+ val[M30] = 0;\r
+ val[M31] = 0;\r
+ val[M32] = 0;\r
+ val[M33] = 1;\r
+ return this;\r
+ }\r
+\r
+ /** Inverts the matrix. Throws a RuntimeException in case the matrix is not invertible. Stores the result in this matrix\r
+ * \r
+ * @return This matrix for chaining */\r
+ public Matrix4 inv () {\r
+ float l_det = val[M30] * val[M21] * val[M12] * val[M03] - val[M20] * val[M31] * val[M12] * val[M03] - val[M30] * val[M11]\r
+ * val[M22] * val[M03] + val[M10] * val[M31] * val[M22] * val[M03] + val[M20] * val[M11] * val[M32] * val[M03] - val[M10]\r
+ * val[M21] * val[M32] * val[M03] - val[M30] * val[M21] * val[M02] * val[M13] + val[M20] * val[M31] * val[M02] * val[M13]\r
+ + val[M30] * val[M01] * val[M22] * val[M13] - val[M00] * val[M31] * val[M22] * val[M13] - val[M20] * val[M01] * val[M32]\r
+ * val[M13] + val[M00] * val[M21] * val[M32] * val[M13] + val[M30] * val[M11] * val[M02] * val[M23] - val[M10] * val[M31]\r
+ * val[M02] * val[M23] - val[M30] * val[M01] * val[M12] * val[M23] + val[M00] * val[M31] * val[M12] * val[M23] + val[M10]\r
+ * val[M01] * val[M32] * val[M23] - val[M00] * val[M11] * val[M32] * val[M23] - val[M20] * val[M11] * val[M02] * val[M33]\r
+ + val[M10] * val[M21] * val[M02] * val[M33] + val[M20] * val[M01] * val[M12] * val[M33] - val[M00] * val[M21] * val[M12]\r
+ * val[M33] - val[M10] * val[M01] * val[M22] * val[M33] + val[M00] * val[M11] * val[M22] * val[M33];\r
+ if (l_det == 0f) throw new RuntimeException("non-invertible matrix");\r
+ float inv_det = 1.0f / l_det;\r
+ tmp[M00] = val[M12] * val[M23] * val[M31] - val[M13] * val[M22] * val[M31] + val[M13] * val[M21] * val[M32] - val[M11]\r
+ * val[M23] * val[M32] - val[M12] * val[M21] * val[M33] + val[M11] * val[M22] * val[M33];\r
+ tmp[M01] = val[M03] * val[M22] * val[M31] - val[M02] * val[M23] * val[M31] - val[M03] * val[M21] * val[M32] + val[M01]\r
+ * val[M23] * val[M32] + val[M02] * val[M21] * val[M33] - val[M01] * val[M22] * val[M33];\r
+ tmp[M02] = val[M02] * val[M13] * val[M31] - val[M03] * val[M12] * val[M31] + val[M03] * val[M11] * val[M32] - val[M01]\r
+ * val[M13] * val[M32] - val[M02] * val[M11] * val[M33] + val[M01] * val[M12] * val[M33];\r
+ tmp[M03] = val[M03] * val[M12] * val[M21] - val[M02] * val[M13] * val[M21] - val[M03] * val[M11] * val[M22] + val[M01]\r
+ * val[M13] * val[M22] + val[M02] * val[M11] * val[M23] - val[M01] * val[M12] * val[M23];\r
+ tmp[M10] = val[M13] * val[M22] * val[M30] - val[M12] * val[M23] * val[M30] - val[M13] * val[M20] * val[M32] + val[M10]\r
+ * val[M23] * val[M32] + val[M12] * val[M20] * val[M33] - val[M10] * val[M22] * val[M33];\r
+ tmp[M11] = val[M02] * val[M23] * val[M30] - val[M03] * val[M22] * val[M30] + val[M03] * val[M20] * val[M32] - val[M00]\r
+ * val[M23] * val[M32] - val[M02] * val[M20] * val[M33] + val[M00] * val[M22] * val[M33];\r
+ tmp[M12] = val[M03] * val[M12] * val[M30] - val[M02] * val[M13] * val[M30] - val[M03] * val[M10] * val[M32] + val[M00]\r
+ * val[M13] * val[M32] + val[M02] * val[M10] * val[M33] - val[M00] * val[M12] * val[M33];\r
+ tmp[M13] = val[M02] * val[M13] * val[M20] - val[M03] * val[M12] * val[M20] + val[M03] * val[M10] * val[M22] - val[M00]\r
+ * val[M13] * val[M22] - val[M02] * val[M10] * val[M23] + val[M00] * val[M12] * val[M23];\r
+ tmp[M20] = val[M11] * val[M23] * val[M30] - val[M13] * val[M21] * val[M30] + val[M13] * val[M20] * val[M31] - val[M10]\r
+ * val[M23] * val[M31] - val[M11] * val[M20] * val[M33] + val[M10] * val[M21] * val[M33];\r
+ tmp[M21] = val[M03] * val[M21] * val[M30] - val[M01] * val[M23] * val[M30] - val[M03] * val[M20] * val[M31] + val[M00]\r
+ * val[M23] * val[M31] + val[M01] * val[M20] * val[M33] - val[M00] * val[M21] * val[M33];\r
+ tmp[M22] = val[M01] * val[M13] * val[M30] - val[M03] * val[M11] * val[M30] + val[M03] * val[M10] * val[M31] - val[M00]\r
+ * val[M13] * val[M31] - val[M01] * val[M10] * val[M33] + val[M00] * val[M11] * val[M33];\r
+ tmp[M23] = val[M03] * val[M11] * val[M20] - val[M01] * val[M13] * val[M20] - val[M03] * val[M10] * val[M21] + val[M00]\r
+ * val[M13] * val[M21] + val[M01] * val[M10] * val[M23] - val[M00] * val[M11] * val[M23];\r
+ tmp[M30] = val[M12] * val[M21] * val[M30] - val[M11] * val[M22] * val[M30] - val[M12] * val[M20] * val[M31] + val[M10]\r
+ * val[M22] * val[M31] + val[M11] * val[M20] * val[M32] - val[M10] * val[M21] * val[M32];\r
+ tmp[M31] = val[M01] * val[M22] * val[M30] - val[M02] * val[M21] * val[M30] + val[M02] * val[M20] * val[M31] - val[M00]\r
+ * val[M22] * val[M31] - val[M01] * val[M20] * val[M32] + val[M00] * val[M21] * val[M32];\r
+ tmp[M32] = val[M02] * val[M11] * val[M30] - val[M01] * val[M12] * val[M30] - val[M02] * val[M10] * val[M31] + val[M00]\r
+ * val[M12] * val[M31] + val[M01] * val[M10] * val[M32] - val[M00] * val[M11] * val[M32];\r
+ tmp[M33] = val[M01] * val[M12] * val[M20] - val[M02] * val[M11] * val[M20] + val[M02] * val[M10] * val[M21] - val[M00]\r
+ * val[M12] * val[M21] - val[M01] * val[M10] * val[M22] + val[M00] * val[M11] * val[M22];\r
+ val[M00] = tmp[M00] * inv_det;\r
+ val[M01] = tmp[M01] * inv_det;\r
+ val[M02] = tmp[M02] * inv_det;\r
+ val[M03] = tmp[M03] * inv_det;\r
+ val[M10] = tmp[M10] * inv_det;\r
+ val[M11] = tmp[M11] * inv_det;\r
+ val[M12] = tmp[M12] * inv_det;\r
+ val[M13] = tmp[M13] * inv_det;\r
+ val[M20] = tmp[M20] * inv_det;\r
+ val[M21] = tmp[M21] * inv_det;\r
+ val[M22] = tmp[M22] * inv_det;\r
+ val[M23] = tmp[M23] * inv_det;\r
+ val[M30] = tmp[M30] * inv_det;\r
+ val[M31] = tmp[M31] * inv_det;\r
+ val[M32] = tmp[M32] * inv_det;\r
+ val[M33] = tmp[M33] * inv_det;\r
+ return this;\r
+ }\r
+\r
+ /** @return The determinant of this matrix */\r
+ public float det () {\r
+ return val[M30] * val[M21] * val[M12] * val[M03] - val[M20] * val[M31] * val[M12] * val[M03] - val[M30] * val[M11]\r
+ * val[M22] * val[M03] + val[M10] * val[M31] * val[M22] * val[M03] + val[M20] * val[M11] * val[M32] * val[M03] - val[M10]\r
+ * val[M21] * val[M32] * val[M03] - val[M30] * val[M21] * val[M02] * val[M13] + val[M20] * val[M31] * val[M02] * val[M13]\r
+ + val[M30] * val[M01] * val[M22] * val[M13] - val[M00] * val[M31] * val[M22] * val[M13] - val[M20] * val[M01] * val[M32]\r
+ * val[M13] + val[M00] * val[M21] * val[M32] * val[M13] + val[M30] * val[M11] * val[M02] * val[M23] - val[M10] * val[M31]\r
+ * val[M02] * val[M23] - val[M30] * val[M01] * val[M12] * val[M23] + val[M00] * val[M31] * val[M12] * val[M23] + val[M10]\r
+ * val[M01] * val[M32] * val[M23] - val[M00] * val[M11] * val[M32] * val[M23] - val[M20] * val[M11] * val[M02] * val[M33]\r
+ + val[M10] * val[M21] * val[M02] * val[M33] + val[M20] * val[M01] * val[M12] * val[M33] - val[M00] * val[M21] * val[M12]\r
+ * val[M33] - val[M10] * val[M01] * val[M22] * val[M33] + val[M00] * val[M11] * val[M22] * val[M33];\r
+ }\r
+\r
+ /** Sets the matrix to a projection matrix with a near- and far plane, a field of view in degrees and an aspect ratio.\r
+ * \r
+ * @param near The near plane\r
+ * @param far The far plane\r
+ * @param fov The field of view in degrees\r
+ * @param aspectRatio The aspect ratio\r
+ * @return This matrix for chaining */\r
+ public Matrix4 setToProjection (float near, float far, float fov, float aspectRatio) {\r
+ this.idt();\r
+ float l_fd = (float)(1.0 / Math.tan((fov * (Math.PI / 180)) / 2.0));\r
+ float l_a1 = (far + near) / (near - far);\r
+ float l_a2 = (2 * far * near) / (near - far);\r
+ val[M00] = l_fd / aspectRatio;\r
+ val[M10] = 0;\r
+ val[M20] = 0;\r
+ val[M30] = 0;\r
+ val[M01] = 0;\r
+ val[M11] = l_fd;\r
+ val[M21] = 0;\r
+ val[M31] = 0;\r
+ val[M02] = 0;\r
+ val[M12] = 0;\r
+ val[M22] = l_a1;\r
+ val[M32] = -1;\r
+ val[M03] = 0;\r
+ val[M13] = 0;\r
+ val[M23] = l_a2;\r
+ val[M33] = 0;\r
+\r
+ return this;\r
+ }\r
+\r
+ /** Sets this matrix to an orthographic projection matrix with the origin at (x,y) extending by width and height. The near plane\r
+ * is set to 0, the far plane is set to 1.\r
+ * \r
+ * @param x The x-coordinate of the origin\r
+ * @param y The y-coordinate of the origin\r
+ * @param width The width\r
+ * @param height The height\r
+ * @return This matrix for chaining */\r
+ public Matrix4 setToOrtho2D (float x, float y, float width, float height) {\r
+ setToOrtho(x, x + width, y, y + height, 0, 1);\r
+ return this;\r
+ }\r
+\r
+ /** Sets this matrix to an orthographic projection matrix with the origin at (x,y) extending by width and height, having a near\r
+ * and far plane.\r
+ * \r
+ * @param x The x-coordinate of the origin\r
+ * @param y The y-coordinate of the origin\r
+ * @param width The width\r
+ * @param height The height\r
+ * @param near The near plane\r
+ * @param far The far plane\r
+ * @return This matrix for chaining */\r
+ public Matrix4 setToOrtho2D (float x, float y, float width, float height, float near, float far) {\r
+ setToOrtho(x, x + width, y, y + height, near, far);\r
+ return this;\r
+ }\r
+\r
+ /** Sets the matrix to an orthographic projection like glOrtho (http://www.opengl.org/sdk/docs/man/xhtml/glOrtho.xml) following\r
+ * the OpenGL equivalent\r
+ * \r
+ * @param left The left clipping plane\r
+ * @param right The right clipping plane\r
+ * @param bottom The bottom clipping plane\r
+ * @param top The top clipping plane\r
+ * @param near The near clipping plane\r
+ * @param far The far clipping plane\r
+ * @return This matrix for chaining */\r
+ public Matrix4 setToOrtho (float left, float right, float bottom, float top, float near, float far) {\r
+\r
+ this.idt();\r
+ float x_orth = 2 / (right - left);\r
+ float y_orth = 2 / (top - bottom);\r
+ float z_orth = -2 / (far - near);\r
+\r
+ float tx = -(right + left) / (right - left);\r
+ float ty = -(top + bottom) / (top - bottom);\r
+ float tz = -(far + near) / (far - near);\r
+\r
+ val[M00] = x_orth;\r
+ val[M10] = 0;\r
+ val[M20] = 0;\r
+ val[M30] = 0;\r
+ val[M01] = 0;\r
+ val[M11] = y_orth;\r
+ val[M21] = 0;\r
+ val[M31] = 0;\r
+ val[M02] = 0;\r
+ val[M12] = 0;\r
+ val[M22] = z_orth;\r
+ val[M32] = 0;\r
+ val[M03] = tx;\r
+ val[M13] = ty;\r
+ val[M23] = tz;\r
+ val[M33] = 1;\r
+\r
+ return this;\r
+ }\r
+\r
+ /** Sets this matrix to a translation matrix, overwriting it first by an identity matrix and then setting the 4th column to the\r
+ * translation vector.\r
+ * \r
+ * @param vector The translation vector\r
+ * @return This matrix for chaining */\r
+ public Matrix4 setToTranslation (Vector3 vector) {\r
+ this.idt();\r
+ val[M03] = vector.x;\r
+ val[M13] = vector.y;\r
+ val[M23] = vector.z;\r
+ return this;\r
+ }\r
+\r
+ /** Sets this matrix to a translation matrix, overwriting it first by an identity matrix and then setting the 4th column to the\r
+ * translation vector.\r
+ * \r
+ * @param x The x-component of the translation vector\r
+ * @param y The y-component of the translation vector\r
+ * @param z The z-component of the translation vector\r
+ * @return This matrix for chaining */\r
+ public Matrix4 setToTranslation (float x, float y, float z) {\r
+ idt();\r
+ val[M03] = x;\r
+ val[M13] = y;\r
+ val[M23] = z;\r
+ return this;\r
+ }\r
+\r
+ /** Sets this matrix to a translation and scaling matrix by first overwritting it with an identity and then setting the\r
+ * translation vector in the 4th column and the scaling vector in the diagonal.\r
+ * \r
+ * @param translation The translation vector\r
+ * @param scaling The scaling vector\r
+ * @return This matrix for chaining */\r
+ public Matrix4 setToTranslationAndScaling (Vector3 translation, Vector3 scaling) {\r
+ idt();\r
+ val[M03] = translation.x;\r
+ val[M13] = translation.y;\r
+ val[M23] = translation.z;\r
+ val[M00] = scaling.x;\r
+ val[M11] = scaling.y;\r
+ val[M22] = scaling.z;\r
+ return this;\r
+ }\r
+\r
+ /** Sets this matrix to a translation and scaling matrix by first overwritting it with an identity and then setting the\r
+ * translation vector in the 4th column and the scaling vector in the diagonal.\r
+ * \r
+ * @param translationX The x-component of the translation vector\r
+ * @param translationY The y-component of the translation vector\r
+ * @param translationZ The z-component of the translation vector\r
+ * @param scalingX The x-component of the scaling vector\r
+ * @param scalingY The x-component of the scaling vector\r
+ * @param scalingZ The x-component of the scaling vector\r
+ * @return This matrix for chaining */\r
+ public Matrix4 setToTranslationAndScaling (float translationX, float translationY, float translationZ, float scalingX,\r
+ float scalingY, float scalingZ) {\r
+ this.idt();\r
+ val[M03] = translationX;\r
+ val[M13] = translationY;\r
+ val[M23] = translationZ;\r
+ val[M00] = scalingX;\r
+ val[M11] = scalingY;\r
+ val[M22] = scalingZ;\r
+ return this;\r
+ }\r
+\r
+ static Quaternion quat = new Quaternion();\r
+\r
+ /** Sets the matrix to a rotation matrix around the given axis.\r
+ * \r
+ * @param axis The axis\r
+ * @param angle The angle in degrees\r
+ * @return This matrix for chaining */\r
+ public Matrix4 setToRotation (Vector3 axis, float angle) {\r
+ idt();\r
+ if (angle == 0) return this;\r
+ return this.set(quat.set(axis, angle));\r
+ }\r
+\r
+ /** Sets the matrix to a rotation matrix around the given axis.\r
+ * \r
+ * @param axisX The x-component of the axis\r
+ * @param axisY The y-component of the axis\r
+ * @param axisZ The z-component of the axis\r
+ * @param angle The angle in degrees\r
+ * @return This matrix for chaining */\r
+ public Matrix4 setToRotation (float axisX, float axisY, float axisZ, float angle) {\r
+ idt();\r
+ if (angle == 0) return this;\r
+ return this.set(quat.set(tmpV.set(axisX, axisY, axisZ), angle));\r
+ }\r
+\r
+ static final Vector3 tmpV = new Vector3();\r
+\r
+ /** Sets this matrix to a rotation matrix from the given euler angles.\r
+ * @param yaw the yaw in degrees\r
+ * @param pitch the pitch in degress\r
+ * @param roll the roll in degrees\r
+ * @return this matrix */\r
+ public Matrix4 setFromEulerAngles (float yaw, float pitch, float roll) {\r
+ idt();\r
+ quat.setEulerAngles(yaw, pitch, roll);\r
+ return this.set(quat);\r
+ }\r
+\r
+ /** Sets this matrix to a scaling matrix\r
+ * \r
+ * @param vector The scaling vector\r
+ * @return This matrix for chaining. */\r
+ public Matrix4 setToScaling (Vector3 vector) {\r
+ idt();\r
+ val[M00] = vector.x;\r
+ val[M11] = vector.y;\r
+ val[M22] = vector.z;\r
+ return this;\r
+ }\r
+\r
+ /** Sets this matrix to a scaling matrix\r
+ * \r
+ * @param x The x-component of the scaling vector\r
+ * @param y The y-component of the scaling vector\r
+ * @param z The z-component of the scaling vector\r
+ * @return This matrix for chaining. */\r
+ public Matrix4 setToScaling (float x, float y, float z) {\r
+ idt();\r
+ val[M00] = x;\r
+ val[M11] = y;\r
+ val[M22] = z;\r
+ return this;\r
+ }\r
+\r
+ static Vector3 l_vez = new Vector3();\r
+ static Vector3 l_vex = new Vector3();\r
+ static Vector3 l_vey = new Vector3();\r
+\r
+ /** Sets the matrix to a look at matrix with a direction and an up vector. Multiply with a translation matrix to get a camera\r
+ * model view matrix.\r
+ * \r
+ * @param direction The direction vector\r
+ * @param up The up vector\r
+ * @return This matrix for chaining */\r
+ public Matrix4 setToLookAt (Vector3 direction, Vector3 up) {\r
+ l_vez.set(direction).nor();\r
+ l_vex.set(direction).nor();\r
+ l_vex.crs(up).nor();\r
+ l_vey.set(l_vex).crs(l_vez).nor();\r
+ idt();\r
+ val[M00] = l_vex.x;\r
+ val[M01] = l_vex.y;\r
+ val[M02] = l_vex.z;\r
+ val[M10] = l_vey.x;\r
+ val[M11] = l_vey.y;\r
+ val[M12] = l_vey.z;\r
+ val[M20] = -l_vez.x;\r
+ val[M21] = -l_vez.y;\r
+ val[M22] = -l_vez.z;\r
+\r
+ return this;\r
+ }\r
+\r
+ static final Vector3 tmpVec = new Vector3();\r
+ static final Matrix4 tmpMat = new Matrix4();\r
+\r
+ /** Sets this matrix to a look at matrix with the given position, target and up vector.\r
+ * \r
+ * @param position the position\r
+ * @param target the target\r
+ * @param up the up vector\r
+ * @return this matrix */\r
+ public Matrix4 setToLookAt (Vector3 position, Vector3 target, Vector3 up) {\r
+ tmpVec.set(target).sub(position);\r
+ setToLookAt(tmpVec, up);\r
+ this.mul(tmpMat.setToTranslation(position.tmp().mul(-1)));\r
+\r
+ return this;\r
+ }\r
+\r
+ static Vector3 right = new Vector3();\r
+ static Vector3 tmpForward = new Vector3();\r
+ static Vector3 tmpUp = new Vector3();\r
+\r
+ public Matrix4 setToWorld (Vector3 position, Vector3 forward, Vector3 up) {\r
+ tmpForward.set(forward).nor();\r
+ right.set(tmpForward).crs(up).nor();\r
+ tmpUp.set(right).crs(tmpForward).nor();\r
+\r
+ this.set(right, tmpUp, tmpForward, position);\r
+ return this;\r
+ }\r
+\r
+ /** {@inheritDoc} */\r
+ public String toString () {\r
+ return "[" + val[M00] + "|" + val[M01] + "|" + val[M02] + "|" + val[M03] + "]\n" + "[" + val[M10] + "|" + val[M11] + "|"\r
+ + val[M12] + "|" + val[M13] + "]\n" + "[" + val[M20] + "|" + val[M21] + "|" + val[M22] + "|" + val[M23] + "]\n" + "["\r
+ + val[M30] + "|" + val[M31] + "|" + val[M32] + "|" + val[M33] + "]\n";\r
+ }\r
+\r
+ /** Linearly interpolates between this matrix and the given matrix mixing by alpha\r
+ * @param matrix the matrix\r
+ * @param alpha the alpha value in the range [0,1] */\r
+ public void lerp (Matrix4 matrix, float alpha) {\r
+ for (int i = 0; i < 16; i++)\r
+ this.val[i] = this.val[i] * (1 - alpha) + matrix.val[i] * alpha;\r
+ }\r
+\r
+ /** Sets this matrix to the given 3x3 matrix. The third column of this matrix is set to (0,0,1,0).\r
+ * @param mat the matrix */\r
+ public Matrix4 set (Matrix3 mat) {\r
+ val[0] = mat.val[0];\r
+ val[1] = mat.val[1];\r
+ val[2] = mat.val[2];\r
+ val[3] = 0;\r
+ val[4] = mat.val[3];\r
+ val[5] = mat.val[4];\r
+ val[6] = mat.val[5];\r
+ val[7] = 0;\r
+ val[8] = 0;\r
+ val[9] = 0;\r
+ val[10] = 1;\r
+ val[11] = 0;\r
+ val[12] = mat.val[6];\r
+ val[13] = mat.val[7];\r
+ val[14] = 0;\r
+ val[15] = mat.val[8];\r
+ return this;\r
+ }\r
+\r
+ public Matrix4 scl (Vector3 scale) {\r
+ val[M00] *= scale.x;\r
+ val[M11] *= scale.y;\r
+ val[M22] *= scale.z;\r
+ return this;\r
+ }\r
+ \r
+ public Matrix4 scl (float scale) {\r
+ val[M00] *= scale;\r
+ val[M11] *= scale;\r
+ val[M22] *= scale;\r
+ return this;\r
+ }\r
+\r
+ public void getTranslation (Vector3 position) {\r
+ position.x = val[M03];\r
+ position.y = val[M13];\r
+ position.z = val[M23];\r
+ }\r
+\r
+ public void getRotation (Quaternion rotation) {\r
+ rotation.setFromMatrix(this);\r
+ }\r
+\r
+ /** removes the translational part and transposes the matrix. */\r
+ public Matrix4 toNormalMatrix () {\r
+ val[M03] = 0;\r
+ val[M13] = 0;\r
+ val[M23] = 0;\r
+ inv();\r
+ return tra();\r
+ }\r
+ \r
+ \r
+ static void matrix4_mul(float[] mata, float[] matb) {\r
+ float tmp[] = new float[16];\r
+ tmp[M00] = mata[M00] * matb[M00] + mata[M01] * matb[M10] + mata[M02] * matb[M20] + mata[M03] * matb[M30];\r
+ tmp[M01] = mata[M00] * matb[M01] + mata[M01] * matb[M11] + mata[M02] * matb[M21] + mata[M03] * matb[M31];\r
+ tmp[M02] = mata[M00] * matb[M02] + mata[M01] * matb[M12] + mata[M02] * matb[M22] + mata[M03] * matb[M32];\r
+ tmp[M03] = mata[M00] * matb[M03] + mata[M01] * matb[M13] + mata[M02] * matb[M23] + mata[M03] * matb[M33];\r
+ tmp[M10] = mata[M10] * matb[M00] + mata[M11] * matb[M10] + mata[M12] * matb[M20] + mata[M13] * matb[M30];\r
+ tmp[M11] = mata[M10] * matb[M01] + mata[M11] * matb[M11] + mata[M12] * matb[M21] + mata[M13] * matb[M31];\r
+ tmp[M12] = mata[M10] * matb[M02] + mata[M11] * matb[M12] + mata[M12] * matb[M22] + mata[M13] * matb[M32];\r
+ tmp[M13] = mata[M10] * matb[M03] + mata[M11] * matb[M13] + mata[M12] * matb[M23] + mata[M13] * matb[M33];\r
+ tmp[M20] = mata[M20] * matb[M00] + mata[M21] * matb[M10] + mata[M22] * matb[M20] + mata[M23] * matb[M30];\r
+ tmp[M21] = mata[M20] * matb[M01] + mata[M21] * matb[M11] + mata[M22] * matb[M21] + mata[M23] * matb[M31];\r
+ tmp[M22] = mata[M20] * matb[M02] + mata[M21] * matb[M12] + mata[M22] * matb[M22] + mata[M23] * matb[M32];\r
+ tmp[M23] = mata[M20] * matb[M03] + mata[M21] * matb[M13] + mata[M22] * matb[M23] + mata[M23] * matb[M33];\r
+ tmp[M30] = mata[M30] * matb[M00] + mata[M31] * matb[M10] + mata[M32] * matb[M20] + mata[M33] * matb[M30];\r
+ tmp[M31] = mata[M30] * matb[M01] + mata[M31] * matb[M11] + mata[M32] * matb[M21] + mata[M33] * matb[M31];\r
+ tmp[M32] = mata[M30] * matb[M02] + mata[M31] * matb[M12] + mata[M32] * matb[M22] + mata[M33] * matb[M32];\r
+ tmp[M33] = mata[M30] * matb[M03] + mata[M31] * matb[M13] + mata[M32] * matb[M23] + mata[M33] * matb[M33];\r
+ System.arraycopy(tmp, 0, mata, 0, 16);\r
+ }\r
+ \r
+ static float matrix4_det(float[] val) {\r
+ return val[M30] * val[M21] * val[M12] * val[M03] - val[M20] * val[M31] * val[M12] * val[M03] - val[M30] * val[M11]\r
+ * val[M22] * val[M03] + val[M10] * val[M31] * val[M22] * val[M03] + val[M20] * val[M11] * val[M32] * val[M03] - val[M10]\r
+ * val[M21] * val[M32] * val[M03] - val[M30] * val[M21] * val[M02] * val[M13] + val[M20] * val[M31] * val[M02] * val[M13]\r
+ + val[M30] * val[M01] * val[M22] * val[M13] - val[M00] * val[M31] * val[M22] * val[M13] - val[M20] * val[M01] * val[M32]\r
+ * val[M13] + val[M00] * val[M21] * val[M32] * val[M13] + val[M30] * val[M11] * val[M02] * val[M23] - val[M10] * val[M31]\r
+ * val[M02] * val[M23] - val[M30] * val[M01] * val[M12] * val[M23] + val[M00] * val[M31] * val[M12] * val[M23] + val[M10]\r
+ * val[M01] * val[M32] * val[M23] - val[M00] * val[M11] * val[M32] * val[M23] - val[M20] * val[M11] * val[M02] * val[M33]\r
+ + val[M10] * val[M21] * val[M02] * val[M33] + val[M20] * val[M01] * val[M12] * val[M33] - val[M00] * val[M21] * val[M12]\r
+ * val[M33] - val[M10] * val[M01] * val[M22] * val[M33] + val[M00] * val[M11] * val[M22] * val[M33];\r
+ }\r
+ \r
+ static boolean matrix4_inv(float[] val) {\r
+ float tmp[] = new float[16];\r
+ float l_det = matrix4_det(val);\r
+ if (l_det == 0) return false;\r
+ tmp[M00] = val[M12] * val[M23] * val[M31] - val[M13] * val[M22] * val[M31] + val[M13] * val[M21] * val[M32] - val[M11]\r
+ * val[M23] * val[M32] - val[M12] * val[M21] * val[M33] + val[M11] * val[M22] * val[M33];\r
+ tmp[M01] = val[M03] * val[M22] * val[M31] - val[M02] * val[M23] * val[M31] - val[M03] * val[M21] * val[M32] + val[M01]\r
+ * val[M23] * val[M32] + val[M02] * val[M21] * val[M33] - val[M01] * val[M22] * val[M33];\r
+ tmp[M02] = val[M02] * val[M13] * val[M31] - val[M03] * val[M12] * val[M31] + val[M03] * val[M11] * val[M32] - val[M01]\r
+ * val[M13] * val[M32] - val[M02] * val[M11] * val[M33] + val[M01] * val[M12] * val[M33];\r
+ tmp[M03] = val[M03] * val[M12] * val[M21] - val[M02] * val[M13] * val[M21] - val[M03] * val[M11] * val[M22] + val[M01]\r
+ * val[M13] * val[M22] + val[M02] * val[M11] * val[M23] - val[M01] * val[M12] * val[M23];\r
+ tmp[M10] = val[M13] * val[M22] * val[M30] - val[M12] * val[M23] * val[M30] - val[M13] * val[M20] * val[M32] + val[M10]\r
+ * val[M23] * val[M32] + val[M12] * val[M20] * val[M33] - val[M10] * val[M22] * val[M33];\r
+ tmp[M11] = val[M02] * val[M23] * val[M30] - val[M03] * val[M22] * val[M30] + val[M03] * val[M20] * val[M32] - val[M00]\r
+ * val[M23] * val[M32] - val[M02] * val[M20] * val[M33] + val[M00] * val[M22] * val[M33];\r
+ tmp[M12] = val[M03] * val[M12] * val[M30] - val[M02] * val[M13] * val[M30] - val[M03] * val[M10] * val[M32] + val[M00]\r
+ * val[M13] * val[M32] + val[M02] * val[M10] * val[M33] - val[M00] * val[M12] * val[M33];\r
+ tmp[M13] = val[M02] * val[M13] * val[M20] - val[M03] * val[M12] * val[M20] + val[M03] * val[M10] * val[M22] - val[M00]\r
+ * val[M13] * val[M22] - val[M02] * val[M10] * val[M23] + val[M00] * val[M12] * val[M23];\r
+ tmp[M20] = val[M11] * val[M23] * val[M30] - val[M13] * val[M21] * val[M30] + val[M13] * val[M20] * val[M31] - val[M10]\r
+ * val[M23] * val[M31] - val[M11] * val[M20] * val[M33] + val[M10] * val[M21] * val[M33];\r
+ tmp[M21] = val[M03] * val[M21] * val[M30] - val[M01] * val[M23] * val[M30] - val[M03] * val[M20] * val[M31] + val[M00]\r
+ * val[M23] * val[M31] + val[M01] * val[M20] * val[M33] - val[M00] * val[M21] * val[M33];\r
+ tmp[M22] = val[M01] * val[M13] * val[M30] - val[M03] * val[M11] * val[M30] + val[M03] * val[M10] * val[M31] - val[M00]\r
+ * val[M13] * val[M31] - val[M01] * val[M10] * val[M33] + val[M00] * val[M11] * val[M33];\r
+ tmp[M23] = val[M03] * val[M11] * val[M20] - val[M01] * val[M13] * val[M20] - val[M03] * val[M10] * val[M21] + val[M00]\r
+ * val[M13] * val[M21] + val[M01] * val[M10] * val[M23] - val[M00] * val[M11] * val[M23];\r
+ tmp[M30] = val[M12] * val[M21] * val[M30] - val[M11] * val[M22] * val[M30] - val[M12] * val[M20] * val[M31] + val[M10]\r
+ * val[M22] * val[M31] + val[M11] * val[M20] * val[M32] - val[M10] * val[M21] * val[M32];\r
+ tmp[M31] = val[M01] * val[M22] * val[M30] - val[M02] * val[M21] * val[M30] + val[M02] * val[M20] * val[M31] - val[M00]\r
+ * val[M22] * val[M31] - val[M01] * val[M20] * val[M32] + val[M00] * val[M21] * val[M32];\r
+ tmp[M32] = val[M02] * val[M11] * val[M30] - val[M01] * val[M12] * val[M30] - val[M02] * val[M10] * val[M31] + val[M00]\r
+ * val[M12] * val[M31] + val[M01] * val[M10] * val[M32] - val[M00] * val[M11] * val[M32];\r
+ tmp[M33] = val[M01] * val[M12] * val[M20] - val[M02] * val[M11] * val[M20] + val[M02] * val[M10] * val[M21] - val[M00]\r
+ * val[M12] * val[M21] - val[M01] * val[M10] * val[M22] + val[M00] * val[M11] * val[M22];\r
+ \r
+ float inv_det = 1.0f / l_det;\r
+ val[M00] = tmp[M00] * inv_det;\r
+ val[M01] = tmp[M01] * inv_det;\r
+ val[M02] = tmp[M02] * inv_det;\r
+ val[M03] = tmp[M03] * inv_det;\r
+ val[M10] = tmp[M10] * inv_det;\r
+ val[M11] = tmp[M11] * inv_det;\r
+ val[M12] = tmp[M12] * inv_det;\r
+ val[M13] = tmp[M13] * inv_det;\r
+ val[M20] = tmp[M20] * inv_det;\r
+ val[M21] = tmp[M21] * inv_det;\r
+ val[M22] = tmp[M22] * inv_det;\r
+ val[M23] = tmp[M23] * inv_det;\r
+ val[M30] = tmp[M30] * inv_det;\r
+ val[M31] = tmp[M31] * inv_det;\r
+ val[M32] = tmp[M32] * inv_det;\r
+ val[M33] = tmp[M33] * inv_det;\r
+ return true;\r
+ }\r
+ \r
+ static void matrix4_mulVec(float[] mat, float[] vec) {\r
+ float x = vec[0] * mat[M00] + vec[1] * mat[M01] + vec[2] * mat[M02] + mat[M03];\r
+ float y = vec[0] * mat[M10] + vec[1] * mat[M11] + vec[2] * mat[M12] + mat[M13];\r
+ float z = vec[0] * mat[M20] + vec[1] * mat[M21] + vec[2] * mat[M22] + mat[M23];\r
+ vec[0] = x;\r
+ vec[1] = y;\r
+ vec[2] = z;\r
+ }\r
+ \r
+ static void matrix4_proj(float[] mat, float[] vec) {\r
+ float inv_w = 1.0f / (vec[0] * mat[M30] + vec[1] * mat[M31] + vec[2] * mat[M32] + mat[M33]);\r
+ float x = (vec[0] * mat[M00] + vec[1] * mat[M01] + vec[2] * mat[M02] + mat[M03]) * inv_w;\r
+ float y = (vec[0] * mat[M10] + vec[1] * mat[M11] + vec[2] * mat[M12] + mat[M13]) * inv_w; \r
+ float z = (vec[0] * mat[M20] + vec[1] * mat[M21] + vec[2] * mat[M22] + mat[M23]) * inv_w;\r
+ vec[0] = x;\r
+ vec[1] = y;\r
+ vec[2] = z;\r
+ }\r
+ \r
+ static void matrix4_rot(float[] mat, float[] vec) {\r
+ float x = vec[0] * mat[M00] + vec[1] * mat[M01] + vec[2] * mat[M02];\r
+ float y = vec[0] * mat[M10] + vec[1] * mat[M11] + vec[2] * mat[M12];\r
+ float z = vec[0] * mat[M20] + vec[1] * mat[M21] + vec[2] * mat[M22];\r
+ vec[0] = x;\r
+ vec[1] = y;\r
+ vec[2] = z;\r
+ }\r
+\r
+ /** Multiplies the matrix mata with matrix matb, storing the result in mata. The arrays are assumed to hold 4x4 column major\r
+ * matrices as you can get from {@link Matrix4#val}. This is the same as {@link Matrix4#mul(Matrix4)}.\r
+ * \r
+ * @param mata the first matrix.\r
+ * @param matb the second matrix. */\r
+ public static void mul (float[] mata, float[] matb) {\r
+ matrix4_mul(mata, matb);\r
+ }\r
+\r
+ /** Multiplies the vector with the given matrix. The matrix array is assumed to hold a 4x4 column major matrix as you can get\r
+ * from {@link Matrix4#val}. The vector array is assumed to hold a 3-component vector, with x being the first element, y being\r
+ * the second and z being the last component. The result is stored in the vector array. This is the same as\r
+ * {@link Vector3#mul(Matrix4)}.\r
+ * @param mat the matrix\r
+ * @param vec the vector. */\r
+ public static void mulVec (float[] mat, float[] vec) {\r
+ matrix4_mulVec(mat, vec);\r
+ }\r
+\r
+ /** Multiplies the vectors with the given matrix. The matrix array is assumed to hold a 4x4 column major matrix as you can get\r
+ * from {@link Matrix4#val}. The vectors array is assumed to hold 3-component vectors. Offset specifies the offset into the\r
+ * array where the x-component of the first vector is located. The numVecs parameter specifies the number of vectors stored in\r
+ * the vectors array. The stride parameter specifies the number of floats between subsequent vectors and must be >= 3. This is\r
+ * the same as {@link Vector3#mul(Matrix4)} applied to multiple vectors.\r
+ * \r
+ * @param mat the matrix\r
+ * @param vecs the vectors\r
+ * @param offset the offset into the vectors array\r
+ * @param numVecs the number of vectors\r
+ * @param stride the stride between vectors in floats */\r
+ public static void mulVec (float[] mat, float[] vecs, int offset, int numVecs, int stride) {\r
+ // FIXME\r
+// float* vecPtr = vecs + offset;\r
+// for(int i = 0; i < numVecs; i++) {\r
+// matrix4_mulVec(mat, vecPtr);\r
+// vecPtr += stride;\r
+// }\r
+ }\r
+\r
+ /** Multiplies the vector with the given matrix, performing a division by w. The matrix array is assumed to hold a 4x4 column\r
+ * major matrix as you can get from {@link Matrix4#val}. The vector array is assumed to hold a 3-component vector, with x being\r
+ * the first element, y being the second and z being the last component. The result is stored in the vector array. This is the\r
+ * same as {@link Vector3#prj(Matrix4)}.\r
+ * @param mat the matrix\r
+ * @param vec the vector. */\r
+ public static void prj (float[] mat, float[] vec) {\r
+ matrix4_proj(mat, vec);\r
+ }\r
+\r
+ /** Multiplies the vectors with the given matrix, , performing a division by w. The matrix array is assumed to hold a 4x4 column\r
+ * major matrix as you can get from {@link Matrix4#val}. The vectors array is assumed to hold 3-component vectors. Offset\r
+ * specifies the offset into the array where the x-component of the first vector is located. The numVecs parameter specifies\r
+ * the number of vectors stored in the vectors array. The stride parameter specifies the number of floats between subsequent\r
+ * vectors and must be >= 3. This is the same as {@link Vector3#prj(Matrix4)} applied to multiple vectors.\r
+ * \r
+ * @param mat the matrix\r
+ * @param vecs the vectors\r
+ * @param offset the offset into the vectors array\r
+ * @param numVecs the number of vectors\r
+ * @param stride the stride between vectors in floats */\r
+ public static void prj (float[] mat, float[] vecs, int offset, int numVecs, int stride) {\r
+ // FIXME\r
+// float* vecPtr = vecs + offset;\r
+// for(int i = 0; i < numVecs; i++) {\r
+// matrix4_proj(mat, vecPtr);\r
+// vecPtr += stride;\r
+// }\r
+ }\r
+\r
+ /** Multiplies the vector with the top most 3x3 sub-matrix of the given matrix. The matrix array is assumed to hold a 4x4 column\r
+ * major matrix as you can get from {@link Matrix4#val}. The vector array is assumed to hold a 3-component vector, with x being\r
+ * the first element, y being the second and z being the last component. The result is stored in the vector array. This is the\r
+ * same as {@link Vector3#rot(Matrix4)}.\r
+ * @param mat the matrix\r
+ * @param vec the vector. */\r
+ public static void rot (float[] mat, float[] vec) {\r
+ matrix4_rot(mat, vec);\r
+ }\r
+\r
+ /** Multiplies the vectors with the top most 3x3 sub-matrix of the given matrix. The matrix array is assumed to hold a 4x4\r
+ * column major matrix as you can get from {@link Matrix4#val}. The vectors array is assumed to hold 3-component vectors.\r
+ * Offset specifies the offset into the array where the x-component of the first vector is located. The numVecs parameter\r
+ * specifies the number of vectors stored in the vectors array. The stride parameter specifies the number of floats between\r
+ * subsequent vectors and must be >= 3. This is the same as {@link Vector3#rot(Matrix4)} applied to multiple vectors.\r
+ * \r
+ * @param mat the matrix\r
+ * @param vecs the vectors\r
+ * @param offset the offset into the vectors array\r
+ * @param numVecs the number of vectors\r
+ * @param stride the stride between vectors in floats */\r
+ public static void rot (float[] mat, float[] vecs, int offset, int numVecs, int stride) {\r
+ // FIXME\r
+// float* vecPtr = vecs + offset;\r
+// for(int i = 0; i < numVecs; i++) {\r
+// matrix4_rot(mat, vecPtr);\r
+// vecPtr += stride;\r
+// }\r
+ }\r
+\r
+ /** Computes the inverse of the given matrix. The matrix array is assumed to hold a 4x4 column major matrix as you can get from\r
+ * {@link Matrix4#val}.\r
+ * @param values the matrix values.\r
+ * @return false in case the inverse could not be calculated, true otherwise. */\r
+ public static boolean inv (float[] values) {\r
+ return matrix4_inv(values);\r
+ }\r
+\r
+ /** Computes the determinante of the given matrix. The matrix array is assumed to hold a 4x4 column major matrix as you can get\r
+ * from {@link Matrix4#val}.\r
+ * @param values the matrix values.\r
+ * @return the determinante. */\r
+ public static float det (float[] values) {\r
+ return matrix4_det(values);\r
+ }\r
+\r
+ /** Postmultiplies this matrix by a translation matrix. Postmultiplication is also used by OpenGL ES'\r
+ * glTranslate/glRotate/glScale\r
+ * @param x\r
+ * @param y\r
+ * @param z\r
+ * @return this matrix for chaining */\r
+ public Matrix4 translate (float x, float y, float z) {\r
+ tmp[M00] = 1;\r
+ tmp[M01] = 0;\r
+ tmp[M02] = 0;\r
+ tmp[M03] = x;\r
+ tmp[M10] = 0;\r
+ tmp[M11] = 1;\r
+ tmp[M12] = 0;\r
+ tmp[M13] = y;\r
+ tmp[M20] = 0;\r
+ tmp[M21] = 0;\r
+ tmp[M22] = 1;\r
+ tmp[M23] = z;\r
+ tmp[M30] = 0;\r
+ tmp[M31] = 0;\r
+ tmp[M32] = 0;\r
+ tmp[M33] = 1;\r
+\r
+ mul(val, tmp);\r
+ return this;\r
+ }\r
+\r
+ /** Postmultiplies this matrix with a (counter-clockwise) rotation matrix. Postmultiplication is also used by OpenGL ES'\r
+ * glTranslate/glRotate/glScale\r
+ * @param axisX\r
+ * @param axisY\r
+ * @param axisZ\r
+ * @param angle the angle in degrees\r
+ * @return this matrix for chaining */\r
+ public Matrix4 rotate (float axisX, float axisY, float axisZ, float angle) {\r
+ if (angle == 0) return this;\r
+ quat.set(tmpV.set(axisX, axisY, axisZ), angle);\r
+ Quaternion quaternion = quat;\r
+ float l_xx = quaternion.x * quaternion.x;\r
+ float l_xy = quaternion.x * quaternion.y;\r
+ float l_xz = quaternion.x * quaternion.z;\r
+ float l_xw = quaternion.x * quaternion.w;\r
+ float l_yy = quaternion.y * quaternion.y;\r
+ float l_yz = quaternion.y * quaternion.z;\r
+ float l_yw = quaternion.y * quaternion.w;\r
+ float l_zz = quaternion.z * quaternion.z;\r
+ float l_zw = quaternion.z * quaternion.w;\r
+ // Set matrix from quaternion\r
+ tmp[M00] = 1 - 2 * (l_yy + l_zz);\r
+ tmp[M01] = 2 * (l_xy - l_zw);\r
+ tmp[M02] = 2 * (l_xz + l_yw);\r
+ tmp[M03] = 0;\r
+ tmp[M10] = 2 * (l_xy + l_zw);\r
+ tmp[M11] = 1 - 2 * (l_xx + l_zz);\r
+ tmp[M12] = 2 * (l_yz - l_xw);\r
+ tmp[M13] = 0;\r
+ tmp[M20] = 2 * (l_xz - l_yw);\r
+ tmp[M21] = 2 * (l_yz + l_xw);\r
+ tmp[M22] = 1 - 2 * (l_xx + l_yy);\r
+ tmp[M23] = 0;\r
+ tmp[M30] = 0;\r
+ tmp[M31] = 0;\r
+ tmp[M32] = 0;\r
+ tmp[M33] = 1;\r
+\r
+ mul(val, tmp);\r
+ return this;\r
+ }\r
+\r
+ /** Postmultiplies this matrix with a scale matrix. Postmultiplication is also used by OpenGL ES' glTranslate/glRotate/glScale.\r
+ * @param scaleX\r
+ * @param scaleY\r
+ * @param scaleZ\r
+ * @return this matrix for chaining */\r
+ public Matrix4 scale (float scaleX, float scaleY, float scaleZ) {\r
+ tmp[M00] = scaleX;\r
+ tmp[M01] = 0;\r
+ tmp[M02] = 0;\r
+ tmp[M03] = 0;\r
+ tmp[M10] = 0;\r
+ tmp[M11] = scaleY;\r
+ tmp[M12] = 0;\r
+ tmp[M13] = 0;\r
+ tmp[M20] = 0;\r
+ tmp[M21] = 0;\r
+ tmp[M22] = scaleZ;\r
+ tmp[M23] = 0;\r
+ tmp[M30] = 0;\r
+ tmp[M31] = 0;\r
+ tmp[M32] = 0;\r
+ tmp[M33] = 1;\r
+\r
+ mul(val, tmp);\r
+ return this;\r
+ }\r
+}\r