| /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. |
| |
| Redistribution and use in source and binary forms, with or without modification, |
| are permitted provided that the following conditions are met: |
| |
| * Redistributions of source code must retain the above copyright notice, this |
| list of conditions and the following disclaimer. |
| * Redistributions in binary form must reproduce the above copyright notice, |
| this list of conditions and the following disclaimer in the documentation |
| and/or other materials provided with the distribution. |
| |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR |
| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
| ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ |
| |
| /** |
| * @class 3x3 Matrix |
| * @name mat3 |
| */ |
| var mat3 = {}; |
| |
| /** |
| * Creates a new identity mat3 |
| * |
| * @returns {mat3} a new 3x3 matrix |
| */ |
| mat3.create = function() { |
| var out = new GLMAT_ARRAY_TYPE(9); |
| out[0] = 1; |
| out[1] = 0; |
| out[2] = 0; |
| out[3] = 0; |
| out[4] = 1; |
| out[5] = 0; |
| out[6] = 0; |
| out[7] = 0; |
| out[8] = 1; |
| return out; |
| }; |
| |
| /** |
| * Copies the upper-left 3x3 values into the given mat3. |
| * |
| * @param {mat3} out the receiving 3x3 matrix |
| * @param {mat4} a the source 4x4 matrix |
| * @returns {mat3} out |
| */ |
| mat3.fromMat4 = function(out, a) { |
| out[0] = a[0]; |
| out[1] = a[1]; |
| out[2] = a[2]; |
| out[3] = a[4]; |
| out[4] = a[5]; |
| out[5] = a[6]; |
| out[6] = a[8]; |
| out[7] = a[9]; |
| out[8] = a[10]; |
| return out; |
| }; |
| |
| /** |
| * Creates a new mat3 initialized with values from an existing matrix |
| * |
| * @param {mat3} a matrix to clone |
| * @returns {mat3} a new 3x3 matrix |
| */ |
| mat3.clone = function(a) { |
| var out = new GLMAT_ARRAY_TYPE(9); |
| out[0] = a[0]; |
| out[1] = a[1]; |
| out[2] = a[2]; |
| out[3] = a[3]; |
| out[4] = a[4]; |
| out[5] = a[5]; |
| out[6] = a[6]; |
| out[7] = a[7]; |
| out[8] = a[8]; |
| return out; |
| }; |
| |
| /** |
| * Copy the values from one mat3 to another |
| * |
| * @param {mat3} out the receiving matrix |
| * @param {mat3} a the source matrix |
| * @returns {mat3} out |
| */ |
| mat3.copy = function(out, a) { |
| out[0] = a[0]; |
| out[1] = a[1]; |
| out[2] = a[2]; |
| out[3] = a[3]; |
| out[4] = a[4]; |
| out[5] = a[5]; |
| out[6] = a[6]; |
| out[7] = a[7]; |
| out[8] = a[8]; |
| return out; |
| }; |
| |
| /** |
| * Set a mat3 to the identity matrix |
| * |
| * @param {mat3} out the receiving matrix |
| * @returns {mat3} out |
| */ |
| mat3.identity = function(out) { |
| out[0] = 1; |
| out[1] = 0; |
| out[2] = 0; |
| out[3] = 0; |
| out[4] = 1; |
| out[5] = 0; |
| out[6] = 0; |
| out[7] = 0; |
| out[8] = 1; |
| return out; |
| }; |
| |
| /** |
| * Transpose the values of a mat3 |
| * |
| * @param {mat3} out the receiving matrix |
| * @param {mat3} a the source matrix |
| * @returns {mat3} out |
| */ |
| mat3.transpose = function(out, a) { |
| // If we are transposing ourselves we can skip a few steps but have to cache some values |
| if (out === a) { |
| var a01 = a[1], a02 = a[2], a12 = a[5]; |
| out[1] = a[3]; |
| out[2] = a[6]; |
| out[3] = a01; |
| out[5] = a[7]; |
| out[6] = a02; |
| out[7] = a12; |
| } else { |
| out[0] = a[0]; |
| out[1] = a[3]; |
| out[2] = a[6]; |
| out[3] = a[1]; |
| out[4] = a[4]; |
| out[5] = a[7]; |
| out[6] = a[2]; |
| out[7] = a[5]; |
| out[8] = a[8]; |
| } |
| |
| return out; |
| }; |
| |
| /** |
| * Inverts a mat3 |
| * |
| * @param {mat3} out the receiving matrix |
| * @param {mat3} a the source matrix |
| * @returns {mat3} out |
| */ |
| mat3.invert = function(out, a) { |
| var a00 = a[0], a01 = a[1], a02 = a[2], |
| a10 = a[3], a11 = a[4], a12 = a[5], |
| a20 = a[6], a21 = a[7], a22 = a[8], |
| |
| b01 = a22 * a11 - a12 * a21, |
| b11 = -a22 * a10 + a12 * a20, |
| b21 = a21 * a10 - a11 * a20, |
| |
| // Calculate the determinant |
| det = a00 * b01 + a01 * b11 + a02 * b21; |
| |
| if (!det) { |
| return null; |
| } |
| det = 1.0 / det; |
| |
| out[0] = b01 * det; |
| out[1] = (-a22 * a01 + a02 * a21) * det; |
| out[2] = (a12 * a01 - a02 * a11) * det; |
| out[3] = b11 * det; |
| out[4] = (a22 * a00 - a02 * a20) * det; |
| out[5] = (-a12 * a00 + a02 * a10) * det; |
| out[6] = b21 * det; |
| out[7] = (-a21 * a00 + a01 * a20) * det; |
| out[8] = (a11 * a00 - a01 * a10) * det; |
| return out; |
| }; |
| |
| /** |
| * Calculates the adjugate of a mat3 |
| * |
| * @param {mat3} out the receiving matrix |
| * @param {mat3} a the source matrix |
| * @returns {mat3} out |
| */ |
| mat3.adjoint = function(out, a) { |
| var a00 = a[0], a01 = a[1], a02 = a[2], |
| a10 = a[3], a11 = a[4], a12 = a[5], |
| a20 = a[6], a21 = a[7], a22 = a[8]; |
| |
| out[0] = (a11 * a22 - a12 * a21); |
| out[1] = (a02 * a21 - a01 * a22); |
| out[2] = (a01 * a12 - a02 * a11); |
| out[3] = (a12 * a20 - a10 * a22); |
| out[4] = (a00 * a22 - a02 * a20); |
| out[5] = (a02 * a10 - a00 * a12); |
| out[6] = (a10 * a21 - a11 * a20); |
| out[7] = (a01 * a20 - a00 * a21); |
| out[8] = (a00 * a11 - a01 * a10); |
| return out; |
| }; |
| |
| /** |
| * Calculates the determinant of a mat3 |
| * |
| * @param {mat3} a the source matrix |
| * @returns {Number} determinant of a |
| */ |
| mat3.determinant = function (a) { |
| var a00 = a[0], a01 = a[1], a02 = a[2], |
| a10 = a[3], a11 = a[4], a12 = a[5], |
| a20 = a[6], a21 = a[7], a22 = a[8]; |
| |
| return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20); |
| }; |
| |
| /** |
| * Multiplies two mat3's |
| * |
| * @param {mat3} out the receiving matrix |
| * @param {mat3} a the first operand |
| * @param {mat3} b the second operand |
| * @returns {mat3} out |
| */ |
| mat3.multiply = function (out, a, b) { |
| var a00 = a[0], a01 = a[1], a02 = a[2], |
| a10 = a[3], a11 = a[4], a12 = a[5], |
| a20 = a[6], a21 = a[7], a22 = a[8], |
| |
| b00 = b[0], b01 = b[1], b02 = b[2], |
| b10 = b[3], b11 = b[4], b12 = b[5], |
| b20 = b[6], b21 = b[7], b22 = b[8]; |
| |
| out[0] = b00 * a00 + b01 * a10 + b02 * a20; |
| out[1] = b00 * a01 + b01 * a11 + b02 * a21; |
| out[2] = b00 * a02 + b01 * a12 + b02 * a22; |
| |
| out[3] = b10 * a00 + b11 * a10 + b12 * a20; |
| out[4] = b10 * a01 + b11 * a11 + b12 * a21; |
| out[5] = b10 * a02 + b11 * a12 + b12 * a22; |
| |
| out[6] = b20 * a00 + b21 * a10 + b22 * a20; |
| out[7] = b20 * a01 + b21 * a11 + b22 * a21; |
| out[8] = b20 * a02 + b21 * a12 + b22 * a22; |
| return out; |
| }; |
| |
| /** |
| * Alias for {@link mat3.multiply} |
| * @function |
| */ |
| mat3.mul = mat3.multiply; |
| |
| /** |
| * Translate a mat3 by the given vector |
| * |
| * @param {mat3} out the receiving matrix |
| * @param {mat3} a the matrix to translate |
| * @param {vec2} v vector to translate by |
| * @returns {mat3} out |
| */ |
| mat3.translate = function(out, a, v) { |
| var a00 = a[0], a01 = a[1], a02 = a[2], |
| a10 = a[3], a11 = a[4], a12 = a[5], |
| a20 = a[6], a21 = a[7], a22 = a[8], |
| x = v[0], y = v[1]; |
| |
| out[0] = a00; |
| out[1] = a01; |
| out[2] = a02; |
| |
| out[3] = a10; |
| out[4] = a11; |
| out[5] = a12; |
| |
| out[6] = x * a00 + y * a10 + a20; |
| out[7] = x * a01 + y * a11 + a21; |
| out[8] = x * a02 + y * a12 + a22; |
| return out; |
| }; |
| |
| /** |
| * Rotates a mat3 by the given angle |
| * |
| * @param {mat3} out the receiving matrix |
| * @param {mat3} a the matrix to rotate |
| * @param {Number} rad the angle to rotate the matrix by |
| * @returns {mat3} out |
| */ |
| mat3.rotate = function (out, a, rad) { |
| var a00 = a[0], a01 = a[1], a02 = a[2], |
| a10 = a[3], a11 = a[4], a12 = a[5], |
| a20 = a[6], a21 = a[7], a22 = a[8], |
| |
| s = Math.sin(rad), |
| c = Math.cos(rad); |
| |
| out[0] = c * a00 + s * a10; |
| out[1] = c * a01 + s * a11; |
| out[2] = c * a02 + s * a12; |
| |
| out[3] = c * a10 - s * a00; |
| out[4] = c * a11 - s * a01; |
| out[5] = c * a12 - s * a02; |
| |
| out[6] = a20; |
| out[7] = a21; |
| out[8] = a22; |
| return out; |
| }; |
| |
| /** |
| * Scales the mat3 by the dimensions in the given vec2 |
| * |
| * @param {mat3} out the receiving matrix |
| * @param {mat3} a the matrix to rotate |
| * @param {vec2} v the vec2 to scale the matrix by |
| * @returns {mat3} out |
| **/ |
| mat3.scale = function(out, a, v) { |
| var x = v[0], y = v[2]; |
| |
| out[0] = x * a[0]; |
| out[1] = x * a[1]; |
| out[2] = x * a[2]; |
| |
| out[3] = y * a[3]; |
| out[4] = y * a[4]; |
| out[5] = y * a[5]; |
| |
| out[6] = a[6]; |
| out[7] = a[7]; |
| out[8] = a[8]; |
| return out; |
| }; |
| |
| /** |
| * Copies the values from a mat2d into a mat3 |
| * |
| * @param {mat3} out the receiving matrix |
| * @param {mat3} a the matrix to rotate |
| * @param {vec2} v the vec2 to scale the matrix by |
| * @returns {mat3} out |
| **/ |
| mat3.fromMat2d = function(out, a) { |
| out[0] = a[0]; |
| out[1] = a[1]; |
| out[2] = 0; |
| |
| out[3] = a[2]; |
| out[4] = a[3]; |
| out[5] = 0; |
| |
| out[6] = a[4]; |
| out[7] = a[5]; |
| out[8] = 1; |
| return out; |
| }; |
| |
| /** |
| * Calculates a 3x3 matrix from the given quaternion |
| * |
| * @param {mat3} out mat3 receiving operation result |
| * @param {quat} q Quaternion to create matrix from |
| * |
| * @returns {mat3} out |
| */ |
| mat3.fromQuat = function (out, q) { |
| var x = q[0], y = q[1], z = q[2], w = q[3], |
| x2 = x + x, |
| y2 = y + y, |
| z2 = z + z, |
| |
| xx = x * x2, |
| xy = x * y2, |
| xz = x * z2, |
| yy = y * y2, |
| yz = y * z2, |
| zz = z * z2, |
| wx = w * x2, |
| wy = w * y2, |
| wz = w * z2; |
| |
| out[0] = 1 - (yy + zz); |
| out[1] = xy + wz; |
| out[2] = xz - wy; |
| |
| out[3] = xy - wz; |
| out[4] = 1 - (xx + zz); |
| out[5] = yz + wx; |
| |
| out[6] = xz + wy; |
| out[7] = yz - wx; |
| out[8] = 1 - (xx + yy); |
| |
| return out; |
| }; |
| |
| /** |
| * Returns a string representation of a mat3 |
| * |
| * @param {mat3} mat matrix to represent as a string |
| * @returns {String} string representation of the matrix |
| */ |
| mat3.str = function (a) { |
| return 'mat3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + |
| a[3] + ', ' + a[4] + ', ' + a[5] + ', ' + |
| a[6] + ', ' + a[7] + ', ' + a[8] + ')'; |
| }; |
| |
| if(typeof(exports) !== 'undefined') { |
| exports.mat3 = mat3; |
| } |