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