OLD | NEW |
(Empty) | |
| 1 /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. |
| 2 |
| 3 Redistribution and use in source and binary forms, with or without modification, |
| 4 are permitted provided that the following conditions are met: |
| 5 |
| 6 * Redistributions of source code must retain the above copyright notice, this |
| 7 list of conditions and the following disclaimer. |
| 8 * Redistributions in binary form must reproduce the above copyright notice, |
| 9 this list of conditions and the following disclaimer in the documentation |
| 10 and/or other materials provided with the distribution. |
| 11 |
| 12 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| 13 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 14 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 15 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR |
| 16 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 17 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 18 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
| 19 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 20 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 21 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ |
| 22 |
| 23 /** |
| 24 * @class 4x4 Matrix |
| 25 * @name mat4 |
| 26 */ |
| 27 var mat4 = {}; |
| 28 |
| 29 /** |
| 30 * Creates a new identity mat4 |
| 31 * |
| 32 * @returns {mat4} a new 4x4 matrix |
| 33 */ |
| 34 mat4.create = function() { |
| 35 var out = new GLMAT_ARRAY_TYPE(16); |
| 36 out[0] = 1; |
| 37 out[1] = 0; |
| 38 out[2] = 0; |
| 39 out[3] = 0; |
| 40 out[4] = 0; |
| 41 out[5] = 1; |
| 42 out[6] = 0; |
| 43 out[7] = 0; |
| 44 out[8] = 0; |
| 45 out[9] = 0; |
| 46 out[10] = 1; |
| 47 out[11] = 0; |
| 48 out[12] = 0; |
| 49 out[13] = 0; |
| 50 out[14] = 0; |
| 51 out[15] = 1; |
| 52 return out; |
| 53 }; |
| 54 |
| 55 /** |
| 56 * Creates a new mat4 initialized with values from an existing matrix |
| 57 * |
| 58 * @param {mat4} a matrix to clone |
| 59 * @returns {mat4} a new 4x4 matrix |
| 60 */ |
| 61 mat4.clone = function(a) { |
| 62 var out = new GLMAT_ARRAY_TYPE(16); |
| 63 out[0] = a[0]; |
| 64 out[1] = a[1]; |
| 65 out[2] = a[2]; |
| 66 out[3] = a[3]; |
| 67 out[4] = a[4]; |
| 68 out[5] = a[5]; |
| 69 out[6] = a[6]; |
| 70 out[7] = a[7]; |
| 71 out[8] = a[8]; |
| 72 out[9] = a[9]; |
| 73 out[10] = a[10]; |
| 74 out[11] = a[11]; |
| 75 out[12] = a[12]; |
| 76 out[13] = a[13]; |
| 77 out[14] = a[14]; |
| 78 out[15] = a[15]; |
| 79 return out; |
| 80 }; |
| 81 |
| 82 /** |
| 83 * Copy the values from one mat4 to another |
| 84 * |
| 85 * @param {mat4} out the receiving matrix |
| 86 * @param {mat4} a the source matrix |
| 87 * @returns {mat4} out |
| 88 */ |
| 89 mat4.copy = function(out, a) { |
| 90 out[0] = a[0]; |
| 91 out[1] = a[1]; |
| 92 out[2] = a[2]; |
| 93 out[3] = a[3]; |
| 94 out[4] = a[4]; |
| 95 out[5] = a[5]; |
| 96 out[6] = a[6]; |
| 97 out[7] = a[7]; |
| 98 out[8] = a[8]; |
| 99 out[9] = a[9]; |
| 100 out[10] = a[10]; |
| 101 out[11] = a[11]; |
| 102 out[12] = a[12]; |
| 103 out[13] = a[13]; |
| 104 out[14] = a[14]; |
| 105 out[15] = a[15]; |
| 106 return out; |
| 107 }; |
| 108 |
| 109 /** |
| 110 * Set a mat4 to the identity matrix |
| 111 * |
| 112 * @param {mat4} out the receiving matrix |
| 113 * @returns {mat4} out |
| 114 */ |
| 115 mat4.identity = function(out) { |
| 116 out[0] = 1; |
| 117 out[1] = 0; |
| 118 out[2] = 0; |
| 119 out[3] = 0; |
| 120 out[4] = 0; |
| 121 out[5] = 1; |
| 122 out[6] = 0; |
| 123 out[7] = 0; |
| 124 out[8] = 0; |
| 125 out[9] = 0; |
| 126 out[10] = 1; |
| 127 out[11] = 0; |
| 128 out[12] = 0; |
| 129 out[13] = 0; |
| 130 out[14] = 0; |
| 131 out[15] = 1; |
| 132 return out; |
| 133 }; |
| 134 |
| 135 /** |
| 136 * Transpose the values of a mat4 |
| 137 * |
| 138 * @param {mat4} out the receiving matrix |
| 139 * @param {mat4} a the source matrix |
| 140 * @returns {mat4} out |
| 141 */ |
| 142 mat4.transpose = function(out, a) { |
| 143 // If we are transposing ourselves we can skip a few steps but have to cache
some values |
| 144 if (out === a) { |
| 145 var a01 = a[1], a02 = a[2], a03 = a[3], |
| 146 a12 = a[6], a13 = a[7], |
| 147 a23 = a[11]; |
| 148 |
| 149 out[1] = a[4]; |
| 150 out[2] = a[8]; |
| 151 out[3] = a[12]; |
| 152 out[4] = a01; |
| 153 out[6] = a[9]; |
| 154 out[7] = a[13]; |
| 155 out[8] = a02; |
| 156 out[9] = a12; |
| 157 out[11] = a[14]; |
| 158 out[12] = a03; |
| 159 out[13] = a13; |
| 160 out[14] = a23; |
| 161 } else { |
| 162 out[0] = a[0]; |
| 163 out[1] = a[4]; |
| 164 out[2] = a[8]; |
| 165 out[3] = a[12]; |
| 166 out[4] = a[1]; |
| 167 out[5] = a[5]; |
| 168 out[6] = a[9]; |
| 169 out[7] = a[13]; |
| 170 out[8] = a[2]; |
| 171 out[9] = a[6]; |
| 172 out[10] = a[10]; |
| 173 out[11] = a[14]; |
| 174 out[12] = a[3]; |
| 175 out[13] = a[7]; |
| 176 out[14] = a[11]; |
| 177 out[15] = a[15]; |
| 178 } |
| 179 |
| 180 return out; |
| 181 }; |
| 182 |
| 183 /** |
| 184 * Inverts a mat4 |
| 185 * |
| 186 * @param {mat4} out the receiving matrix |
| 187 * @param {mat4} a the source matrix |
| 188 * @returns {mat4} out |
| 189 */ |
| 190 mat4.invert = function(out, a) { |
| 191 var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3], |
| 192 a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7], |
| 193 a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11], |
| 194 a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15], |
| 195 |
| 196 b00 = a00 * a11 - a01 * a10, |
| 197 b01 = a00 * a12 - a02 * a10, |
| 198 b02 = a00 * a13 - a03 * a10, |
| 199 b03 = a01 * a12 - a02 * a11, |
| 200 b04 = a01 * a13 - a03 * a11, |
| 201 b05 = a02 * a13 - a03 * a12, |
| 202 b06 = a20 * a31 - a21 * a30, |
| 203 b07 = a20 * a32 - a22 * a30, |
| 204 b08 = a20 * a33 - a23 * a30, |
| 205 b09 = a21 * a32 - a22 * a31, |
| 206 b10 = a21 * a33 - a23 * a31, |
| 207 b11 = a22 * a33 - a23 * a32, |
| 208 |
| 209 // Calculate the determinant |
| 210 det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 *
b06; |
| 211 |
| 212 if (!det) { |
| 213 return null; |
| 214 } |
| 215 det = 1.0 / det; |
| 216 |
| 217 out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; |
| 218 out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; |
| 219 out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; |
| 220 out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; |
| 221 out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; |
| 222 out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; |
| 223 out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; |
| 224 out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; |
| 225 out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; |
| 226 out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; |
| 227 out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; |
| 228 out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; |
| 229 out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; |
| 230 out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; |
| 231 out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; |
| 232 out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; |
| 233 |
| 234 return out; |
| 235 }; |
| 236 |
| 237 /** |
| 238 * Calculates the adjugate of a mat4 |
| 239 * |
| 240 * @param {mat4} out the receiving matrix |
| 241 * @param {mat4} a the source matrix |
| 242 * @returns {mat4} out |
| 243 */ |
| 244 mat4.adjoint = function(out, a) { |
| 245 var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3], |
| 246 a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7], |
| 247 a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11], |
| 248 a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; |
| 249 |
| 250 out[0] = (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) +
a31 * (a12 * a23 - a13 * a22)); |
| 251 out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) +
a31 * (a02 * a23 - a03 * a22)); |
| 252 out[2] = (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) +
a31 * (a02 * a13 - a03 * a12)); |
| 253 out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) +
a21 * (a02 * a13 - a03 * a12)); |
| 254 out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) +
a30 * (a12 * a23 - a13 * a22)); |
| 255 out[5] = (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) +
a30 * (a02 * a23 - a03 * a22)); |
| 256 out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) +
a30 * (a02 * a13 - a03 * a12)); |
| 257 out[7] = (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) +
a20 * (a02 * a13 - a03 * a12)); |
| 258 out[8] = (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) +
a30 * (a11 * a23 - a13 * a21)); |
| 259 out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) +
a30 * (a01 * a23 - a03 * a21)); |
| 260 out[10] = (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) +
a30 * (a01 * a13 - a03 * a11)); |
| 261 out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) +
a20 * (a01 * a13 - a03 * a11)); |
| 262 out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) +
a30 * (a11 * a22 - a12 * a21)); |
| 263 out[13] = (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) +
a30 * (a01 * a22 - a02 * a21)); |
| 264 out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) +
a30 * (a01 * a12 - a02 * a11)); |
| 265 out[15] = (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) +
a20 * (a01 * a12 - a02 * a11)); |
| 266 return out; |
| 267 }; |
| 268 |
| 269 /** |
| 270 * Calculates the determinant of a mat4 |
| 271 * |
| 272 * @param {mat4} a the source matrix |
| 273 * @returns {Number} determinant of a |
| 274 */ |
| 275 mat4.determinant = function (a) { |
| 276 var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3], |
| 277 a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7], |
| 278 a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11], |
| 279 a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15], |
| 280 |
| 281 b00 = a00 * a11 - a01 * a10, |
| 282 b01 = a00 * a12 - a02 * a10, |
| 283 b02 = a00 * a13 - a03 * a10, |
| 284 b03 = a01 * a12 - a02 * a11, |
| 285 b04 = a01 * a13 - a03 * a11, |
| 286 b05 = a02 * a13 - a03 * a12, |
| 287 b06 = a20 * a31 - a21 * a30, |
| 288 b07 = a20 * a32 - a22 * a30, |
| 289 b08 = a20 * a33 - a23 * a30, |
| 290 b09 = a21 * a32 - a22 * a31, |
| 291 b10 = a21 * a33 - a23 * a31, |
| 292 b11 = a22 * a33 - a23 * a32; |
| 293 |
| 294 // Calculate the determinant |
| 295 return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06
; |
| 296 }; |
| 297 |
| 298 /** |
| 299 * Multiplies two mat4's |
| 300 * |
| 301 * @param {mat4} out the receiving matrix |
| 302 * @param {mat4} a the first operand |
| 303 * @param {mat4} b the second operand |
| 304 * @returns {mat4} out |
| 305 */ |
| 306 mat4.multiply = function (out, a, b) { |
| 307 var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3], |
| 308 a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7], |
| 309 a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11], |
| 310 a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; |
| 311 |
| 312 // Cache only the current line of the second matrix |
| 313 var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; |
| 314 out[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30; |
| 315 out[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31; |
| 316 out[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32; |
| 317 out[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33; |
| 318 |
| 319 b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7]; |
| 320 out[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30; |
| 321 out[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31; |
| 322 out[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32; |
| 323 out[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33; |
| 324 |
| 325 b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11]; |
| 326 out[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30; |
| 327 out[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31; |
| 328 out[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32; |
| 329 out[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33; |
| 330 |
| 331 b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15]; |
| 332 out[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30; |
| 333 out[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31; |
| 334 out[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32; |
| 335 out[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33; |
| 336 return out; |
| 337 }; |
| 338 |
| 339 /** |
| 340 * Alias for {@link mat4.multiply} |
| 341 * @function |
| 342 */ |
| 343 mat4.mul = mat4.multiply; |
| 344 |
| 345 /** |
| 346 * Translate a mat4 by the given vector |
| 347 * |
| 348 * @param {mat4} out the receiving matrix |
| 349 * @param {mat4} a the matrix to translate |
| 350 * @param {vec3} v vector to translate by |
| 351 * @returns {mat4} out |
| 352 */ |
| 353 mat4.translate = function (out, a, v) { |
| 354 var x = v[0], y = v[1], z = v[2], |
| 355 a00, a01, a02, a03, |
| 356 a10, a11, a12, a13, |
| 357 a20, a21, a22, a23; |
| 358 |
| 359 if (a === out) { |
| 360 out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; |
| 361 out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; |
| 362 out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; |
| 363 out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; |
| 364 } else { |
| 365 a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; |
| 366 a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; |
| 367 a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; |
| 368 |
| 369 out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03; |
| 370 out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13; |
| 371 out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23; |
| 372 |
| 373 out[12] = a00 * x + a10 * y + a20 * z + a[12]; |
| 374 out[13] = a01 * x + a11 * y + a21 * z + a[13]; |
| 375 out[14] = a02 * x + a12 * y + a22 * z + a[14]; |
| 376 out[15] = a03 * x + a13 * y + a23 * z + a[15]; |
| 377 } |
| 378 |
| 379 return out; |
| 380 }; |
| 381 |
| 382 /** |
| 383 * Scales the mat4 by the dimensions in the given vec3 |
| 384 * |
| 385 * @param {mat4} out the receiving matrix |
| 386 * @param {mat4} a the matrix to scale |
| 387 * @param {vec3} v the vec3 to scale the matrix by |
| 388 * @returns {mat4} out |
| 389 **/ |
| 390 mat4.scale = function(out, a, v) { |
| 391 var x = v[0], y = v[1], z = v[2]; |
| 392 |
| 393 out[0] = a[0] * x; |
| 394 out[1] = a[1] * x; |
| 395 out[2] = a[2] * x; |
| 396 out[3] = a[3] * x; |
| 397 out[4] = a[4] * y; |
| 398 out[5] = a[5] * y; |
| 399 out[6] = a[6] * y; |
| 400 out[7] = a[7] * y; |
| 401 out[8] = a[8] * z; |
| 402 out[9] = a[9] * z; |
| 403 out[10] = a[10] * z; |
| 404 out[11] = a[11] * z; |
| 405 out[12] = a[12]; |
| 406 out[13] = a[13]; |
| 407 out[14] = a[14]; |
| 408 out[15] = a[15]; |
| 409 return out; |
| 410 }; |
| 411 |
| 412 /** |
| 413 * Rotates a mat4 by the given angle |
| 414 * |
| 415 * @param {mat4} out the receiving matrix |
| 416 * @param {mat4} a the matrix to rotate |
| 417 * @param {Number} rad the angle to rotate the matrix by |
| 418 * @param {vec3} axis the axis to rotate around |
| 419 * @returns {mat4} out |
| 420 */ |
| 421 mat4.rotate = function (out, a, rad, axis) { |
| 422 var x = axis[0], y = axis[1], z = axis[2], |
| 423 len = Math.sqrt(x * x + y * y + z * z), |
| 424 s, c, t, |
| 425 a00, a01, a02, a03, |
| 426 a10, a11, a12, a13, |
| 427 a20, a21, a22, a23, |
| 428 b00, b01, b02, |
| 429 b10, b11, b12, |
| 430 b20, b21, b22; |
| 431 |
| 432 if (Math.abs(len) < GLMAT_EPSILON) { return null; } |
| 433 |
| 434 len = 1 / len; |
| 435 x *= len; |
| 436 y *= len; |
| 437 z *= len; |
| 438 |
| 439 s = Math.sin(rad); |
| 440 c = Math.cos(rad); |
| 441 t = 1 - c; |
| 442 |
| 443 a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; |
| 444 a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; |
| 445 a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; |
| 446 |
| 447 // Construct the elements of the rotation matrix |
| 448 b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s; |
| 449 b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s; |
| 450 b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c; |
| 451 |
| 452 // Perform rotation-specific matrix multiplication |
| 453 out[0] = a00 * b00 + a10 * b01 + a20 * b02; |
| 454 out[1] = a01 * b00 + a11 * b01 + a21 * b02; |
| 455 out[2] = a02 * b00 + a12 * b01 + a22 * b02; |
| 456 out[3] = a03 * b00 + a13 * b01 + a23 * b02; |
| 457 out[4] = a00 * b10 + a10 * b11 + a20 * b12; |
| 458 out[5] = a01 * b10 + a11 * b11 + a21 * b12; |
| 459 out[6] = a02 * b10 + a12 * b11 + a22 * b12; |
| 460 out[7] = a03 * b10 + a13 * b11 + a23 * b12; |
| 461 out[8] = a00 * b20 + a10 * b21 + a20 * b22; |
| 462 out[9] = a01 * b20 + a11 * b21 + a21 * b22; |
| 463 out[10] = a02 * b20 + a12 * b21 + a22 * b22; |
| 464 out[11] = a03 * b20 + a13 * b21 + a23 * b22; |
| 465 |
| 466 if (a !== out) { // If the source and destination differ, copy the unchanged
last row |
| 467 out[12] = a[12]; |
| 468 out[13] = a[13]; |
| 469 out[14] = a[14]; |
| 470 out[15] = a[15]; |
| 471 } |
| 472 return out; |
| 473 }; |
| 474 |
| 475 /** |
| 476 * Rotates a matrix by the given angle around the X axis |
| 477 * |
| 478 * @param {mat4} out the receiving matrix |
| 479 * @param {mat4} a the matrix to rotate |
| 480 * @param {Number} rad the angle to rotate the matrix by |
| 481 * @returns {mat4} out |
| 482 */ |
| 483 mat4.rotateX = function (out, a, rad) { |
| 484 var s = Math.sin(rad), |
| 485 c = Math.cos(rad), |
| 486 a10 = a[4], |
| 487 a11 = a[5], |
| 488 a12 = a[6], |
| 489 a13 = a[7], |
| 490 a20 = a[8], |
| 491 a21 = a[9], |
| 492 a22 = a[10], |
| 493 a23 = a[11]; |
| 494 |
| 495 if (a !== out) { // If the source and destination differ, copy the unchanged
rows |
| 496 out[0] = a[0]; |
| 497 out[1] = a[1]; |
| 498 out[2] = a[2]; |
| 499 out[3] = a[3]; |
| 500 out[12] = a[12]; |
| 501 out[13] = a[13]; |
| 502 out[14] = a[14]; |
| 503 out[15] = a[15]; |
| 504 } |
| 505 |
| 506 // Perform axis-specific matrix multiplication |
| 507 out[4] = a10 * c + a20 * s; |
| 508 out[5] = a11 * c + a21 * s; |
| 509 out[6] = a12 * c + a22 * s; |
| 510 out[7] = a13 * c + a23 * s; |
| 511 out[8] = a20 * c - a10 * s; |
| 512 out[9] = a21 * c - a11 * s; |
| 513 out[10] = a22 * c - a12 * s; |
| 514 out[11] = a23 * c - a13 * s; |
| 515 return out; |
| 516 }; |
| 517 |
| 518 /** |
| 519 * Rotates a matrix by the given angle around the Y axis |
| 520 * |
| 521 * @param {mat4} out the receiving matrix |
| 522 * @param {mat4} a the matrix to rotate |
| 523 * @param {Number} rad the angle to rotate the matrix by |
| 524 * @returns {mat4} out |
| 525 */ |
| 526 mat4.rotateY = function (out, a, rad) { |
| 527 var s = Math.sin(rad), |
| 528 c = Math.cos(rad), |
| 529 a00 = a[0], |
| 530 a01 = a[1], |
| 531 a02 = a[2], |
| 532 a03 = a[3], |
| 533 a20 = a[8], |
| 534 a21 = a[9], |
| 535 a22 = a[10], |
| 536 a23 = a[11]; |
| 537 |
| 538 if (a !== out) { // If the source and destination differ, copy the unchanged
rows |
| 539 out[4] = a[4]; |
| 540 out[5] = a[5]; |
| 541 out[6] = a[6]; |
| 542 out[7] = a[7]; |
| 543 out[12] = a[12]; |
| 544 out[13] = a[13]; |
| 545 out[14] = a[14]; |
| 546 out[15] = a[15]; |
| 547 } |
| 548 |
| 549 // Perform axis-specific matrix multiplication |
| 550 out[0] = a00 * c - a20 * s; |
| 551 out[1] = a01 * c - a21 * s; |
| 552 out[2] = a02 * c - a22 * s; |
| 553 out[3] = a03 * c - a23 * s; |
| 554 out[8] = a00 * s + a20 * c; |
| 555 out[9] = a01 * s + a21 * c; |
| 556 out[10] = a02 * s + a22 * c; |
| 557 out[11] = a03 * s + a23 * c; |
| 558 return out; |
| 559 }; |
| 560 |
| 561 /** |
| 562 * Rotates a matrix by the given angle around the Z axis |
| 563 * |
| 564 * @param {mat4} out the receiving matrix |
| 565 * @param {mat4} a the matrix to rotate |
| 566 * @param {Number} rad the angle to rotate the matrix by |
| 567 * @returns {mat4} out |
| 568 */ |
| 569 mat4.rotateZ = function (out, a, rad) { |
| 570 var s = Math.sin(rad), |
| 571 c = Math.cos(rad), |
| 572 a00 = a[0], |
| 573 a01 = a[1], |
| 574 a02 = a[2], |
| 575 a03 = a[3], |
| 576 a10 = a[4], |
| 577 a11 = a[5], |
| 578 a12 = a[6], |
| 579 a13 = a[7]; |
| 580 |
| 581 if (a !== out) { // If the source and destination differ, copy the unchanged
last row |
| 582 out[8] = a[8]; |
| 583 out[9] = a[9]; |
| 584 out[10] = a[10]; |
| 585 out[11] = a[11]; |
| 586 out[12] = a[12]; |
| 587 out[13] = a[13]; |
| 588 out[14] = a[14]; |
| 589 out[15] = a[15]; |
| 590 } |
| 591 |
| 592 // Perform axis-specific matrix multiplication |
| 593 out[0] = a00 * c + a10 * s; |
| 594 out[1] = a01 * c + a11 * s; |
| 595 out[2] = a02 * c + a12 * s; |
| 596 out[3] = a03 * c + a13 * s; |
| 597 out[4] = a10 * c - a00 * s; |
| 598 out[5] = a11 * c - a01 * s; |
| 599 out[6] = a12 * c - a02 * s; |
| 600 out[7] = a13 * c - a03 * s; |
| 601 return out; |
| 602 }; |
| 603 |
| 604 /** |
| 605 * Creates a matrix from a quaternion rotation and vector translation |
| 606 * This is equivalent to (but much faster than): |
| 607 * |
| 608 * mat4.identity(dest); |
| 609 * mat4.translate(dest, vec); |
| 610 * var quatMat = mat4.create(); |
| 611 * quat4.toMat4(quat, quatMat); |
| 612 * mat4.multiply(dest, quatMat); |
| 613 * |
| 614 * @param {mat4} out mat4 receiving operation result |
| 615 * @param {quat4} q Rotation quaternion |
| 616 * @param {vec3} v Translation vector |
| 617 * @returns {mat4} out |
| 618 */ |
| 619 mat4.fromRotationTranslation = function (out, q, v) { |
| 620 // Quaternion math |
| 621 var x = q[0], y = q[1], z = q[2], w = q[3], |
| 622 x2 = x + x, |
| 623 y2 = y + y, |
| 624 z2 = z + z, |
| 625 |
| 626 xx = x * x2, |
| 627 xy = x * y2, |
| 628 xz = x * z2, |
| 629 yy = y * y2, |
| 630 yz = y * z2, |
| 631 zz = z * z2, |
| 632 wx = w * x2, |
| 633 wy = w * y2, |
| 634 wz = w * z2; |
| 635 |
| 636 out[0] = 1 - (yy + zz); |
| 637 out[1] = xy + wz; |
| 638 out[2] = xz - wy; |
| 639 out[3] = 0; |
| 640 out[4] = xy - wz; |
| 641 out[5] = 1 - (xx + zz); |
| 642 out[6] = yz + wx; |
| 643 out[7] = 0; |
| 644 out[8] = xz + wy; |
| 645 out[9] = yz - wx; |
| 646 out[10] = 1 - (xx + yy); |
| 647 out[11] = 0; |
| 648 out[12] = v[0]; |
| 649 out[13] = v[1]; |
| 650 out[14] = v[2]; |
| 651 out[15] = 1; |
| 652 |
| 653 return out; |
| 654 }; |
| 655 |
| 656 /** |
| 657 * Calculates a 4x4 matrix from the given quaternion |
| 658 * |
| 659 * @param {mat4} out mat4 receiving operation result |
| 660 * @param {quat} q Quaternion to create matrix from |
| 661 * |
| 662 * @returns {mat4} out |
| 663 */ |
| 664 mat4.fromQuat = function (out, q) { |
| 665 var x = q[0], y = q[1], z = q[2], w = q[3], |
| 666 x2 = x + x, |
| 667 y2 = y + y, |
| 668 z2 = z + z, |
| 669 |
| 670 xx = x * x2, |
| 671 xy = x * y2, |
| 672 xz = x * z2, |
| 673 yy = y * y2, |
| 674 yz = y * z2, |
| 675 zz = z * z2, |
| 676 wx = w * x2, |
| 677 wy = w * y2, |
| 678 wz = w * z2; |
| 679 |
| 680 out[0] = 1 - (yy + zz); |
| 681 out[1] = xy + wz; |
| 682 out[2] = xz - wy; |
| 683 out[3] = 0; |
| 684 |
| 685 out[4] = xy - wz; |
| 686 out[5] = 1 - (xx + zz); |
| 687 out[6] = yz + wx; |
| 688 out[7] = 0; |
| 689 |
| 690 out[8] = xz + wy; |
| 691 out[9] = yz - wx; |
| 692 out[10] = 1 - (xx + yy); |
| 693 out[11] = 0; |
| 694 |
| 695 out[12] = 0; |
| 696 out[13] = 0; |
| 697 out[14] = 0; |
| 698 out[15] = 1; |
| 699 |
| 700 return out; |
| 701 }; |
| 702 |
| 703 /** |
| 704 * Generates a frustum matrix with the given bounds |
| 705 * |
| 706 * @param {mat4} out mat4 frustum matrix will be written into |
| 707 * @param {Number} left Left bound of the frustum |
| 708 * @param {Number} right Right bound of the frustum |
| 709 * @param {Number} bottom Bottom bound of the frustum |
| 710 * @param {Number} top Top bound of the frustum |
| 711 * @param {Number} near Near bound of the frustum |
| 712 * @param {Number} far Far bound of the frustum |
| 713 * @returns {mat4} out |
| 714 */ |
| 715 mat4.frustum = function (out, left, right, bottom, top, near, far) { |
| 716 var rl = 1 / (right - left), |
| 717 tb = 1 / (top - bottom), |
| 718 nf = 1 / (near - far); |
| 719 out[0] = (near * 2) * rl; |
| 720 out[1] = 0; |
| 721 out[2] = 0; |
| 722 out[3] = 0; |
| 723 out[4] = 0; |
| 724 out[5] = (near * 2) * tb; |
| 725 out[6] = 0; |
| 726 out[7] = 0; |
| 727 out[8] = (right + left) * rl; |
| 728 out[9] = (top + bottom) * tb; |
| 729 out[10] = (far + near) * nf; |
| 730 out[11] = -1; |
| 731 out[12] = 0; |
| 732 out[13] = 0; |
| 733 out[14] = (far * near * 2) * nf; |
| 734 out[15] = 0; |
| 735 return out; |
| 736 }; |
| 737 |
| 738 /** |
| 739 * Generates a perspective projection matrix with the given bounds |
| 740 * |
| 741 * @param {mat4} out mat4 frustum matrix will be written into |
| 742 * @param {number} fovy Vertical field of view in radians |
| 743 * @param {number} aspect Aspect ratio. typically viewport width/height |
| 744 * @param {number} near Near bound of the frustum |
| 745 * @param {number} far Far bound of the frustum |
| 746 * @returns {mat4} out |
| 747 */ |
| 748 mat4.perspective = function (out, fovy, aspect, near, far) { |
| 749 var f = 1.0 / Math.tan(fovy / 2), |
| 750 nf = 1 / (near - far); |
| 751 out[0] = f / aspect; |
| 752 out[1] = 0; |
| 753 out[2] = 0; |
| 754 out[3] = 0; |
| 755 out[4] = 0; |
| 756 out[5] = f; |
| 757 out[6] = 0; |
| 758 out[7] = 0; |
| 759 out[8] = 0; |
| 760 out[9] = 0; |
| 761 out[10] = (far + near) * nf; |
| 762 out[11] = -1; |
| 763 out[12] = 0; |
| 764 out[13] = 0; |
| 765 out[14] = (2 * far * near) * nf; |
| 766 out[15] = 0; |
| 767 return out; |
| 768 }; |
| 769 |
| 770 /** |
| 771 * Generates a orthogonal projection matrix with the given bounds |
| 772 * |
| 773 * @param {mat4} out mat4 frustum matrix will be written into |
| 774 * @param {number} left Left bound of the frustum |
| 775 * @param {number} right Right bound of the frustum |
| 776 * @param {number} bottom Bottom bound of the frustum |
| 777 * @param {number} top Top bound of the frustum |
| 778 * @param {number} near Near bound of the frustum |
| 779 * @param {number} far Far bound of the frustum |
| 780 * @returns {mat4} out |
| 781 */ |
| 782 mat4.ortho = function (out, left, right, bottom, top, near, far) { |
| 783 var lr = 1 / (left - right), |
| 784 bt = 1 / (bottom - top), |
| 785 nf = 1 / (near - far); |
| 786 out[0] = -2 * lr; |
| 787 out[1] = 0; |
| 788 out[2] = 0; |
| 789 out[3] = 0; |
| 790 out[4] = 0; |
| 791 out[5] = -2 * bt; |
| 792 out[6] = 0; |
| 793 out[7] = 0; |
| 794 out[8] = 0; |
| 795 out[9] = 0; |
| 796 out[10] = 2 * nf; |
| 797 out[11] = 0; |
| 798 out[12] = (left + right) * lr; |
| 799 out[13] = (top + bottom) * bt; |
| 800 out[14] = (far + near) * nf; |
| 801 out[15] = 1; |
| 802 return out; |
| 803 }; |
| 804 |
| 805 /** |
| 806 * Generates a look-at matrix with the given eye position, focal point, and up a
xis |
| 807 * |
| 808 * @param {mat4} out mat4 frustum matrix will be written into |
| 809 * @param {vec3} eye Position of the viewer |
| 810 * @param {vec3} center Point the viewer is looking at |
| 811 * @param {vec3} up vec3 pointing up |
| 812 * @returns {mat4} out |
| 813 */ |
| 814 mat4.lookAt = function (out, eye, center, up) { |
| 815 var x0, x1, x2, y0, y1, y2, z0, z1, z2, len, |
| 816 eyex = eye[0], |
| 817 eyey = eye[1], |
| 818 eyez = eye[2], |
| 819 upx = up[0], |
| 820 upy = up[1], |
| 821 upz = up[2], |
| 822 centerx = center[0], |
| 823 centery = center[1], |
| 824 centerz = center[2]; |
| 825 |
| 826 if (Math.abs(eyex - centerx) < GLMAT_EPSILON && |
| 827 Math.abs(eyey - centery) < GLMAT_EPSILON && |
| 828 Math.abs(eyez - centerz) < GLMAT_EPSILON) { |
| 829 return mat4.identity(out); |
| 830 } |
| 831 |
| 832 z0 = eyex - centerx; |
| 833 z1 = eyey - centery; |
| 834 z2 = eyez - centerz; |
| 835 |
| 836 len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2); |
| 837 z0 *= len; |
| 838 z1 *= len; |
| 839 z2 *= len; |
| 840 |
| 841 x0 = upy * z2 - upz * z1; |
| 842 x1 = upz * z0 - upx * z2; |
| 843 x2 = upx * z1 - upy * z0; |
| 844 len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2); |
| 845 if (!len) { |
| 846 x0 = 0; |
| 847 x1 = 0; |
| 848 x2 = 0; |
| 849 } else { |
| 850 len = 1 / len; |
| 851 x0 *= len; |
| 852 x1 *= len; |
| 853 x2 *= len; |
| 854 } |
| 855 |
| 856 y0 = z1 * x2 - z2 * x1; |
| 857 y1 = z2 * x0 - z0 * x2; |
| 858 y2 = z0 * x1 - z1 * x0; |
| 859 |
| 860 len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2); |
| 861 if (!len) { |
| 862 y0 = 0; |
| 863 y1 = 0; |
| 864 y2 = 0; |
| 865 } else { |
| 866 len = 1 / len; |
| 867 y0 *= len; |
| 868 y1 *= len; |
| 869 y2 *= len; |
| 870 } |
| 871 |
| 872 out[0] = x0; |
| 873 out[1] = y0; |
| 874 out[2] = z0; |
| 875 out[3] = 0; |
| 876 out[4] = x1; |
| 877 out[5] = y1; |
| 878 out[6] = z1; |
| 879 out[7] = 0; |
| 880 out[8] = x2; |
| 881 out[9] = y2; |
| 882 out[10] = z2; |
| 883 out[11] = 0; |
| 884 out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez); |
| 885 out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez); |
| 886 out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez); |
| 887 out[15] = 1; |
| 888 |
| 889 return out; |
| 890 }; |
| 891 |
| 892 /** |
| 893 * Returns a string representation of a mat4 |
| 894 * |
| 895 * @param {mat4} mat matrix to represent as a string |
| 896 * @returns {String} string representation of the matrix |
| 897 */ |
| 898 mat4.str = function (a) { |
| 899 return 'mat4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + |
| 900 a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' + |
| 901 a[8] + ', ' + a[9] + ', ' + a[10] + ', ' + a[11] + ', ' + |
| 902 a[12] + ', ' + a[13] + ', ' + a[14] + ', ' + a[15] + ')'; |
| 903 }; |
| 904 |
| 905 if(typeof(exports) !== 'undefined') { |
| 906 exports.mat4 = mat4; |
| 907 } |
OLD | NEW |