1e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang/* 2e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * Copyright (C) 2009 Apple Inc. All Rights Reserved. 3e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * 4e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * Redistribution and use in source and binary forms, with or without 5e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * modification, are permitted provided that the following conditions 6e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * are met: 7e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * 1. Redistributions of source code must retain the above copyright 8e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * notice, this list of conditions and the following disclaimer. 9e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * 2. Redistributions in binary form must reproduce the above copyright 10e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * notice, this list of conditions and the following disclaimer in the 11e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * documentation and/or other materials provided with the distribution. 12e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * 13e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang */ 25e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 26e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // J3DI (Jedi) - A support library for WebGL. 27e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 28e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang/* 29e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DI Math Classes. Currently includes: 30e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 31e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4 - A 4x4 Matrix 32e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang*/ 33e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 34e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang/* 35e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4 class 36e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 37e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang This class implements a 4x4 matrix. It has functions which duplicate the 38e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang functionality of the OpenGL matrix stack and glut functions. On browsers 39e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang that support it, CSSMatrix is used to accelerate operations. 40e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 41e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang IDL: 42e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 43e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang [ 44e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang Constructor(in J3DIMatrix4 matrix), // copy passed matrix into new J3DIMatrix4 45e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang Constructor(in sequence<float> array) // create new J3DIMatrix4 with 16 floats (row major) 46e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang Constructor() // create new J3DIMatrix4 with identity matrix 47e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang ] 48e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang interface J3DIMatrix4 { 49e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void load(in J3DIMatrix4 matrix); // copy the values from the passed matrix 50e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void load(in sequence<float> array); // copy 16 floats into the matrix 51e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang sequence<float> getAsArray(); // return the matrix as an array of 16 floats 52e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang Float32Array getAsFloat32Array(); // return the matrix as a Float32Array with 16 values 53e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void setUniform(in WebGLRenderingContext ctx, // Send the matrix to the passed uniform location in the passed context 54e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang in WebGLUniformLocation loc, 55e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang in boolean transpose); 56e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void makeIdentity(); // replace the matrix with identity 57e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void transpose(); // replace the matrix with its transpose 58e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void invert(); // replace the matrix with its inverse 59e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 60e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void translate(in float x, in float y, in float z); // multiply the matrix by passed translation values on the right 61e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void translate(in J3DVector3 v); // multiply the matrix by passed translation values on the right 62e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void scale(in float x, in float y, in float z); // multiply the matrix by passed scale values on the right 63e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void scale(in J3DVector3 v); // multiply the matrix by passed scale values on the right 64e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void rotate(in float angle, // multiply the matrix by passed rotation values on the right 65e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang in float x, in float y, in float z); // (angle is in degrees) 66e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void rotate(in float angle, in J3DVector3 v); // multiply the matrix by passed rotation values on the right 67e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // (angle is in degrees) 68e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void multiply(in CanvasMatrix matrix); // multiply the matrix by the passed matrix on the right 69e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void divide(in float divisor); // divide the matrix by the passed divisor 70e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void ortho(in float left, in float right, // multiply the matrix by the passed ortho values on the right 71e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang in float bottom, in float top, 72e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang in float near, in float far); 73e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void frustum(in float left, in float right, // multiply the matrix by the passed frustum values on the right 74e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang in float bottom, in float top, 75e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang in float near, in float far); 76e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void perspective(in float fovy, in float aspect, // multiply the matrix by the passed perspective values on the right 77e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang in float zNear, in float zFar); 78e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void lookat(in J3DVector3 eye, // multiply the matrix by the passed lookat 79e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang in J3DVector3 center, in J3DVector3 up); // values on the right 80e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang bool decompose(in J3DVector3 translate, // decompose the matrix into the passed vector 81e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang in J3DVector3 rotate, 82e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang in J3DVector3 scale, 83e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang in J3DVector3 skew, 84e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang in sequence<float> perspective); 85e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 86e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 87e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang [ 88e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang Constructor(in J3DVector3 vector), // copy passed vector into new J3DVector3 89e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang Constructor(in sequence<float> array) // create new J3DVector3 with 3 floats from array 90e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang Constructor(in float x, in float y, in float z) // create new J3DVector3 with 3 floats 91e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang Constructor() // create new J3DVector3 with (0,0,0) 92e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang ] 93e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang interface J3DVector3 { 94e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void load(in J3DVector3 vector); // copy the values from the passed vector 95e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void load(in sequence<float> array); // copy 3 floats into the vector from array 96e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void load(in float x, in float y, in float z); // copy 3 floats into the vector 97e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang sequence<float> getAsArray(); // return the vector as an array of 3 floats 98e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang Float32Array getAsFloat32Array(); // return the matrix as a Float32Array with 16 values 99e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void multMatrix(in J3DIMatrix4 matrix); // multiply the vector by the passed matrix (on the right) 100e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang float vectorLength(); // return the length of the vector 101e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang float dot(); // return the dot product of the vector 102e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void cross(in J3DVector3 v); // replace the vector with vector x v 103e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang void divide(in float divisor); // divide the vector by the passed divisor 104e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 105e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang*/ 106e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 107e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIHasCSSMatrix = false; 108e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIHasCSSMatrixCopy = false; 109e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang/* 110e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liangif ("WebKitCSSMatrix" in window && ("media" in window && window.media.matchMedium("(-webkit-transform-3d)")) || 111e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang ("styleMedia" in window && window.styleMedia.matchMedium("(-webkit-transform-3d)"))) { 112e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIHasCSSMatrix = true; 113e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if ("copy" in WebKitCSSMatrix.prototype) 114e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIHasCSSMatrixCopy = true; 115e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 116e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang*/ 117e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 118e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang// console.log("J3DIHasCSSMatrix="+J3DIHasCSSMatrix); 119e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang// console.log("J3DIHasCSSMatrixCopy="+J3DIHasCSSMatrixCopy); 120e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 121e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang// 122e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang// J3DIMatrix4 123e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang// 124e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4 = function(m) 125e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 126e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (J3DIHasCSSMatrix) 127e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix = new WebKitCSSMatrix; 128e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang else 129e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix = new Object; 130e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 131e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (typeof m == 'object') { 132e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if ("length" in m && m.length >= 16) { 133e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.load(m); 134e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return; 135e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 136e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang else if (m instanceof J3DIMatrix4) { 137e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.load(m); 138e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return; 139e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 140e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 141e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.makeIdentity(); 142e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 143e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 144e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype.load = function() 145e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 146e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (arguments.length == 1 && typeof arguments[0] == 'object') { 147e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var matrix; 148e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 149e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (arguments[0] instanceof J3DIMatrix4) { 150e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix = arguments[0].$matrix; 151e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 152e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m11 = matrix.m11; 153e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m12 = matrix.m12; 154e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m13 = matrix.m13; 155e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m14 = matrix.m14; 156e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 157e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m21 = matrix.m21; 158e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m22 = matrix.m22; 159e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m23 = matrix.m23; 160e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m24 = matrix.m24; 161e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 162e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m31 = matrix.m31; 163e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m32 = matrix.m32; 164e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m33 = matrix.m33; 165e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m34 = matrix.m34; 166e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 167e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m41 = matrix.m41; 168e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m42 = matrix.m42; 169e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m43 = matrix.m43; 170e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m44 = matrix.m44; 171e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return; 172e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 173e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang else 174e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix = arguments[0]; 175e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 176e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if ("length" in matrix && matrix.length >= 16) { 177e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m11 = matrix[0]; 178e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m12 = matrix[1]; 179e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m13 = matrix[2]; 180e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m14 = matrix[3]; 181e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 182e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m21 = matrix[4]; 183e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m22 = matrix[5]; 184e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m23 = matrix[6]; 185e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m24 = matrix[7]; 186e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 187e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m31 = matrix[8]; 188e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m32 = matrix[9]; 189e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m33 = matrix[10]; 190e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m34 = matrix[11]; 191e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 192e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m41 = matrix[12]; 193e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m42 = matrix[13]; 194e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m43 = matrix[14]; 195e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m44 = matrix[15]; 196e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return; 197e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 198e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 199e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 200e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.makeIdentity(); 201e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 202e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 203e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype.getAsArray = function() 204e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 205e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return [ 206e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m11, this.$matrix.m12, this.$matrix.m13, this.$matrix.m14, 207e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m21, this.$matrix.m22, this.$matrix.m23, this.$matrix.m24, 208e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m31, this.$matrix.m32, this.$matrix.m33, this.$matrix.m34, 209e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m41, this.$matrix.m42, this.$matrix.m43, this.$matrix.m44 210e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang ]; 211e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 212e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 213e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype.getAsFloat32Array = function() 214e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 215e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (J3DIHasCSSMatrixCopy) { 216e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var array = new Float32Array(16); 217e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.copy(array); 218e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return array; 219e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 220e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return new Float32Array(this.getAsArray()); 221e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 222e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 223e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype.setUniform = function(ctx, loc, transpose) 224e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 225e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (J3DIMatrix4.setUniformArray == undefined) { 226e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformWebGLArray = new Float32Array(16); 227e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformArray = new Array(16); 228e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 229e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 230e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (J3DIHasCSSMatrixCopy) 231e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.copy(J3DIMatrix4.setUniformWebGLArray); 232e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang else { 233e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformArray[0] = this.$matrix.m11; 234e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformArray[1] = this.$matrix.m12; 235e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformArray[2] = this.$matrix.m13; 236e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformArray[3] = this.$matrix.m14; 237e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformArray[4] = this.$matrix.m21; 238e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformArray[5] = this.$matrix.m22; 239e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformArray[6] = this.$matrix.m23; 240e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformArray[7] = this.$matrix.m24; 241e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformArray[8] = this.$matrix.m31; 242e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformArray[9] = this.$matrix.m32; 243e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformArray[10] = this.$matrix.m33; 244e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformArray[11] = this.$matrix.m34; 245e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformArray[12] = this.$matrix.m41; 246e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformArray[13] = this.$matrix.m42; 247e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformArray[14] = this.$matrix.m43; 248e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformArray[15] = this.$matrix.m44; 249e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 250e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang J3DIMatrix4.setUniformWebGLArray.set(J3DIMatrix4.setUniformArray); 251e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 252e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 253e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang ctx.uniformMatrix4fv(loc, transpose, J3DIMatrix4.setUniformWebGLArray); 254e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 255e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 256e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype.makeIdentity = function() 257e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 258e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m11 = 1; 259e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m12 = 0; 260e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m13 = 0; 261e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m14 = 0; 262e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 263e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m21 = 0; 264e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m22 = 1; 265e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m23 = 0; 266e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m24 = 0; 267e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 268e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m31 = 0; 269e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m32 = 0; 270e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m33 = 1; 271e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m34 = 0; 272e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 273e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m41 = 0; 274e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m42 = 0; 275e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m43 = 0; 276e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m44 = 1; 277e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 278e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 279e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype.transpose = function() 280e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 281e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var tmp = this.$matrix.m12; 282e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m12 = this.$matrix.m21; 283e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m21 = tmp; 284e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 285e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang tmp = this.$matrix.m13; 286e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m13 = this.$matrix.m31; 287e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m31 = tmp; 288e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 289e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang tmp = this.$matrix.m14; 290e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m14 = this.$matrix.m41; 291e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m41 = tmp; 292e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 293e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang tmp = this.$matrix.m23; 294e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m23 = this.$matrix.m32; 295e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m32 = tmp; 296e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 297e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang tmp = this.$matrix.m24; 298e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m24 = this.$matrix.m42; 299e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m42 = tmp; 300e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 301e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang tmp = this.$matrix.m34; 302e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m34 = this.$matrix.m43; 303e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m43 = tmp; 304e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 305e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 306e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype.invert = function() 307e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 308e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (J3DIHasCSSMatrix) { 309e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix = this.$matrix.inverse(); 310e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return; 311e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 312e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 313e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Calculate the 4x4 determinant 314e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // If the determinant is zero, 315e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // then the inverse matrix is not unique. 316e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var det = this._determinant4x4(); 317e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 318e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (Math.abs(det) < 1e-8) 319e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return null; 320e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 321e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this._makeAdjoint(); 322e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 323e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Scale the adjoint matrix to get the inverse 324e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m11 /= det; 325e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m12 /= det; 326e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m13 /= det; 327e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m14 /= det; 328e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 329e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m21 /= det; 330e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m22 /= det; 331e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m23 /= det; 332e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m24 /= det; 333e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 334e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m31 /= det; 335e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m32 /= det; 336e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m33 /= det; 337e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m34 /= det; 338e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 339e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m41 /= det; 340e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m42 /= det; 341e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m43 /= det; 342e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m44 /= det; 343e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 344e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 345e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype.translate = function(x,y,z) 346e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 347e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (typeof x == 'object' && "length" in x) { 348e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var t = x; 349e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang x = t[0]; 350e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang y = t[1]; 351e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang z = t[2]; 352e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 353e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang else { 354e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (x == undefined) 355e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang x = 0; 356e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (y == undefined) 357e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang y = 0; 358e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (z == undefined) 359e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang z = 0; 360e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 361e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 362e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (J3DIHasCSSMatrix) { 363e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix = this.$matrix.translate(x, y, z); 364e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return; 365e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 366e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 367e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var matrix = new J3DIMatrix4(); 368e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m41 = x; 369e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m42 = y; 370e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m43 = z; 371e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 372e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.multiply(matrix); 373e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 374e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 375e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype.scale = function(x,y,z) 376e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 377e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (typeof x == 'object' && "length" in x) { 378e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var t = x; 379e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang x = t[0]; 380e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang y = t[1]; 381e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang z = t[2]; 382e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 383e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang else { 384e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (x == undefined) 385e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang x = 1; 386e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (z == undefined) { 387e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (y == undefined) { 388e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang y = x; 389e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang z = x; 390e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 391e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang else 392e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang z = 1; 393e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 394e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang else if (y == undefined) 395e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang y = x; 396e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 397e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 398e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (J3DIHasCSSMatrix) { 399e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix = this.$matrix.scale(x, y, z); 400e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return; 401e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 402e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 403e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var matrix = new J3DIMatrix4(); 404e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m11 = x; 405e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m22 = y; 406e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m33 = z; 407e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 408e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.multiply(matrix); 409e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 410e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 411e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype.rotate = function(angle,x,y,z) 412e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 413e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Forms are (angle, x,y,z), (angle,vector), (angleX, angleY, angleZ), (angle) 414e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (typeof x == 'object' && "length" in x) { 415e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var t = x; 416e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang x = t[0]; 417e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang y = t[1]; 418e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang z = t[2]; 419e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 420e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang else { 421e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (arguments.length == 1) { 422e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang x = 0; 423e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang y = 0; 424e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang z = 1; 425e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 426e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang else if (arguments.length == 3) { 427e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.rotate(angle, 1,0,0); // about X axis 428e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.rotate(x, 0,1,0); // about Y axis 429e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.rotate(y, 0,0,1); // about Z axis 430e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return; 431e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 432e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 433e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 434e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (J3DIHasCSSMatrix) { 435e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix = this.$matrix.rotateAxisAngle(x, y, z, angle); 436e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return; 437e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 438e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 439e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // angles are in degrees. Switch to radians 440e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang angle = angle / 180 * Math.PI; 441e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 442e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang angle /= 2; 443e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var sinA = Math.sin(angle); 444e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var cosA = Math.cos(angle); 445e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var sinA2 = sinA * sinA; 446e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 447e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // normalize 448e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var len = Math.sqrt(x * x + y * y + z * z); 449e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (len == 0) { 450e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // bad vector, just use something reasonable 451e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang x = 0; 452e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang y = 0; 453e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang z = 1; 454e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } else if (len != 1) { 455e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang x /= len; 456e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang y /= len; 457e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang z /= len; 458e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 459e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 460e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var mat = new J3DIMatrix4(); 461e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 462e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // optimize case where axis is along major axis 463e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (x == 1 && y == 0 && z == 0) { 464e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m11 = 1; 465e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m12 = 0; 466e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m13 = 0; 467e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m21 = 0; 468e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m22 = 1 - 2 * sinA2; 469e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m23 = 2 * sinA * cosA; 470e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m31 = 0; 471e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m32 = -2 * sinA * cosA; 472e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m33 = 1 - 2 * sinA2; 473e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m14 = mat.$matrix.m24 = mat.$matrix.m34 = 0; 474e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m41 = mat.$matrix.m42 = mat.$matrix.m43 = 0; 475e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m44 = 1; 476e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } else if (x == 0 && y == 1 && z == 0) { 477e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m11 = 1 - 2 * sinA2; 478e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m12 = 0; 479e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m13 = -2 * sinA * cosA; 480e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m21 = 0; 481e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m22 = 1; 482e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m23 = 0; 483e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m31 = 2 * sinA * cosA; 484e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m32 = 0; 485e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m33 = 1 - 2 * sinA2; 486e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m14 = mat.$matrix.m24 = mat.$matrix.m34 = 0; 487e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m41 = mat.$matrix.m42 = mat.$matrix.m43 = 0; 488e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m44 = 1; 489e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } else if (x == 0 && y == 0 && z == 1) { 490e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m11 = 1 - 2 * sinA2; 491e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m12 = 2 * sinA * cosA; 492e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m13 = 0; 493e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m21 = -2 * sinA * cosA; 494e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m22 = 1 - 2 * sinA2; 495e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m23 = 0; 496e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m31 = 0; 497e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m32 = 0; 498e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m33 = 1; 499e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m14 = mat.$matrix.m24 = mat.$matrix.m34 = 0; 500e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m41 = mat.$matrix.m42 = mat.$matrix.m43 = 0; 501e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m44 = 1; 502e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } else { 503e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var x2 = x*x; 504e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var y2 = y*y; 505e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var z2 = z*z; 506e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 507e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m11 = 1 - 2 * (y2 + z2) * sinA2; 508e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m12 = 2 * (x * y * sinA2 + z * sinA * cosA); 509e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m13 = 2 * (x * z * sinA2 - y * sinA * cosA); 510e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m21 = 2 * (y * x * sinA2 - z * sinA * cosA); 511e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m22 = 1 - 2 * (z2 + x2) * sinA2; 512e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m23 = 2 * (y * z * sinA2 + x * sinA * cosA); 513e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m31 = 2 * (z * x * sinA2 + y * sinA * cosA); 514e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m32 = 2 * (z * y * sinA2 - x * sinA * cosA); 515e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m33 = 1 - 2 * (x2 + y2) * sinA2; 516e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m14 = mat.$matrix.m24 = mat.$matrix.m34 = 0; 517e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m41 = mat.$matrix.m42 = mat.$matrix.m43 = 0; 518e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mat.$matrix.m44 = 1; 519e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 520e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.multiply(mat); 521e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 522e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 523e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype.multiply = function(mat) 524e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 525e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (J3DIHasCSSMatrix) { 526e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix = this.$matrix.multiply(mat.$matrix); 527e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return; 528e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 529e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 530e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var m11 = (mat.$matrix.m11 * this.$matrix.m11 + mat.$matrix.m12 * this.$matrix.m21 531e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + mat.$matrix.m13 * this.$matrix.m31 + mat.$matrix.m14 * this.$matrix.m41); 532e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var m12 = (mat.$matrix.m11 * this.$matrix.m12 + mat.$matrix.m12 * this.$matrix.m22 533e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + mat.$matrix.m13 * this.$matrix.m32 + mat.$matrix.m14 * this.$matrix.m42); 534e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var m13 = (mat.$matrix.m11 * this.$matrix.m13 + mat.$matrix.m12 * this.$matrix.m23 535e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + mat.$matrix.m13 * this.$matrix.m33 + mat.$matrix.m14 * this.$matrix.m43); 536e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var m14 = (mat.$matrix.m11 * this.$matrix.m14 + mat.$matrix.m12 * this.$matrix.m24 537e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + mat.$matrix.m13 * this.$matrix.m34 + mat.$matrix.m14 * this.$matrix.m44); 538e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 539e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var m21 = (mat.$matrix.m21 * this.$matrix.m11 + mat.$matrix.m22 * this.$matrix.m21 540e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + mat.$matrix.m23 * this.$matrix.m31 + mat.$matrix.m24 * this.$matrix.m41); 541e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var m22 = (mat.$matrix.m21 * this.$matrix.m12 + mat.$matrix.m22 * this.$matrix.m22 542e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + mat.$matrix.m23 * this.$matrix.m32 + mat.$matrix.m24 * this.$matrix.m42); 543e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var m23 = (mat.$matrix.m21 * this.$matrix.m13 + mat.$matrix.m22 * this.$matrix.m23 544e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + mat.$matrix.m23 * this.$matrix.m33 + mat.$matrix.m24 * this.$matrix.m43); 545e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var m24 = (mat.$matrix.m21 * this.$matrix.m14 + mat.$matrix.m22 * this.$matrix.m24 546e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + mat.$matrix.m23 * this.$matrix.m34 + mat.$matrix.m24 * this.$matrix.m44); 547e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 548e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var m31 = (mat.$matrix.m31 * this.$matrix.m11 + mat.$matrix.m32 * this.$matrix.m21 549e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + mat.$matrix.m33 * this.$matrix.m31 + mat.$matrix.m34 * this.$matrix.m41); 550e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var m32 = (mat.$matrix.m31 * this.$matrix.m12 + mat.$matrix.m32 * this.$matrix.m22 551e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + mat.$matrix.m33 * this.$matrix.m32 + mat.$matrix.m34 * this.$matrix.m42); 552e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var m33 = (mat.$matrix.m31 * this.$matrix.m13 + mat.$matrix.m32 * this.$matrix.m23 553e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + mat.$matrix.m33 * this.$matrix.m33 + mat.$matrix.m34 * this.$matrix.m43); 554e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var m34 = (mat.$matrix.m31 * this.$matrix.m14 + mat.$matrix.m32 * this.$matrix.m24 555e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + mat.$matrix.m33 * this.$matrix.m34 + mat.$matrix.m34 * this.$matrix.m44); 556e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 557e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var m41 = (mat.$matrix.m41 * this.$matrix.m11 + mat.$matrix.m42 * this.$matrix.m21 558e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + mat.$matrix.m43 * this.$matrix.m31 + mat.$matrix.m44 * this.$matrix.m41); 559e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var m42 = (mat.$matrix.m41 * this.$matrix.m12 + mat.$matrix.m42 * this.$matrix.m22 560e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + mat.$matrix.m43 * this.$matrix.m32 + mat.$matrix.m44 * this.$matrix.m42); 561e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var m43 = (mat.$matrix.m41 * this.$matrix.m13 + mat.$matrix.m42 * this.$matrix.m23 562e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + mat.$matrix.m43 * this.$matrix.m33 + mat.$matrix.m44 * this.$matrix.m43); 563e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var m44 = (mat.$matrix.m41 * this.$matrix.m14 + mat.$matrix.m42 * this.$matrix.m24 564e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + mat.$matrix.m43 * this.$matrix.m34 + mat.$matrix.m44 * this.$matrix.m44); 565e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 566e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m11 = m11; 567e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m12 = m12; 568e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m13 = m13; 569e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m14 = m14; 570e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 571e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m21 = m21; 572e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m22 = m22; 573e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m23 = m23; 574e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m24 = m24; 575e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 576e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m31 = m31; 577e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m32 = m32; 578e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m33 = m33; 579e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m34 = m34; 580e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 581e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m41 = m41; 582e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m42 = m42; 583e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m43 = m43; 584e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m44 = m44; 585e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 586e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 587e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype.divide = function(divisor) 588e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 589e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m11 /= divisor; 590e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m12 /= divisor; 591e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m13 /= divisor; 592e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m14 /= divisor; 593e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 594e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m21 /= divisor; 595e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m22 /= divisor; 596e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m23 /= divisor; 597e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m24 /= divisor; 598e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 599e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m31 /= divisor; 600e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m32 /= divisor; 601e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m33 /= divisor; 602e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m34 /= divisor; 603e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 604e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m41 /= divisor; 605e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m42 /= divisor; 606e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m43 /= divisor; 607e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m44 /= divisor; 608e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 609e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 610e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 611e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype.ortho = function(left, right, bottom, top, near, far) 612e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 613e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var tx = (left + right) / (left - right); 614e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var ty = (top + bottom) / (top - bottom); 615e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var tz = (far + near) / (far - near); 616e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 617e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var matrix = new J3DIMatrix4(); 618e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m11 = 2 / (left - right); 619e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m12 = 0; 620e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m13 = 0; 621e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m14 = 0; 622e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m21 = 0; 623e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m22 = 2 / (top - bottom); 624e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m23 = 0; 625e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m24 = 0; 626e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m31 = 0; 627e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m32 = 0; 628e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m33 = -2 / (far - near); 629e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m34 = 0; 630e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m41 = tx; 631e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m42 = ty; 632e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m43 = tz; 633e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m44 = 1; 634e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 635e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.multiply(matrix); 636e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 637e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 638e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype.frustum = function(left, right, bottom, top, near, far) 639e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 640e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var matrix = new J3DIMatrix4(); 641e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var A = (right + left) / (right - left); 642e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var B = (top + bottom) / (top - bottom); 643e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var C = -(far + near) / (far - near); 644e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var D = -(2 * far * near) / (far - near); 645e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 646e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m11 = (2 * near) / (right - left); 647e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m12 = 0; 648e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m13 = 0; 649e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m14 = 0; 650e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 651e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m21 = 0; 652e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m22 = 2 * near / (top - bottom); 653e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m23 = 0; 654e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m24 = 0; 655e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 656e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m31 = A; 657e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m32 = B; 658e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m33 = C; 659e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m34 = -1; 660e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 661e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m41 = 0; 662e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m42 = 0; 663e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m43 = D; 664e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m44 = 0; 665e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 666e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.multiply(matrix); 667e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 668e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 669e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype.perspective = function(fovy, aspect, zNear, zFar) 670e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 671e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var top = Math.tan(fovy * Math.PI / 360) * zNear; 672e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var bottom = -top; 673e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var left = aspect * bottom; 674e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var right = aspect * top; 675e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.frustum(left, right, bottom, top, zNear, zFar); 676e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 677e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 678e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype.lookat = function(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz) 679e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 680e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (typeof eyez == 'object' && "length" in eyez) { 681e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var t = eyez; 682e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang upx = t[0]; 683e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang upy = t[1]; 684e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang upz = t[2]; 685e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 686e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang t = eyey; 687e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang centerx = t[0]; 688e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang centery = t[1]; 689e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang centerz = t[2]; 690e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 691e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang t = eyex; 692e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang eyex = t[0]; 693e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang eyey = t[1]; 694e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang eyez = t[2]; 695e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 696e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 697e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var matrix = new J3DIMatrix4(); 698e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 699e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Make rotation matrix 700e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 701e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Z vector 702e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var zx = eyex - centerx; 703e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var zy = eyey - centery; 704e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var zz = eyez - centerz; 705e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var mag = Math.sqrt(zx * zx + zy * zy + zz * zz); 706e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (mag) { 707e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang zx /= mag; 708e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang zy /= mag; 709e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang zz /= mag; 710e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 711e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 712e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Y vector 713e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var yx = upx; 714e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var yy = upy; 715e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var yz = upz; 716e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 717e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // X vector = Y cross Z 718e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang xx = yy * zz - yz * zy; 719e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang xy = -yx * zz + yz * zx; 720e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang xz = yx * zy - yy * zx; 721e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 722e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Recompute Y = Z cross X 723e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang yx = zy * xz - zz * xy; 724e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang yy = -zx * xz + zz * xx; 725e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang yx = zx * xy - zy * xx; 726e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 727e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // cross product gives area of parallelogram, which is < 1.0 for 728e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // non-perpendicular unit-length vectors; so normalize x, y here 729e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 730e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mag = Math.sqrt(xx * xx + xy * xy + xz * xz); 731e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (mag) { 732e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang xx /= mag; 733e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang xy /= mag; 734e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang xz /= mag; 735e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 736e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 737e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang mag = Math.sqrt(yx * yx + yy * yy + yz * yz); 738e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (mag) { 739e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang yx /= mag; 740e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang yy /= mag; 741e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang yz /= mag; 742e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 743e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 744e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m11 = xx; 745e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m12 = xy; 746e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m13 = xz; 747e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m14 = 0; 748e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 749e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m21 = yx; 750e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m22 = yy; 751e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m23 = yz; 752e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m24 = 0; 753e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 754e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m31 = zx; 755e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m32 = zy; 756e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m33 = zz; 757e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m34 = 0; 758e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 759e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m41 = 0; 760e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m42 = 0; 761e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m43 = 0; 762e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m44 = 1; 763e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.translate(-eyex, -eyey, -eyez); 764e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 765e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.multiply(matrix); 766e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 767e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 768e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang// Returns true on success, false otherwise. All params are Array objects 769e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype.decompose = function(_translate, _rotate, _scale, _skew, _perspective) 770e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 771e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Normalize the matrix. 772e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (this.$matrix.m44 == 0) 773e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return false; 774e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 775e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Gather the params 776e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var translate, rotate, scale, skew, perspective; 777e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 778e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var translate = (_translate == undefined || !("length" in _translate)) ? new J3DIVector3 : _translate; 779e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var rotate = (_rotate == undefined || !("length" in _rotate)) ? new J3DIVector3 : _rotate; 780e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var scale = (_scale == undefined || !("length" in _scale)) ? new J3DIVector3 : _scale; 781e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var skew = (_skew == undefined || !("length" in _skew)) ? new J3DIVector3 : _skew; 782e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var perspective = (_perspective == undefined || !("length" in _perspective)) ? new Array(4) : _perspective; 783e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 784e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var matrix = new J3DIMatrix4(this); 785e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 786e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.divide(matrix.$matrix.m44); 787e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 788e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // perspectiveMatrix is used to solve for perspective, but it also provides 789e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // an easy way to test for singularity of the upper 3x3 component. 790e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var perspectiveMatrix = new J3DIMatrix4(matrix); 791e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 792e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang perspectiveMatrix.$matrix.m14 = 0; 793e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang perspectiveMatrix.$matrix.m24 = 0; 794e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang perspectiveMatrix.$matrix.m34 = 0; 795e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang perspectiveMatrix.$matrix.m44 = 1; 796e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 797e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (perspectiveMatrix._determinant4x4() == 0) 798e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return false; 799e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 800e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // First, isolate perspective. 801e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (matrix.$matrix.m14 != 0 || matrix.$matrix.m24 != 0 || matrix.$matrix.m34 != 0) { 802e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // rightHandSide is the right hand side of the equation. 803e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var rightHandSide = [ matrix.$matrix.m14, matrix.$matrix.m24, matrix.$matrix.m34, matrix.$matrix.m44 ]; 804e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 805e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Solve the equation by inverting perspectiveMatrix and multiplying 806e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // rightHandSide by the inverse. 807e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var inversePerspectiveMatrix = new J3DIMatrix4(perspectiveMatrix); 808e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang inversePerspectiveMatrix.invert(); 809e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var transposedInversePerspectiveMatrix = new J3DIMatrix4(inversePerspectiveMatrix); 810e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang transposedInversePerspectiveMatrix.transpose(); 811e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang transposedInversePerspectiveMatrix.multVecMatrix(perspective, rightHandSide); 812e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 813e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Clear the perspective partition 814e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m14 = matrix.$matrix.m24 = matrix.$matrix.m34 = 0 815e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m44 = 1; 816e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 817e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang else { 818e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // No perspective. 819e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang perspective[0] = perspective[1] = perspective[2] = 0; 820e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang perspective[3] = 1; 821e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 822e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 823e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Next take care of translation 824e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang translate[0] = matrix.$matrix.m41 825e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m41 = 0 826e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang translate[1] = matrix.$matrix.m42 827e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m42 = 0 828e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang translate[2] = matrix.$matrix.m43 829e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang matrix.$matrix.m43 = 0 830e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 831e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Now get scale and shear. 'row' is a 3 element array of 3 component vectors 832e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var row0 = new J3DIVector3(matrix.$matrix.m11, matrix.$matrix.m12, matrix.$matrix.m13); 833e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var row1 = new J3DIVector3(matrix.$matrix.m21, matrix.$matrix.m22, matrix.$matrix.m23); 834e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var row2 = new J3DIVector3(matrix.$matrix.m31, matrix.$matrix.m32, matrix.$matrix.m33); 835e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 836e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Compute X scale factor and normalize first row. 837e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang scale[0] = row0.vectorLength(); 838e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang row0.divide(scale[0]); 839e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 840e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Compute XY shear factor and make 2nd row orthogonal to 1st. 841e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang skew[0] = row0.dot(row1); 842e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang row1.combine(row0, 1.0, -skew[0]); 843e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 844e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Now, compute Y scale and normalize 2nd row. 845e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang scale[1] = row1.vectorLength(); 846e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang row1.divide(scale[1]); 847e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang skew[0] /= scale[1]; 848e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 849e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Compute XZ and YZ shears, orthogonalize 3rd row 850e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang skew[1] = row1.dot(row2); 851e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang row2.combine(row0, 1.0, -skew[1]); 852e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang skew[2] = row1.dot(row2); 853e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang row2.combine(row1, 1.0, -skew[2]); 854e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 855e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Next, get Z scale and normalize 3rd row. 856e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang scale[2] = row2.vectorLength(); 857e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang row2.divide(scale[2]); 858e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang skew[1] /= scale[2]; 859e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang skew[2] /= scale[2]; 860e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 861e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // At this point, the matrix (in rows) is orthonormal. 862e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Check for a coordinate system flip. If the determinant 863e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // is -1, then negate the matrix and the scaling factors. 864e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var pdum3 = new J3DIVector3(row1); 865e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang pdum3.cross(row2); 866e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (row0.dot(pdum3) < 0) { 867e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang for (i = 0; i < 3; i++) { 868e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang scale[i] *= -1; 869e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang row[0][i] *= -1; 870e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang row[1][i] *= -1; 871e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang row[2][i] *= -1; 872e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 873e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 874e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 875e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Now, get the rotations out 876e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang rotate[1] = Math.asin(-row0[2]); 877e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (Math.cos(rotate[1]) != 0) { 878e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang rotate[0] = Math.atan2(row1[2], row2[2]); 879e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang rotate[2] = Math.atan2(row0[1], row0[0]); 880e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 881e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang else { 882e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang rotate[0] = Math.atan2(-row2[0], row1[1]); 883e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang rotate[2] = 0; 884e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 885e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 886e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Convert rotations to degrees 887e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var rad2deg = 180 / Math.PI; 888e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang rotate[0] *= rad2deg; 889e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang rotate[1] *= rad2deg; 890e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang rotate[2] *= rad2deg; 891e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 892e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return true; 893e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 894e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 895e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype._determinant2x2 = function(a, b, c, d) 896e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 897e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return a * d - b * c; 898e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 899e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 900e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype._determinant3x3 = function(a1, a2, a3, b1, b2, b3, c1, c2, c3) 901e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 902e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return a1 * this._determinant2x2(b2, b3, c2, c3) 903e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang - b1 * this._determinant2x2(a2, a3, c2, c3) 904e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + c1 * this._determinant2x2(a2, a3, b2, b3); 905e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 906e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 907e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype._determinant4x4 = function() 908e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 909e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var a1 = this.$matrix.m11; 910e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var b1 = this.$matrix.m12; 911e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var c1 = this.$matrix.m13; 912e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var d1 = this.$matrix.m14; 913e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 914e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var a2 = this.$matrix.m21; 915e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var b2 = this.$matrix.m22; 916e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var c2 = this.$matrix.m23; 917e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var d2 = this.$matrix.m24; 918e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 919e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var a3 = this.$matrix.m31; 920e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var b3 = this.$matrix.m32; 921e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var c3 = this.$matrix.m33; 922e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var d3 = this.$matrix.m34; 923e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 924e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var a4 = this.$matrix.m41; 925e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var b4 = this.$matrix.m42; 926e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var c4 = this.$matrix.m43; 927e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var d4 = this.$matrix.m44; 928e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 929e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return a1 * this._determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4) 930e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang - b1 * this._determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4) 931e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang + c1 * this._determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4) 932e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang - d1 * this._determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4); 933e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 934e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 935e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIMatrix4.prototype._makeAdjoint = function() 936e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 937e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var a1 = this.$matrix.m11; 938e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var b1 = this.$matrix.m12; 939e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var c1 = this.$matrix.m13; 940e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var d1 = this.$matrix.m14; 941e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 942e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var a2 = this.$matrix.m21; 943e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var b2 = this.$matrix.m22; 944e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var c2 = this.$matrix.m23; 945e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var d2 = this.$matrix.m24; 946e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 947e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var a3 = this.$matrix.m31; 948e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var b3 = this.$matrix.m32; 949e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var c3 = this.$matrix.m33; 950e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var d3 = this.$matrix.m34; 951e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 952e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var a4 = this.$matrix.m41; 953e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var b4 = this.$matrix.m42; 954e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var c4 = this.$matrix.m43; 955e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var d4 = this.$matrix.m44; 956e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 957e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang // Row column labeling reversed since we transpose rows & columns 958e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m11 = this._determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4); 959e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m21 = - this._determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4); 960e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m31 = this._determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4); 961e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m41 = - this._determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4); 962e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 963e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m12 = - this._determinant3x3(b1, b3, b4, c1, c3, c4, d1, d3, d4); 964e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m22 = this._determinant3x3(a1, a3, a4, c1, c3, c4, d1, d3, d4); 965e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m32 = - this._determinant3x3(a1, a3, a4, b1, b3, b4, d1, d3, d4); 966e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m42 = this._determinant3x3(a1, a3, a4, b1, b3, b4, c1, c3, c4); 967e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 968e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m13 = this._determinant3x3(b1, b2, b4, c1, c2, c4, d1, d2, d4); 969e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m23 = - this._determinant3x3(a1, a2, a4, c1, c2, c4, d1, d2, d4); 970e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m33 = this._determinant3x3(a1, a2, a4, b1, b2, b4, d1, d2, d4); 971e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m43 = - this._determinant3x3(a1, a2, a4, b1, b2, b4, c1, c2, c4); 972e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 973e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m14 = - this._determinant3x3(b1, b2, b3, c1, c2, c3, d1, d2, d3); 974e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m24 = this._determinant3x3(a1, a2, a3, c1, c2, c3, d1, d2, d3); 975e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m34 = - this._determinant3x3(a1, a2, a3, b1, b2, b3, d1, d2, d3); 976e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.$matrix.m44 = this._determinant3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3); 977e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 978e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 979e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang// 980e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang// J3DIVector3 981e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang// 982e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIVector3 = function(x,y,z) 983e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 984e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this.load(x,y,z); 985e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 986e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 987e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIVector3.prototype.load = function(x,y,z) 988e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 989e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (typeof x == 'object' && "length" in x) { 990e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[0] = x[0]; 991e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[1] = x[1]; 992e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[2] = x[2]; 993e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 994e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang else if (typeof x == 'number') { 995e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[0] = x; 996e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[1] = y; 997e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[2] = z; 998e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 999e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang else { 1000e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[0] = 0; 1001e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[1] = 0; 1002e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[2] = 0; 1003e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 1004e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 1005e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 1006e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIVector3.prototype.getAsArray = function() 1007e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 1008e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return [ this[0], this[1], this[2] ]; 1009e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 1010e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 1011e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIVector3.prototype.getAsFloat32Array = function() 1012e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 1013e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return new Float32Array(this.getAsArray()); 1014e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 1015e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 1016e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIVector3.prototype.vectorLength = function() 1017e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 1018e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return Math.sqrt(this[0] * this[0] + this[1] * this[1] + this[2] * this[2]); 1019e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 1020e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 1021e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIVector3.prototype.divide = function(divisor) 1022e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 1023e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[0] /= divisor; this[1] /= divisor; this[2] /= divisor; 1024e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 1025e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 1026e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIVector3.prototype.cross = function(v) 1027e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 1028e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[0] = this[1] * v[2] - this[2] * v[1]; 1029e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[1] = -this[0] * v[2] + this[2] * v[0]; 1030e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[2] = this[0] * v[1] - this[1] * v[0]; 1031e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 1032e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 1033e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIVector3.prototype.dot = function(v) 1034e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 1035e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return this[0] * v[0] + this[1] * v[1] + this[2] * v[2]; 1036e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 1037e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 1038e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIVector3.prototype.combine = function(v, ascl, bscl) 1039e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 1040e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[0] = (ascl * this[0]) + (bscl * v[0]); 1041e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[1] = (ascl * this[1]) + (bscl * v[1]); 1042e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[2] = (ascl * this[2]) + (bscl * v[2]); 1043e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 1044e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 1045e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIVector3.prototype.multVecMatrix = function(matrix) 1046e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 1047e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var x = this[0]; 1048e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var y = this[1]; 1049e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var z = this[2]; 1050e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 1051e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[0] = matrix.$matrix.m41 + x * matrix.$matrix.m11 + y * matrix.$matrix.m21 + z * matrix.$matrix.m31; 1052e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[1] = matrix.$matrix.m42 + x * matrix.$matrix.m12 + y * matrix.$matrix.m22 + z * matrix.$matrix.m32; 1053e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[2] = matrix.$matrix.m43 + x * matrix.$matrix.m13 + y * matrix.$matrix.m23 + z * matrix.$matrix.m33; 1054e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang var w = matrix.$matrix.m44 + x * matrix.$matrix.m14 + y * matrix.$matrix.m24 + z * matrix.$matrix.m34; 1055e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang if (w != 1 && w != 0) { 1056e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[0] /= w; 1057e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[1] /= w; 1058e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang this[2] /= w; 1059e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang } 1060e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 1061e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang 1062e15aa36789a41772d5689bc7610d45736eae60d0Ricky LiangJ3DIVector3.prototype.toString = function() 1063e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang{ 1064e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang return "["+this[0]+","+this[1]+","+this[2]+"]"; 1065e15aa36789a41772d5689bc7610d45736eae60d0Ricky Liang} 1066