1 /*
2     SPDX-FileCopyrightText: 2011 See AUTHORS file.
3 
4     SPDX-License-Identifier: Apache-2.0
5 */
6 
7 package org.kde.kstars.math;
8 
9 /** from libgdx: https://github.com/libgdx/libgdx */
10 
11 import java.io.Serializable;
12 
13 /** Encapsulates a <a href="http://en.wikipedia.org/wiki/Row-major_order">column major</a> 4 by 4 matrix. Like the {@link Vector3}
14  * class it allows the chaining of methods by returning a reference to itself. For example:
15  *
16  * <pre>
17  * Matrix4 mat = new Matrix4().trn(position).mul(camera.combined);
18  * </pre>
19  *
20  * @author badlogicgames@gmail.com */
21 public class Matrix4 implements Serializable {
22 	private static final long serialVersionUID = -2717655254359579617L;
23 	public static final int M00 = 0;// 0;
24 	public static final int M01 = 4;// 1;
25 	public static final int M02 = 8;// 2;
26 	public static final int M03 = 12;// 3;
27 	public static final int M10 = 1;// 4;
28 	public static final int M11 = 5;// 5;
29 	public static final int M12 = 9;// 6;
30 	public static final int M13 = 13;// 7;
31 	public static final int M20 = 2;// 8;
32 	public static final int M21 = 6;// 9;
33 	public static final int M22 = 10;// 10;
34 	public static final int M23 = 14;// 11;
35 	public static final int M30 = 3;// 12;
36 	public static final int M31 = 7;// 13;
37 	public static final int M32 = 11;// 14;
38 	public static final int M33 = 15;// 15;
39 
40 	public final float tmp[] = new float[16];
41 	public final float val[] = new float[16];
42 
43 	/** Constructs an identity matrix */
Matrix4()44 	public Matrix4 () {
45 		val[M00] = 1f;
46 		val[M11] = 1f;
47 		val[M22] = 1f;
48 		val[M33] = 1f;
49 	}
50 
51 	/** Constructs a matrix from the given matrix.
52 	 *
53 	 * @param matrix The matrix to copy. (This matrix is not modified) */
Matrix4(Matrix4 matrix)54 	public Matrix4 (Matrix4 matrix) {
55 		this.set(matrix);
56 	}
57 
58 	/** Constructs a matrix from the given float array. The array must have at least 16 elements; the first 16 will be copied.
59 	 * @param values The float array to copy. Remember that this matrix is in <a
60 	 *           href="http://en.wikipedia.org/wiki/Row-major_order">column major</a> order. (The float array is not modified) */
Matrix4(float[] values)61 	public Matrix4 (float[] values) {
62 		this.set(values);
63 	}
64 
65 	/** Constructs a rotation matrix from the given {@link Quaternion}.
66 	 * @param quaternion The quaternion to be copied. (The quaternion is not modified) */
Matrix4(Quaternion quaternion)67 	public Matrix4 (Quaternion quaternion) {
68 		this.set(quaternion);
69 	}
70 
71 	/** Sets the matrix to the given matrix.
72 	 *
73 	 * @param matrix The matrix that is to be copied. (The given matrix is not modified)
74 	 * @return This matrix for the purpose of chaining methods together. */
set(Matrix4 matrix)75 	public Matrix4 set (Matrix4 matrix) {
76 		return this.set(matrix.val);
77 	}
78 
79 	/** 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
80 	 * copied.
81 	 *
82 	 * @param values The matrix, in float form, that is to be copied. Remember that this matrix is in <a
83 	 *           href="http://en.wikipedia.org/wiki/Row-major_order">column major</a> order.
84 	 * @return This matrix for the purpose of chaining methods together. */
set(float[] values)85 	public Matrix4 set (float[] values) {
86 		System.arraycopy(values, 0, val, 0, val.length);
87 		return this;
88 	}
89 
90 	/** Sets the matrix to a rotation matrix representing the quaternion.
91 	 *
92 	 * @param quaternion The quaternion that is to be used to set this matrix.
93 	 * @return This matrix for the purpose of chaining methods together. */
set(Quaternion quaternion)94 	public Matrix4 set (Quaternion quaternion) {
95 		// Compute quaternion factors
96 		float l_xx = quaternion.x * quaternion.x;
97 		float l_xy = quaternion.x * quaternion.y;
98 		float l_xz = quaternion.x * quaternion.z;
99 		float l_xw = quaternion.x * quaternion.w;
100 		float l_yy = quaternion.y * quaternion.y;
101 		float l_yz = quaternion.y * quaternion.z;
102 		float l_yw = quaternion.y * quaternion.w;
103 		float l_zz = quaternion.z * quaternion.z;
104 		float l_zw = quaternion.z * quaternion.w;
105 		// Set matrix from quaternion
106 		val[M00] = 1 - 2 * (l_yy + l_zz);
107 		val[M01] = 2 * (l_xy - l_zw);
108 		val[M02] = 2 * (l_xz + l_yw);
109 		val[M03] = 0;
110 		val[M10] = 2 * (l_xy + l_zw);
111 		val[M11] = 1 - 2 * (l_xx + l_zz);
112 		val[M12] = 2 * (l_yz - l_xw);
113 		val[M13] = 0;
114 		val[M20] = 2 * (l_xz - l_yw);
115 		val[M21] = 2 * (l_yz + l_xw);
116 		val[M22] = 1 - 2 * (l_xx + l_yy);
117 		val[M23] = 0;
118 		val[M30] = 0;
119 		val[M31] = 0;
120 		val[M32] = 0;
121 		val[M33] = 1;
122 		return this;
123 	}
124 
125 	/** Sets the four columns of the matrix which correspond to the x-, y- and z-axis of the vector space this matrix creates as
126 	 * well as the 4th column representing the translation of any point that is multiplied by this matrix.
127 	 *
128 	 * @param xAxis The x-axis.
129 	 * @param yAxis The y-axis.
130 	 * @param zAxis The z-axis.
131 	 * @param pos The translation vector. */
set(Vector3 xAxis, Vector3 yAxis, Vector3 zAxis, Vector3 pos)132 	public Matrix4 set (Vector3 xAxis, Vector3 yAxis, Vector3 zAxis, Vector3 pos) {
133 		val[M00] = xAxis.x;
134 		val[M01] = xAxis.y;
135 		val[M02] = xAxis.z;
136 		val[M10] = yAxis.x;
137 		val[M11] = yAxis.y;
138 		val[M12] = yAxis.z;
139 		val[M20] = -zAxis.x;
140 		val[M21] = -zAxis.y;
141 		val[M22] = -zAxis.z;
142 		val[M03] = pos.x;
143 		val[M13] = pos.y;
144 		val[M23] = pos.z;
145 		val[M30] = 0;
146 		val[M31] = 0;
147 		val[M32] = 0;
148 		val[M33] = 1;
149 		return this;
150 	}
151 
152 	/** @return a copy of this matrix */
cpy()153 	public Matrix4 cpy () {
154 		return new Matrix4(this);
155 	}
156 
157 	/** Adds a translational component to the matrix in the 4th column. The other columns are untouched.
158 	 *
159 	 * @param vector The translation vector to add to the current matrix. (This vector is not modified)
160 	 * @return This matrix for the purpose of chaining methods together. */
trn(Vector3 vector)161 	public Matrix4 trn (Vector3 vector) {
162 		val[M03] += vector.x;
163 		val[M13] += vector.y;
164 		val[M23] += vector.z;
165 		return this;
166 	}
167 
168 	/** Adds a translational component to the matrix in the 4th column. The other columns are untouched.
169 	 *
170 	 * @param x The x-component of the translation vector.
171 	 * @param y The y-component of the translation vector.
172 	 * @param z The z-component of the translation vector.
173 	 * @return This matrix for the purpose of chaining methods together. */
trn(float x, float y, float z)174 	public Matrix4 trn (float x, float y, float z) {
175 		val[M03] += x;
176 		val[M13] += y;
177 		val[M23] += z;
178 		return this;
179 	}
180 
181 	/** @return the backing float array */
getValues()182 	public float[] getValues () {
183 		return val;
184 	}
185 
186 	/** Multiplies this matrix with the given matrix, storing the result in this matrix. For example:
187 	 *
188 	 * <pre>
189 	 * A.mul(B) results in A := AB.
190 	 * </pre>
191 	 *
192 	 * @param matrix The other matrix to multiply by.
193 	 * @return This matrix for the purpose of chaining operations together. */
mul(Matrix4 matrix)194 	public Matrix4 mul (Matrix4 matrix) {
195 		//mul(val, matrix.val);
196 		//return this;
197 		return mul_java(matrix);
198 	}
199 
200 	/**
201 	 * Multiplies this matrix with the given matrix, storing the result in this
202 	 * matrix.
203 	 *
204 	 * @param matrix
205 	 *            The other matrix
206 	 * @return This matrix for chaining.
207 	 */
mul_java(Matrix4 matrix)208 	public Matrix4 mul_java(Matrix4 matrix) {
209 		tmp[M00] = val[M00] * matrix.val[M00] + val[M01] * matrix.val[M10] + val[M02] * matrix.val[M20] + val[M03] * matrix.val[M30];
210 		tmp[M01] = val[M00] * matrix.val[M01] + val[M01] * matrix.val[M11] + val[M02] * matrix.val[M21] + val[M03] * matrix.val[M31];
211 		tmp[M02] = val[M00] * matrix.val[M02] + val[M01] * matrix.val[M12] + val[M02] * matrix.val[M22] + val[M03] * matrix.val[M32];
212 		tmp[M03] = val[M00] * matrix.val[M03] + val[M01] * matrix.val[M13] + val[M02] * matrix.val[M23] + val[M03] * matrix.val[M33];
213 		tmp[M10] = val[M10] * matrix.val[M00] + val[M11] * matrix.val[M10] + val[M12] * matrix.val[M20] + val[M13] * matrix.val[M30];
214 		tmp[M11] = val[M10] * matrix.val[M01] + val[M11] * matrix.val[M11] + val[M12] * matrix.val[M21] + val[M13] * matrix.val[M31];
215 		tmp[M12] = val[M10] * matrix.val[M02] + val[M11] * matrix.val[M12] + val[M12] * matrix.val[M22] + val[M13] * matrix.val[M32];
216 		tmp[M13] = val[M10] * matrix.val[M03] + val[M11] * matrix.val[M13] + val[M12] * matrix.val[M23] + val[M13] * matrix.val[M33];
217 		tmp[M20] = val[M20] * matrix.val[M00] + val[M21] * matrix.val[M10] + val[M22] * matrix.val[M20] + val[M23] * matrix.val[M30];
218 		tmp[M21] = val[M20] * matrix.val[M01] + val[M21] * matrix.val[M11] + val[M22] * matrix.val[M21] + val[M23] * matrix.val[M31];
219 		tmp[M22] = val[M20] * matrix.val[M02] + val[M21] * matrix.val[M12] + val[M22] * matrix.val[M22] + val[M23] * matrix.val[M32];
220 		tmp[M23] = val[M20] * matrix.val[M03] + val[M21] * matrix.val[M13] + val[M22] * matrix.val[M23] + val[M23] * matrix.val[M33];
221 		tmp[M30] = val[M30] * matrix.val[M00] + val[M31] * matrix.val[M10] + val[M32] * matrix.val[M20] + val[M33] * matrix.val[M30];
222 		tmp[M31] = val[M30] * matrix.val[M01] + val[M31] * matrix.val[M11] + val[M32] * matrix.val[M21] + val[M33] * matrix.val[M31];
223 		tmp[M32] = val[M30] * matrix.val[M02] + val[M31] * matrix.val[M12] + val[M32] * matrix.val[M22] + val[M33] * matrix.val[M32];
224 		tmp[M33] = val[M30] * matrix.val[M03] + val[M31] * matrix.val[M13] + val[M32] * matrix.val[M23] + val[M33] * matrix.val[M33];
225 		return this.set(tmp);
226 	}
227 
228 	/** Transposes the matrix.
229 	 *
230 	 * @return This matrix for the purpose of chaining methods together. */
tra()231 	public Matrix4 tra () {
232 		tmp[M00] = val[M00];
233 		tmp[M01] = val[M10];
234 		tmp[M02] = val[M20];
235 		tmp[M03] = val[M30];
236 		tmp[M10] = val[M01];
237 		tmp[M11] = val[M11];
238 		tmp[M12] = val[M21];
239 		tmp[M13] = val[M31];
240 		tmp[M20] = val[M02];
241 		tmp[M21] = val[M12];
242 		tmp[M22] = val[M22];
243 		tmp[M23] = val[M32];
244 		tmp[M30] = val[M03];
245 		tmp[M31] = val[M13];
246 		tmp[M32] = val[M23];
247 		tmp[M33] = val[M33];
248 		return set(tmp);
249 	}
250 
251 	/** Sets the matrix to an identity matrix.
252 	 *
253 	 * @return This matrix for the purpose of chaining methods together. */
idt()254 	public Matrix4 idt () {
255 		val[M00] = 1;
256 		val[M01] = 0;
257 		val[M02] = 0;
258 		val[M03] = 0;
259 		val[M10] = 0;
260 		val[M11] = 1;
261 		val[M12] = 0;
262 		val[M13] = 0;
263 		val[M20] = 0;
264 		val[M21] = 0;
265 		val[M22] = 1;
266 		val[M23] = 0;
267 		val[M30] = 0;
268 		val[M31] = 0;
269 		val[M32] = 0;
270 		val[M33] = 1;
271 		return this;
272 	}
273 
274 	/** Inverts the matrix. Throws a {@link RuntimeException} in case the matrix is not invertible. Stores the result in this
275 	 * matrix.
276 	 *
277 	 * @return This matrix for the purpose of chaining methods together. */
inv()278 	public Matrix4 inv () {
279 		float l_det = val[M30] * val[M21] * val[M12] * val[M03] - val[M20] * val[M31] * val[M12] * val[M03] - val[M30] * val[M11]
280 			* val[M22] * val[M03] + val[M10] * val[M31] * val[M22] * val[M03] + val[M20] * val[M11] * val[M32] * val[M03] - val[M10]
281 			* val[M21] * val[M32] * val[M03] - val[M30] * val[M21] * val[M02] * val[M13] + val[M20] * val[M31] * val[M02] * val[M13]
282 			+ val[M30] * val[M01] * val[M22] * val[M13] - val[M00] * val[M31] * val[M22] * val[M13] - val[M20] * val[M01] * val[M32]
283 			* val[M13] + val[M00] * val[M21] * val[M32] * val[M13] + val[M30] * val[M11] * val[M02] * val[M23] - val[M10] * val[M31]
284 			* val[M02] * val[M23] - val[M30] * val[M01] * val[M12] * val[M23] + val[M00] * val[M31] * val[M12] * val[M23] + val[M10]
285 			* val[M01] * val[M32] * val[M23] - val[M00] * val[M11] * val[M32] * val[M23] - val[M20] * val[M11] * val[M02] * val[M33]
286 			+ val[M10] * val[M21] * val[M02] * val[M33] + val[M20] * val[M01] * val[M12] * val[M33] - val[M00] * val[M21] * val[M12]
287 			* val[M33] - val[M10] * val[M01] * val[M22] * val[M33] + val[M00] * val[M11] * val[M22] * val[M33];
288 		if (l_det == 0f) throw new RuntimeException("non-invertible matrix");
289 		float inv_det = 1.0f / l_det;
290 		tmp[M00] = val[M12] * val[M23] * val[M31] - val[M13] * val[M22] * val[M31] + val[M13] * val[M21] * val[M32] - val[M11]
291 			* val[M23] * val[M32] - val[M12] * val[M21] * val[M33] + val[M11] * val[M22] * val[M33];
292 		tmp[M01] = val[M03] * val[M22] * val[M31] - val[M02] * val[M23] * val[M31] - val[M03] * val[M21] * val[M32] + val[M01]
293 			* val[M23] * val[M32] + val[M02] * val[M21] * val[M33] - val[M01] * val[M22] * val[M33];
294 		tmp[M02] = val[M02] * val[M13] * val[M31] - val[M03] * val[M12] * val[M31] + val[M03] * val[M11] * val[M32] - val[M01]
295 			* val[M13] * val[M32] - val[M02] * val[M11] * val[M33] + val[M01] * val[M12] * val[M33];
296 		tmp[M03] = val[M03] * val[M12] * val[M21] - val[M02] * val[M13] * val[M21] - val[M03] * val[M11] * val[M22] + val[M01]
297 			* val[M13] * val[M22] + val[M02] * val[M11] * val[M23] - val[M01] * val[M12] * val[M23];
298 		tmp[M10] = val[M13] * val[M22] * val[M30] - val[M12] * val[M23] * val[M30] - val[M13] * val[M20] * val[M32] + val[M10]
299 			* val[M23] * val[M32] + val[M12] * val[M20] * val[M33] - val[M10] * val[M22] * val[M33];
300 		tmp[M11] = val[M02] * val[M23] * val[M30] - val[M03] * val[M22] * val[M30] + val[M03] * val[M20] * val[M32] - val[M00]
301 			* val[M23] * val[M32] - val[M02] * val[M20] * val[M33] + val[M00] * val[M22] * val[M33];
302 		tmp[M12] = val[M03] * val[M12] * val[M30] - val[M02] * val[M13] * val[M30] - val[M03] * val[M10] * val[M32] + val[M00]
303 			* val[M13] * val[M32] + val[M02] * val[M10] * val[M33] - val[M00] * val[M12] * val[M33];
304 		tmp[M13] = val[M02] * val[M13] * val[M20] - val[M03] * val[M12] * val[M20] + val[M03] * val[M10] * val[M22] - val[M00]
305 			* val[M13] * val[M22] - val[M02] * val[M10] * val[M23] + val[M00] * val[M12] * val[M23];
306 		tmp[M20] = val[M11] * val[M23] * val[M30] - val[M13] * val[M21] * val[M30] + val[M13] * val[M20] * val[M31] - val[M10]
307 			* val[M23] * val[M31] - val[M11] * val[M20] * val[M33] + val[M10] * val[M21] * val[M33];
308 		tmp[M21] = val[M03] * val[M21] * val[M30] - val[M01] * val[M23] * val[M30] - val[M03] * val[M20] * val[M31] + val[M00]
309 			* val[M23] * val[M31] + val[M01] * val[M20] * val[M33] - val[M00] * val[M21] * val[M33];
310 		tmp[M22] = val[M01] * val[M13] * val[M30] - val[M03] * val[M11] * val[M30] + val[M03] * val[M10] * val[M31] - val[M00]
311 			* val[M13] * val[M31] - val[M01] * val[M10] * val[M33] + val[M00] * val[M11] * val[M33];
312 		tmp[M23] = val[M03] * val[M11] * val[M20] - val[M01] * val[M13] * val[M20] - val[M03] * val[M10] * val[M21] + val[M00]
313 			* val[M13] * val[M21] + val[M01] * val[M10] * val[M23] - val[M00] * val[M11] * val[M23];
314 		tmp[M30] = val[M12] * val[M21] * val[M30] - val[M11] * val[M22] * val[M30] - val[M12] * val[M20] * val[M31] + val[M10]
315 			* val[M22] * val[M31] + val[M11] * val[M20] * val[M32] - val[M10] * val[M21] * val[M32];
316 		tmp[M31] = val[M01] * val[M22] * val[M30] - val[M02] * val[M21] * val[M30] + val[M02] * val[M20] * val[M31] - val[M00]
317 			* val[M22] * val[M31] - val[M01] * val[M20] * val[M32] + val[M00] * val[M21] * val[M32];
318 		tmp[M32] = val[M02] * val[M11] * val[M30] - val[M01] * val[M12] * val[M30] - val[M02] * val[M10] * val[M31] + val[M00]
319 			* val[M12] * val[M31] + val[M01] * val[M10] * val[M32] - val[M00] * val[M11] * val[M32];
320 		tmp[M33] = val[M01] * val[M12] * val[M20] - val[M02] * val[M11] * val[M20] + val[M02] * val[M10] * val[M21] - val[M00]
321 			* val[M12] * val[M21] - val[M01] * val[M10] * val[M22] + val[M00] * val[M11] * val[M22];
322 		val[M00] = tmp[M00] * inv_det;
323 		val[M01] = tmp[M01] * inv_det;
324 		val[M02] = tmp[M02] * inv_det;
325 		val[M03] = tmp[M03] * inv_det;
326 		val[M10] = tmp[M10] * inv_det;
327 		val[M11] = tmp[M11] * inv_det;
328 		val[M12] = tmp[M12] * inv_det;
329 		val[M13] = tmp[M13] * inv_det;
330 		val[M20] = tmp[M20] * inv_det;
331 		val[M21] = tmp[M21] * inv_det;
332 		val[M22] = tmp[M22] * inv_det;
333 		val[M23] = tmp[M23] * inv_det;
334 		val[M30] = tmp[M30] * inv_det;
335 		val[M31] = tmp[M31] * inv_det;
336 		val[M32] = tmp[M32] * inv_det;
337 		val[M33] = tmp[M33] * inv_det;
338 		return this;
339 	}
340 
341 	/** @return The determinant of this matrix */
det()342 	public float det () {
343 		return val[M30] * val[M21] * val[M12] * val[M03] - val[M20] * val[M31] * val[M12] * val[M03] - val[M30] * val[M11]
344 			* val[M22] * val[M03] + val[M10] * val[M31] * val[M22] * val[M03] + val[M20] * val[M11] * val[M32] * val[M03] - val[M10]
345 			* val[M21] * val[M32] * val[M03] - val[M30] * val[M21] * val[M02] * val[M13] + val[M20] * val[M31] * val[M02] * val[M13]
346 			+ val[M30] * val[M01] * val[M22] * val[M13] - val[M00] * val[M31] * val[M22] * val[M13] - val[M20] * val[M01] * val[M32]
347 			* val[M13] + val[M00] * val[M21] * val[M32] * val[M13] + val[M30] * val[M11] * val[M02] * val[M23] - val[M10] * val[M31]
348 			* val[M02] * val[M23] - val[M30] * val[M01] * val[M12] * val[M23] + val[M00] * val[M31] * val[M12] * val[M23] + val[M10]
349 			* val[M01] * val[M32] * val[M23] - val[M00] * val[M11] * val[M32] * val[M23] - val[M20] * val[M11] * val[M02] * val[M33]
350 			+ val[M10] * val[M21] * val[M02] * val[M33] + val[M20] * val[M01] * val[M12] * val[M33] - val[M00] * val[M21] * val[M12]
351 			* val[M33] - val[M10] * val[M01] * val[M22] * val[M33] + val[M00] * val[M11] * val[M22] * val[M33];
352 	}
353 
354 	/** Sets the matrix to a projection matrix with a near- and far plane, a field of view in degrees and an aspect ratio.
355 	 *
356 	 * @param near The near plane
357 	 * @param far The far plane
358 	 * @param fov The field of view in degrees
359 	 * @param aspectRatio The aspect ratio
360 	 * @return This matrix for the purpose of chaining methods together. */
setToProjection(float near, float far, float fov, float aspectRatio)361 	public Matrix4 setToProjection (float near, float far, float fov, float aspectRatio) {
362 		idt();
363 		float l_fd = (float)(1.0 / Math.tan((fov * (Math.PI / 180)) / 2.0));
364 		float l_a1 = (far + near) / (near - far);
365 		float l_a2 = (2 * far * near) / (near - far);
366 		val[M00] = l_fd / aspectRatio;
367 		val[M10] = 0;
368 		val[M20] = 0;
369 		val[M30] = 0;
370 		val[M01] = 0;
371 		val[M11] = l_fd;
372 		val[M21] = 0;
373 		val[M31] = 0;
374 		val[M02] = 0;
375 		val[M12] = 0;
376 		val[M22] = l_a1;
377 		val[M32] = -1;
378 		val[M03] = 0;
379 		val[M13] = 0;
380 		val[M23] = l_a2;
381 		val[M33] = 0;
382 
383 		return this;
384 	}
385 
386 	/** Sets this matrix to an orthographic projection matrix with the origin at (x,y) extending by width and height. The near plane
387 	 * is set to 0, the far plane is set to 1.
388 	 *
389 	 * @param x The x-coordinate of the origin
390 	 * @param y The y-coordinate of the origin
391 	 * @param width The width
392 	 * @param height The height
393 	 * @return This matrix for the purpose of chaining methods together. */
setToOrtho2D(float x, float y, float width, float height)394 	public Matrix4 setToOrtho2D (float x, float y, float width, float height) {
395 		setToOrtho(x, x + width, y, y + height, 0, 1);
396 		return this;
397 	}
398 
399 	/** Sets this matrix to an orthographic projection matrix with the origin at (x,y) extending by width and height, having a near
400 	 * and far plane.
401 	 *
402 	 * @param x The x-coordinate of the origin
403 	 * @param y The y-coordinate of the origin
404 	 * @param width The width
405 	 * @param height The height
406 	 * @param near The near plane
407 	 * @param far The far plane
408 	 * @return This matrix for the purpose of chaining methods together. */
setToOrtho2D(float x, float y, float width, float height, float near, float far)409 	public Matrix4 setToOrtho2D (float x, float y, float width, float height, float near, float far) {
410 		setToOrtho(x, x + width, y, y + height, near, far);
411 		return this;
412 	}
413 
414 	/** Sets the matrix to an orthographic projection like glOrtho (http://www.opengl.org/sdk/docs/man/xhtml/glOrtho.xml) following
415 	 * the OpenGL equivalent
416 	 *
417 	 * @param left The left clipping plane
418 	 * @param right The right clipping plane
419 	 * @param bottom The bottom clipping plane
420 	 * @param top The top clipping plane
421 	 * @param near The near clipping plane
422 	 * @param far The far clipping plane
423 	 * @return This matrix for the purpose of chaining methods together. */
setToOrtho(float left, float right, float bottom, float top, float near, float far)424 	public Matrix4 setToOrtho (float left, float right, float bottom, float top, float near, float far) {
425 
426 		this.idt();
427 		float x_orth = 2 / (right - left);
428 		float y_orth = 2 / (top - bottom);
429 		float z_orth = -2 / (far - near);
430 
431 		float tx = -(right + left) / (right - left);
432 		float ty = -(top + bottom) / (top - bottom);
433 		float tz = -(far + near) / (far - near);
434 
435 		val[M00] = x_orth;
436 		val[M10] = 0;
437 		val[M20] = 0;
438 		val[M30] = 0;
439 		val[M01] = 0;
440 		val[M11] = y_orth;
441 		val[M21] = 0;
442 		val[M31] = 0;
443 		val[M02] = 0;
444 		val[M12] = 0;
445 		val[M22] = z_orth;
446 		val[M32] = 0;
447 		val[M03] = tx;
448 		val[M13] = ty;
449 		val[M23] = tz;
450 		val[M33] = 1;
451 
452 		return this;
453 	}
454 
455 	/** Sets this matrix to a translation matrix, overwriting it first by an identity matrix and then setting the 4th column to the
456 	 * translation vector.
457 	 *
458 	 * @param vector The translation vector
459 	 * @return This matrix for the purpose of chaining methods together. */
setToTranslation(Vector3 vector)460 	public Matrix4 setToTranslation (Vector3 vector) {
461 		idt();
462 		val[M03] = vector.x;
463 		val[M13] = vector.y;
464 		val[M23] = vector.z;
465 		return this;
466 	}
467 
468 	/** Sets this matrix to a translation matrix, overwriting it first by an identity matrix and then setting the 4th column to the
469 	 * translation vector.
470 	 *
471 	 * @param x The x-component of the translation vector.
472 	 * @param y The y-component of the translation vector.
473 	 * @param z The z-component of the translation vector.
474 	 * @return This matrix for the purpose of chaining methods together. */
setToTranslation(float x, float y, float z)475 	public Matrix4 setToTranslation (float x, float y, float z) {
476 		idt();
477 		val[M03] = x;
478 		val[M13] = y;
479 		val[M23] = z;
480 		return this;
481 	}
482 
483 	/** Sets this matrix to a translation and scaling matrix by first overwritting it with an identity and then setting the
484 	 * translation vector in the 4th column and the scaling vector in the diagonal.
485 	 *
486 	 * @param translation The translation vector
487 	 * @param scaling The scaling vector
488 	 * @return This matrix for the purpose of chaining methods together. */
setToTranslationAndScaling(Vector3 translation, Vector3 scaling)489 	public Matrix4 setToTranslationAndScaling (Vector3 translation, Vector3 scaling) {
490 		idt();
491 		val[M03] = translation.x;
492 		val[M13] = translation.y;
493 		val[M23] = translation.z;
494 		val[M00] = scaling.x;
495 		val[M11] = scaling.y;
496 		val[M22] = scaling.z;
497 		return this;
498 	}
499 
500 	/** Sets this matrix to a translation and scaling matrix by first overwritting it with an identity and then setting the
501 	 * translation vector in the 4th column and the scaling vector in the diagonal.
502 	 *
503 	 * @param translationX The x-component of the translation vector
504 	 * @param translationY The y-component of the translation vector
505 	 * @param translationZ The z-component of the translation vector
506 	 * @param scalingX The x-component of the scaling vector
507 	 * @param scalingY The x-component of the scaling vector
508 	 * @param scalingZ The x-component of the scaling vector
509 	 * @return This matrix for the purpose of chaining methods together. */
setToTranslationAndScaling(float translationX, float translationY, float translationZ, float scalingX, float scalingY, float scalingZ)510 	public Matrix4 setToTranslationAndScaling (float translationX, float translationY, float translationZ, float scalingX,
511 		float scalingY, float scalingZ) {
512 		idt();
513 		val[M03] = translationX;
514 		val[M13] = translationY;
515 		val[M23] = translationZ;
516 		val[M00] = scalingX;
517 		val[M11] = scalingY;
518 		val[M22] = scalingZ;
519 		return this;
520 	}
521 
522 	static Quaternion quat = new Quaternion();
523 
524 	/** Sets the matrix to a rotation matrix around the given axis.
525 	 *
526 	 * @param axis The axis
527 	 * @param angle The angle in degrees
528 	 * @return This matrix for the purpose of chaining methods together. */
setToRotation(Vector3 axis, float angle)529 	public Matrix4 setToRotation (Vector3 axis, float angle) {
530 		if (angle == 0) {
531 			idt();
532 			return this;
533 		}
534 		return set(quat.set(axis, angle));
535 	}
536 
537 	/** Sets the matrix to a rotation matrix around the given axis.
538 	 *
539 	 * @param axisX The x-component of the axis
540 	 * @param axisY The y-component of the axis
541 	 * @param axisZ The z-component of the axis
542 	 * @param angle The angle in degrees
543 	 * @return This matrix for the purpose of chaining methods together. */
setToRotation(float axisX, float axisY, float axisZ, float angle)544 	public Matrix4 setToRotation (float axisX, float axisY, float axisZ, float angle) {
545 		if (angle == 0) {
546 			idt();
547 			return this;
548 		}
549 		return set(quat.set(tmpV.set(axisX, axisY, axisZ), angle));
550 	}
551 
552 	/** Set the matrix to a rotation matrix between two vectors.
553 	 * @param v1 The base vector
554 	 * @param v2 The target vector
555 	 * @return This matrix for the purpose of chaining methods together */
setToRotation(final Vector3 v1, final Vector3 v2)556 	public Matrix4 setToRotation (final Vector3 v1, final Vector3 v2) {
557 		idt();
558 		return set(quat.setFromCross(v1, v2));
559 	}
560 
561 	/** Set the matrix to a rotation matrix between two vectors.
562 	 * @param x1 The base vectors x value
563 	 * @param y1 The base vectors y value
564 	 * @param z1 The base vectors z value
565 	 * @param x2 The target vector x value
566 	 * @param y2 The target vector y value
567 	 * @param z2 The target vector z value
568 	 * @return This matrix for the purpose of chaining methods together */
setToRotation(final float x1, final float y1, final float z1, final float x2, final float y2, final float z2)569 		public Matrix4 setToRotation (final float x1, final float y1, final float z1, final float x2, final float y2, final float z2) {
570 		idt();
571 		return set(quat.setFromCross(x1, y1, z1, x2, y2, z2));
572 	}
573 
574 	static final Vector3 tmpV = new Vector3();
575 
576 	/** Sets this matrix to a rotation matrix from the given euler angles.
577 	 * @param yaw the yaw in degrees
578 	 * @param pitch the pitch in degress
579 	 * @param roll the roll in degrees
580 	 * @return This matrix */
setFromEulerAngles(float yaw, float pitch, float roll)581 	public Matrix4 setFromEulerAngles (float yaw, float pitch, float roll) {
582 		quat.setEulerAngles(yaw, pitch, roll);
583 		return set(quat);
584 	}
585 
586 	/** Sets this matrix to a scaling matrix
587 	 *
588 	 * @param vector The scaling vector
589 	 * @return This matrix for chaining. */
setToScaling(Vector3 vector)590 	public Matrix4 setToScaling (Vector3 vector) {
591 		idt();
592 		val[M00] = vector.x;
593 		val[M11] = vector.y;
594 		val[M22] = vector.z;
595 		return this;
596 	}
597 
598 	/** Sets this matrix to a scaling matrix
599 	 *
600 	 * @param x The x-component of the scaling vector
601 	 * @param y The y-component of the scaling vector
602 	 * @param z The z-component of the scaling vector
603 	 * @return This matrix for chaining. */
setToScaling(float x, float y, float z)604 	public Matrix4 setToScaling (float x, float y, float z) {
605 		idt();
606 		val[M00] = x;
607 		val[M11] = y;
608 		val[M22] = z;
609 		return this;
610 	}
611 
612 	static Vector3 l_vez = new Vector3();
613 	static Vector3 l_vex = new Vector3();
614 	static Vector3 l_vey = new Vector3();
615 
616 	/** Sets the matrix to a look at matrix with a direction and an up vector. Multiply with a translation matrix to get a camera
617 	 * model view matrix.
618 	 *
619 	 * @param direction The direction vector
620 	 * @param up The up vector
621 	 * @return This matrix for the purpose of chaining methods together. */
setToLookAt(Vector3 direction, Vector3 up)622 	public Matrix4 setToLookAt (Vector3 direction, Vector3 up) {
623 		l_vez.set(direction).nor();
624 		l_vex.set(direction).nor();
625 		l_vex.crs(up).nor();
626 		l_vey.set(l_vex).crs(l_vez).nor();
627 		idt();
628 		val[M00] = l_vex.x;
629 		val[M01] = l_vex.y;
630 		val[M02] = l_vex.z;
631 		val[M10] = l_vey.x;
632 		val[M11] = l_vey.y;
633 		val[M12] = l_vey.z;
634 		val[M20] = -l_vez.x;
635 		val[M21] = -l_vez.y;
636 		val[M22] = -l_vez.z;
637 
638 		return this;
639 	}
640 
641 	static final Vector3 tmpVec = new Vector3();
642 	static final Matrix4 tmpMat = new Matrix4();
643 
644 	/** Sets this matrix to a look at matrix with the given position, target and up vector.
645 	 *
646 	 * @param position the position
647 	 * @param target the target
648 	 * @param up the up vector
649 	 * @return This matrix */
setToLookAt(Vector3 position, Vector3 target, Vector3 up)650 	public Matrix4 setToLookAt (Vector3 position, Vector3 target, Vector3 up) {
651 		tmpVec.set(target).sub(position);
652 		setToLookAt(tmpVec, up);
653 		this.mul(tmpMat.setToTranslation(position.tmp().mul(-1)));
654 
655 		return this;
656 	}
657 
658 	static Vector3 right = new Vector3();
659 	static Vector3 tmpForward = new Vector3();
660 	static Vector3 tmpUp = new Vector3();
661 
setToWorld(Vector3 position, Vector3 forward, Vector3 up)662 	public Matrix4 setToWorld (Vector3 position, Vector3 forward, Vector3 up) {
663 		tmpForward.set(forward).nor();
664 		right.set(tmpForward).crs(up).nor();
665 		tmpUp.set(right).crs(tmpForward).nor();
666 
667 		this.set(right, tmpUp, tmpForward, position);
668 		return this;
669 	}
670 
671 	/** {@inheritDoc} */
toString()672 	public String toString () {
673 		return "[" + val[M00] + "|" + val[M01] + "|" + val[M02] + "|" + val[M03] + "]\n" + "[" + val[M10] + "|" + val[M11] + "|"
674 			+ val[M12] + "|" + val[M13] + "]\n" + "[" + val[M20] + "|" + val[M21] + "|" + val[M22] + "|" + val[M23] + "]\n" + "["
675 			+ val[M30] + "|" + val[M31] + "|" + val[M32] + "|" + val[M33] + "]\n";
676 	}
677 
678 	/** Linearly interpolates between this matrix and the given matrix mixing by alpha
679 	 * @param matrix the matrix
680 	 * @param alpha the alpha value in the range [0,1] */
lerp(Matrix4 matrix, float alpha)681 	public void lerp (Matrix4 matrix, float alpha) {
682 		for (int i = 0; i < 16; i++)
683 			this.val[i] = this.val[i] * (1 - alpha) + matrix.val[i] * alpha;
684 	}
685 
686 	/** Sets this matrix to the given 3x3 matrix. The third column of this matrix is set to (0,0,1,0).
687 	 * @param mat the matrix */
set(Matrix3 mat)688 	public Matrix4 set (Matrix3 mat) {
689 		val[0] = mat.val[0];
690 		val[1] = mat.val[1];
691 		val[2] = mat.val[2];
692 		val[3] = 0;
693 		val[4] = mat.val[3];
694 		val[5] = mat.val[4];
695 		val[6] = mat.val[5];
696 		val[7] = 0;
697 		val[8] = 0;
698 		val[9] = 0;
699 		val[10] = 1;
700 		val[11] = 0;
701 		val[12] = mat.val[6];
702 		val[13] = mat.val[7];
703 		val[14] = 0;
704 		val[15] = mat.val[8];
705 		return this;
706 	}
707 
scl(Vector3 scale)708 	public Matrix4 scl (Vector3 scale) {
709 		val[M00] *= scale.x;
710 		val[M11] *= scale.y;
711 		val[M22] *= scale.z;
712 		return this;
713 	}
714 
scl(float x, float y, float z)715 	public Matrix4 scl (float x, float y, float z) {
716 		val[M00] *= x;
717 		val[M11] *= y;
718 		val[M22] *= z;
719 		return this;
720 	}
721 
scl(float scale)722 	public Matrix4 scl (float scale) {
723 		val[M00] *= scale;
724 		val[M11] *= scale;
725 		val[M22] *= scale;
726 		return this;
727 	}
728 
getTranslation(Vector3 position)729 	public void getTranslation (Vector3 position) {
730 		position.x = val[M03];
731 		position.y = val[M13];
732 		position.z = val[M23];
733 	}
734 
getRotation(Quaternion rotation)735 	public void getRotation (Quaternion rotation) {
736 		rotation.setFromMatrix(this);
737 	}
738 
739 	/** removes the translational part and transposes the matrix. */
toNormalMatrix()740 	public Matrix4 toNormalMatrix () {
741 		val[M03] = 0;
742 		val[M13] = 0;
743 		val[M23] = 0;
744 		return inv().tra();
745 	}
746 
747 	// @off
748 	/*JNI
749 	#include <memory.h>
750 	#include <stdio.h>
751 	#include <string.h>
752 
753 	#define M00 0
754 	#define M01 4
755 	#define M02 8
756 	#define M03 12
757 	#define M10 1
758 	#define M11 5
759 	#define M12 9
760 	#define M13 13
761 	#define M20 2
762 	#define M21 6
763 	#define M22 10
764 	#define M23 14
765 	#define M30 3
766 	#define M31 7
767 	#define M32 11
768 	#define M33 15
769 
770 	static inline void matrix4_mul(float* mata, float* matb) {
771 		float tmp[16];
772 		tmp[M00] = mata[M00] * matb[M00] + mata[M01] * matb[M10] + mata[M02] * matb[M20] + mata[M03] * matb[M30];
773 		tmp[M01] = mata[M00] * matb[M01] + mata[M01] * matb[M11] + mata[M02] * matb[M21] + mata[M03] * matb[M31];
774 		tmp[M02] = mata[M00] * matb[M02] + mata[M01] * matb[M12] + mata[M02] * matb[M22] + mata[M03] * matb[M32];
775 		tmp[M03] = mata[M00] * matb[M03] + mata[M01] * matb[M13] + mata[M02] * matb[M23] + mata[M03] * matb[M33];
776 		tmp[M10] = mata[M10] * matb[M00] + mata[M11] * matb[M10] + mata[M12] * matb[M20] + mata[M13] * matb[M30];
777 		tmp[M11] = mata[M10] * matb[M01] + mata[M11] * matb[M11] + mata[M12] * matb[M21] + mata[M13] * matb[M31];
778 		tmp[M12] = mata[M10] * matb[M02] + mata[M11] * matb[M12] + mata[M12] * matb[M22] + mata[M13] * matb[M32];
779 		tmp[M13] = mata[M10] * matb[M03] + mata[M11] * matb[M13] + mata[M12] * matb[M23] + mata[M13] * matb[M33];
780 		tmp[M20] = mata[M20] * matb[M00] + mata[M21] * matb[M10] + mata[M22] * matb[M20] + mata[M23] * matb[M30];
781 		tmp[M21] = mata[M20] * matb[M01] + mata[M21] * matb[M11] + mata[M22] * matb[M21] + mata[M23] * matb[M31];
782 		tmp[M22] = mata[M20] * matb[M02] + mata[M21] * matb[M12] + mata[M22] * matb[M22] + mata[M23] * matb[M32];
783 		tmp[M23] = mata[M20] * matb[M03] + mata[M21] * matb[M13] + mata[M22] * matb[M23] + mata[M23] * matb[M33];
784 		tmp[M30] = mata[M30] * matb[M00] + mata[M31] * matb[M10] + mata[M32] * matb[M20] + mata[M33] * matb[M30];
785 		tmp[M31] = mata[M30] * matb[M01] + mata[M31] * matb[M11] + mata[M32] * matb[M21] + mata[M33] * matb[M31];
786 		tmp[M32] = mata[M30] * matb[M02] + mata[M31] * matb[M12] + mata[M32] * matb[M22] + mata[M33] * matb[M32];
787 		tmp[M33] = mata[M30] * matb[M03] + mata[M31] * matb[M13] + mata[M32] * matb[M23] + mata[M33] * matb[M33];
788 		memcpy(mata, tmp, sizeof(float) *  16);
789 	}
790 
791 	static inline float matrix4_det(float* val) {
792 		return val[M30] * val[M21] * val[M12] * val[M03] - val[M20] * val[M31] * val[M12] * val[M03] - val[M30] * val[M11]
793 				* val[M22] * val[M03] + val[M10] * val[M31] * val[M22] * val[M03] + val[M20] * val[M11] * val[M32] * val[M03] - val[M10]
794 				* val[M21] * val[M32] * val[M03] - val[M30] * val[M21] * val[M02] * val[M13] + val[M20] * val[M31] * val[M02] * val[M13]
795 				+ val[M30] * val[M01] * val[M22] * val[M13] - val[M00] * val[M31] * val[M22] * val[M13] - val[M20] * val[M01] * val[M32]
796 				* val[M13] + val[M00] * val[M21] * val[M32] * val[M13] + val[M30] * val[M11] * val[M02] * val[M23] - val[M10] * val[M31]
797 				* val[M02] * val[M23] - val[M30] * val[M01] * val[M12] * val[M23] + val[M00] * val[M31] * val[M12] * val[M23] + val[M10]
798 				* val[M01] * val[M32] * val[M23] - val[M00] * val[M11] * val[M32] * val[M23] - val[M20] * val[M11] * val[M02] * val[M33]
799 				+ val[M10] * val[M21] * val[M02] * val[M33] + val[M20] * val[M01] * val[M12] * val[M33] - val[M00] * val[M21] * val[M12]
800 				* val[M33] - val[M10] * val[M01] * val[M22] * val[M33] + val[M00] * val[M11] * val[M22] * val[M33];
801 	}
802 
803 	static inline bool matrix4_inv(float* val) {
804 		float tmp[16];
805 		float l_det = matrix4_det(val);
806 		if (l_det == 0) return false;
807 		tmp[M00] = val[M12] * val[M23] * val[M31] - val[M13] * val[M22] * val[M31] + val[M13] * val[M21] * val[M32] - val[M11]
808 			* val[M23] * val[M32] - val[M12] * val[M21] * val[M33] + val[M11] * val[M22] * val[M33];
809 		tmp[M01] = val[M03] * val[M22] * val[M31] - val[M02] * val[M23] * val[M31] - val[M03] * val[M21] * val[M32] + val[M01]
810 			* val[M23] * val[M32] + val[M02] * val[M21] * val[M33] - val[M01] * val[M22] * val[M33];
811 		tmp[M02] = val[M02] * val[M13] * val[M31] - val[M03] * val[M12] * val[M31] + val[M03] * val[M11] * val[M32] - val[M01]
812 			* val[M13] * val[M32] - val[M02] * val[M11] * val[M33] + val[M01] * val[M12] * val[M33];
813 		tmp[M03] = val[M03] * val[M12] * val[M21] - val[M02] * val[M13] * val[M21] - val[M03] * val[M11] * val[M22] + val[M01]
814 			* val[M13] * val[M22] + val[M02] * val[M11] * val[M23] - val[M01] * val[M12] * val[M23];
815 		tmp[M10] = val[M13] * val[M22] * val[M30] - val[M12] * val[M23] * val[M30] - val[M13] * val[M20] * val[M32] + val[M10]
816 			* val[M23] * val[M32] + val[M12] * val[M20] * val[M33] - val[M10] * val[M22] * val[M33];
817 		tmp[M11] = val[M02] * val[M23] * val[M30] - val[M03] * val[M22] * val[M30] + val[M03] * val[M20] * val[M32] - val[M00]
818 			* val[M23] * val[M32] - val[M02] * val[M20] * val[M33] + val[M00] * val[M22] * val[M33];
819 		tmp[M12] = val[M03] * val[M12] * val[M30] - val[M02] * val[M13] * val[M30] - val[M03] * val[M10] * val[M32] + val[M00]
820 			* val[M13] * val[M32] + val[M02] * val[M10] * val[M33] - val[M00] * val[M12] * val[M33];
821 		tmp[M13] = val[M02] * val[M13] * val[M20] - val[M03] * val[M12] * val[M20] + val[M03] * val[M10] * val[M22] - val[M00]
822 			* val[M13] * val[M22] - val[M02] * val[M10] * val[M23] + val[M00] * val[M12] * val[M23];
823 		tmp[M20] = val[M11] * val[M23] * val[M30] - val[M13] * val[M21] * val[M30] + val[M13] * val[M20] * val[M31] - val[M10]
824 			* val[M23] * val[M31] - val[M11] * val[M20] * val[M33] + val[M10] * val[M21] * val[M33];
825 		tmp[M21] = val[M03] * val[M21] * val[M30] - val[M01] * val[M23] * val[M30] - val[M03] * val[M20] * val[M31] + val[M00]
826 			* val[M23] * val[M31] + val[M01] * val[M20] * val[M33] - val[M00] * val[M21] * val[M33];
827 		tmp[M22] = val[M01] * val[M13] * val[M30] - val[M03] * val[M11] * val[M30] + val[M03] * val[M10] * val[M31] - val[M00]
828 			* val[M13] * val[M31] - val[M01] * val[M10] * val[M33] + val[M00] * val[M11] * val[M33];
829 		tmp[M23] = val[M03] * val[M11] * val[M20] - val[M01] * val[M13] * val[M20] - val[M03] * val[M10] * val[M21] + val[M00]
830 			* val[M13] * val[M21] + val[M01] * val[M10] * val[M23] - val[M00] * val[M11] * val[M23];
831 		tmp[M30] = val[M12] * val[M21] * val[M30] - val[M11] * val[M22] * val[M30] - val[M12] * val[M20] * val[M31] + val[M10]
832 			* val[M22] * val[M31] + val[M11] * val[M20] * val[M32] - val[M10] * val[M21] * val[M32];
833 		tmp[M31] = val[M01] * val[M22] * val[M30] - val[M02] * val[M21] * val[M30] + val[M02] * val[M20] * val[M31] - val[M00]
834 			* val[M22] * val[M31] - val[M01] * val[M20] * val[M32] + val[M00] * val[M21] * val[M32];
835 		tmp[M32] = val[M02] * val[M11] * val[M30] - val[M01] * val[M12] * val[M30] - val[M02] * val[M10] * val[M31] + val[M00]
836 			* val[M12] * val[M31] + val[M01] * val[M10] * val[M32] - val[M00] * val[M11] * val[M32];
837 		tmp[M33] = val[M01] * val[M12] * val[M20] - val[M02] * val[M11] * val[M20] + val[M02] * val[M10] * val[M21] - val[M00]
838 			* val[M12] * val[M21] - val[M01] * val[M10] * val[M22] + val[M00] * val[M11] * val[M22];
839 
840 		float inv_det = 1.0f / l_det;
841 		val[M00] = tmp[M00] * inv_det;
842 		val[M01] = tmp[M01] * inv_det;
843 		val[M02] = tmp[M02] * inv_det;
844 		val[M03] = tmp[M03] * inv_det;
845 		val[M10] = tmp[M10] * inv_det;
846 		val[M11] = tmp[M11] * inv_det;
847 		val[M12] = tmp[M12] * inv_det;
848 		val[M13] = tmp[M13] * inv_det;
849 		val[M20] = tmp[M20] * inv_det;
850 		val[M21] = tmp[M21] * inv_det;
851 		val[M22] = tmp[M22] * inv_det;
852 		val[M23] = tmp[M23] * inv_det;
853 		val[M30] = tmp[M30] * inv_det;
854 		val[M31] = tmp[M31] * inv_det;
855 		val[M32] = tmp[M32] * inv_det;
856 		val[M33] = tmp[M33] * inv_det;
857 		return true;
858 	}
859 
860 	static inline void matrix4_mulVec(float* mat, float* vec) {
861 		float x = vec[0] * mat[M00] + vec[1] * mat[M01] + vec[2] * mat[M02] + mat[M03];
862 		float y = vec[0] * mat[M10] + vec[1] * mat[M11] + vec[2] * mat[M12] + mat[M13];
863 		float z = vec[0] * mat[M20] + vec[1] * mat[M21] + vec[2] * mat[M22] + mat[M23];
864 		vec[0] = x;
865 		vec[1] = y;
866 		vec[2] = z;
867 	}
868 
869 	static inline void matrix4_proj(float* mat, float* vec) {
870 		float inv_w = 1.0f / (vec[0] * mat[M30] + vec[1] * mat[M31] + vec[2] * mat[M32] + mat[M33]);
871 		float x = (vec[0] * mat[M00] + vec[1] * mat[M01] + vec[2] * mat[M02] + mat[M03]) * inv_w;
872 		float y = (vec[0] * mat[M10] + vec[1] * mat[M11] + vec[2] * mat[M12] + mat[M13]) * inv_w;
873 		float z = (vec[0] * mat[M20] + vec[1] * mat[M21] + vec[2] * mat[M22] + mat[M23]) * inv_w;
874 		vec[0] = x;
875 		vec[1] = y;
876 		vec[2] = z;
877 	}
878 
879 	static inline void matrix4_rot(float* mat, float* vec) {
880 		float x = vec[0] * mat[M00] + vec[1] * mat[M01] + vec[2] * mat[M02];
881 		float y = vec[0] * mat[M10] + vec[1] * mat[M11] + vec[2] * mat[M12];
882 		float z = vec[0] * mat[M20] + vec[1] * mat[M21] + vec[2] * mat[M22];
883 		vec[0] = x;
884 		vec[1] = y;
885 		vec[2] = z;
886 	}
887 	 */
888 
889 	/** Multiplies the matrix mata with matrix matb, storing the result in mata. The arrays are assumed to hold 4x4 column major
890 	 * matrices as you can get from {@link Matrix4#val}. This is the same as {@link Matrix4#mul(Matrix4)}.
891 	 *
892 	 * @param mata the first matrix.
893 	 * @param matb the second matrix. */
mul(float[] mata, float[] matb)894 	public static native void mul (float[] mata, float[] matb) /*-{ }-*/; /*
895 		matrix4_mul(mata, matb);
896 	*/
897 
898 	/** Multiplies the vector with the given matrix. The matrix array is assumed to hold a 4x4 column major matrix as you can get
899 	 * from {@link Matrix4#val}. The vector array is assumed to hold a 3-component vector, with x being the first element, y being
900 	 * the second and z being the last component. The result is stored in the vector array. This is the same as
901 	 * {@link Vector3#mul(Matrix4)}.
902 	 * @param mat the matrix
903 	 * @param vec the vector. */
mulVec(float[] mat, float[] vec)904 	public static native void mulVec (float[] mat, float[] vec) /*-{ }-*/; /*
905 		matrix4_mulVec(mat, vec);
906 	*/
907 
908 	/** Multiplies the vectors with the given matrix. The matrix array is assumed to hold a 4x4 column major matrix as you can get
909 	 * from {@link Matrix4#val}. The vectors array is assumed to hold 3-component vectors. Offset specifies the offset into the
910 	 * array where the x-component of the first vector is located. The numVecs parameter specifies the number of vectors stored in
911 	 * the vectors array. The stride parameter specifies the number of floats between subsequent vectors and must be >= 3. This is
912 	 * the same as {@link Vector3#mul(Matrix4)} applied to multiple vectors.
913 	 *
914 	 * @param mat the matrix
915 	 * @param vecs the vectors
916 	 * @param offset the offset into the vectors array
917 	 * @param numVecs the number of vectors
918 	 * @param stride the stride between vectors in floats */
mulVec(float[] mat, float[] vecs, int offset, int numVecs, int stride)919 	public static native void mulVec (float[] mat, float[] vecs, int offset, int numVecs, int stride) /*-{ }-*/; /*
920 		float* vecPtr = vecs + offset;
921 		for(int i = 0; i < numVecs; i++) {
922 			matrix4_mulVec(mat, vecPtr);
923 			vecPtr += stride;
924 		}
925 	*/
926 
927 	/** Multiplies the vector with the given matrix, performing a division by w. The matrix array is assumed to hold a 4x4 column
928 	 * major matrix as you can get from {@link Matrix4#val}. The vector array is assumed to hold a 3-component vector, with x being
929 	 * the first element, y being the second and z being the last component. The result is stored in the vector array. This is the
930 	 * same as {@link Vector3#prj(Matrix4)}.
931 	 * @param mat the matrix
932 	 * @param vec the vector. */
prj(float[] mat, float[] vec)933 	public static native void prj (float[] mat, float[] vec) /*-{ }-*/; /*
934 		matrix4_proj(mat, vec);
935 	*/
936 
937 	/** Multiplies the vectors with the given matrix, , performing a division by w. The matrix array is assumed to hold a 4x4 column
938 	 * major matrix as you can get from {@link Matrix4#val}. The vectors array is assumed to hold 3-component vectors. Offset
939 	 * specifies the offset into the array where the x-component of the first vector is located. The numVecs parameter specifies
940 	 * the number of vectors stored in the vectors array. The stride parameter specifies the number of floats between subsequent
941 	 * vectors and must be >= 3. This is the same as {@link Vector3#prj(Matrix4)} applied to multiple vectors.
942 	 *
943 	 * @param mat the matrix
944 	 * @param vecs the vectors
945 	 * @param offset the offset into the vectors array
946 	 * @param numVecs the number of vectors
947 	 * @param stride the stride between vectors in floats */
prj(float[] mat, float[] vecs, int offset, int numVecs, int stride)948 	public static native void prj (float[] mat, float[] vecs, int offset, int numVecs, int stride) /*-{ }-*/; /*
949 		float* vecPtr = vecs + offset;
950 		for(int i = 0; i < numVecs; i++) {
951 			matrix4_proj(mat, vecPtr);
952 			vecPtr += stride;
953 		}
954 	*/
955 
956 	/** Multiplies the vector with the top most 3x3 sub-matrix of the given matrix. The matrix array is assumed to hold a 4x4 column
957 	 * major matrix as you can get from {@link Matrix4#val}. The vector array is assumed to hold a 3-component vector, with x being
958 	 * the first element, y being the second and z being the last component. The result is stored in the vector array. This is the
959 	 * same as {@link Vector3#rot(Matrix4)}.
960 	 * @param mat the matrix
961 	 * @param vec the vector. */
rot(float[] mat, float[] vec)962 	public static native void rot (float[] mat, float[] vec) /*-{ }-*/; /*
963 		matrix4_rot(mat, vec);
964 	*/
965 
966 	/** Multiplies the vectors with the top most 3x3 sub-matrix of the given matrix. The matrix array is assumed to hold a 4x4
967 	 * column major matrix as you can get from {@link Matrix4#val}. The vectors array is assumed to hold 3-component vectors.
968 	 * Offset specifies the offset into the array where the x-component of the first vector is located. The numVecs parameter
969 	 * specifies the number of vectors stored in the vectors array. The stride parameter specifies the number of floats between
970 	 * subsequent vectors and must be >= 3. This is the same as {@link Vector3#rot(Matrix4)} applied to multiple vectors.
971 	 *
972 	 * @param mat the matrix
973 	 * @param vecs the vectors
974 	 * @param offset the offset into the vectors array
975 	 * @param numVecs the number of vectors
976 	 * @param stride the stride between vectors in floats */
rot(float[] mat, float[] vecs, int offset, int numVecs, int stride)977 	public static native void rot (float[] mat, float[] vecs, int offset, int numVecs, int stride) /*-{ }-*/; /*
978 		float* vecPtr = vecs + offset;
979 		for(int i = 0; i < numVecs; i++) {
980 			matrix4_rot(mat, vecPtr);
981 			vecPtr += stride;
982 		}
983 	*/
984 
985 	/** Computes the inverse of the given matrix. The matrix array is assumed to hold a 4x4 column major matrix as you can get from
986 	 * {@link Matrix4#val}.
987 	 * @param values the matrix values.
988 	 * @return false in case the inverse could not be calculated, true otherwise. */
inv(float[] values)989 	public static native boolean inv (float[] values) /*-{ }-*/; /*
990 		return matrix4_inv(values);
991 	*/
992 
993 	/** Computes the determinante of the given matrix. The matrix array is assumed to hold a 4x4 column major matrix as you can get
994 	 * from {@link Matrix4#val}.
995 	 * @param values the matrix values.
996 	 * @return the determinante. */
det(float[] values)997 	public static native float det (float[] values) /*-{ }-*/; /*
998 		return matrix4_det(values);
999 	*/
1000 
1001 	// @on
1002 	/** Postmultiplies this matrix by a translation matrix. Postmultiplication is also used by OpenGL ES'
1003 	 * glTranslate/glRotate/glScale
1004 	 * @param translation
1005 	 * @return This matrix for the purpose of chaining methods together. */
translate(Vector3 translation)1006 	public Matrix4 translate (Vector3 translation) {
1007 		return translate(translation.x, translation.y, translation.z);
1008 	}
1009 
1010 	/** Postmultiplies this matrix by a translation matrix. Postmultiplication is also used by OpenGL ES' 1.x
1011 	 * glTranslate/glRotate/glScale.
1012 	 * @param x Translation in the x-axis.
1013 	 * @param y Translation in the y-axis.
1014 	 * @param z Translation in the z-axis.
1015 	 * @return This matrix for the purpose of chaining methods together. */
translate(float x, float y, float z)1016 	public Matrix4 translate (float x, float y, float z) {
1017 		tmp[M00] = 1;
1018 		tmp[M01] = 0;
1019 		tmp[M02] = 0;
1020 		tmp[M03] = x;
1021 		tmp[M10] = 0;
1022 		tmp[M11] = 1;
1023 		tmp[M12] = 0;
1024 		tmp[M13] = y;
1025 		tmp[M20] = 0;
1026 		tmp[M21] = 0;
1027 		tmp[M22] = 1;
1028 		tmp[M23] = z;
1029 		tmp[M30] = 0;
1030 		tmp[M31] = 0;
1031 		tmp[M32] = 0;
1032 		tmp[M33] = 1;
1033 
1034 		mul(val, tmp);
1035 		return this;
1036 	}
1037 
1038 	/** Postmultiplies this matrix with a (counter-clockwise) rotation matrix. Postmultiplication is also used by OpenGL ES' 1.x
1039 	 * glTranslate/glRotate/glScale.
1040 	 *
1041 	 * @param axis The vector axis to rotate around.
1042 	 * @param angle The angle in degrees.
1043 	 * @return This matrix for the purpose of chaining methods together. */
rotate(Vector3 axis, float angle)1044 	public Matrix4 rotate (Vector3 axis, float angle) {
1045 		if (angle == 0) return this;
1046 		quat.set(axis, angle);
1047 		return rotate(quat);
1048 	}
1049 
1050 	/** Postmultiplies this matrix with a (counter-clockwise) rotation matrix. Postmultiplication is also used by OpenGL ES' 1.x
1051 	 * glTranslate/glRotate/glScale
1052 	 * @param axisX The x-axis component of the vector to rotate around.
1053 	 * @param axisY The y-axis component of the vector to rotate around.
1054 	 * @param axisZ The z-axis component of the vector to rotate around.
1055 	 * @param angle The angle in degrees
1056 	 * @return This matrix for the purpose of chaining methods together. */
rotate(float axisX, float axisY, float axisZ, float angle)1057 	public Matrix4 rotate (float axisX, float axisY, float axisZ, float angle) {
1058 		if (angle == 0) return this;
1059 		quat.set(tmpV.set(axisX, axisY, axisZ), angle);
1060 		return rotate(quat);
1061 	}
1062 
1063 	/** Postmultiplies this matrix with a (counter-clockwise) rotation matrix. Postmultiplication is also used by OpenGL ES' 1.x
1064 	 * glTranslate/glRotate/glScale.
1065 	 *
1066 	 * @param rotation
1067 	 * @return This matrix for the purpose of chaining methods together. */
rotate(Quaternion rotation)1068 	public Matrix4 rotate (Quaternion rotation) {
1069 		rotation.toMatrix(tmp);
1070 		mul(val, tmp);
1071 		return this;
1072 	}
1073 
1074 	/** Postmultiplies this matrix with a scale matrix. Postmultiplication is also used by OpenGL ES' 1.x
1075 	 * glTranslate/glRotate/glScale.
1076 	 * @param scaleX The scale in the x-axis.
1077 	 * @param scaleY The scale in the y-axis.
1078 	 * @param scaleZ The scale in the z-axis.
1079 	 * @return This matrix for the purpose of chaining methods together. */
scale(float scaleX, float scaleY, float scaleZ)1080 	public Matrix4 scale (float scaleX, float scaleY, float scaleZ) {
1081 		tmp[M00] = scaleX;
1082 		tmp[M01] = 0;
1083 		tmp[M02] = 0;
1084 		tmp[M03] = 0;
1085 		tmp[M10] = 0;
1086 		tmp[M11] = scaleY;
1087 		tmp[M12] = 0;
1088 		tmp[M13] = 0;
1089 		tmp[M20] = 0;
1090 		tmp[M21] = 0;
1091 		tmp[M22] = scaleZ;
1092 		tmp[M23] = 0;
1093 		tmp[M30] = 0;
1094 		tmp[M31] = 0;
1095 		tmp[M32] = 0;
1096 		tmp[M33] = 1;
1097 
1098 		mul(val, tmp);
1099 		return this;
1100 	}
1101 }
1102