├── .gitignore ├── .npmignore ├── LICENSE.md ├── README.md ├── add.js ├── adjoint.js ├── clone.js ├── copy.js ├── create.js ├── determinant.js ├── fromQuat.js ├── fromRotation.js ├── fromRotationTranslation.js ├── fromScaling.js ├── fromTranslation.js ├── fromXRotation.js ├── fromYRotation.js ├── fromZRotation.js ├── frustum.js ├── identity.js ├── index.js ├── invert.js ├── lookAt.js ├── multiply.js ├── ortho.js ├── package.json ├── perspective.js ├── perspectiveFromFieldOfView.js ├── rotate.js ├── rotateX.js ├── rotateY.js ├── rotateZ.js ├── scale.js ├── str.js ├── sub.js ├── test └── index.js ├── tools └── parser.js ├── translate.js └── transpose.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | .DS_Store 4 | bundle.js 5 | tools/original.js 6 | README.stub.md -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | .DS_Store 4 | bundle.js 5 | test 6 | test.js 7 | tools 8 | README.stub.md -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Brandon Jones, Colin MacKenzie IV 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 16 | 2. Altered source versions must be plainly marked as such, and must not 17 | be misrepresented as being the original software. 18 | 19 | 3. This notice may not be removed or altered from any source distribution. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gl-mat4 [![stable](http://badges.github.io/stability-badges/dist/stable.svg)](http://github.com/badges/stability-badges) 2 | 3 | Part of a fork of [@toji](http://github.com/toji)'s 4 | [gl-matrix](http://github.com/toji/gl-matrix) split into smaller pieces: this 5 | package contains `glMatrix.mat4`. 6 | 7 | ## Usage 8 | 9 | [![NPM](https://nodei.co/npm/gl-mat4.png)](https://nodei.co/npm/gl-mat4/) 10 | 11 | ### `mat4 = require('gl-mat4')` 12 | 13 | Will load all of the module's functionality and expose it on a single 14 | object. Note that any of the methods may also be required directly 15 | from their files. 16 | 17 | For example, the following are equivalent: 18 | 19 | ``` javascript 20 | var scale = require('gl-mat4').scale 21 | var scale = require('gl-mat4/scale') 22 | ``` 23 | 24 | ## API 25 | 26 | - [add()](#addoutmat4-amat4-bmat4) 27 | - [adjoint()](#adjointoutmat4-amat4) 28 | - [clone()](#cloneamat4) 29 | - [copy()](#copyoutmat4-amat4) 30 | - [create()](#create) 31 | - [determinant()](#determinantamat4) 32 | - [fromQuat()](#fromquatoutmat4-qquat4) 33 | - [fromRotation()](#fromrotationoutmat4-radnumber-axisvec3) 34 | - [fromRotationTranslation()](#fromrotationtranslationoutmat4-qquat4-vvec3) 35 | - [fromScaling()](#fromscalingoutmat4-vvec3) 36 | - [fromTranslation()](#fromtranslationoutmat4-vvec3) 37 | - [fromXRotation()](#fromxrotationoutmat4-radnumber) 38 | - [fromYRotation()](#fromyrotationoutmat4-radnumber) 39 | - [fromZRotation()](#fromzrotationoutmat4-radnumber) 40 | - [frustum()](#frustumoutmat4-leftnumber-rightnumber-bottomnumber-topnumber-nearnumber-farnumber) 41 | - [identity()](#identityoutmat4) 42 | - [invert()](#invertoutmat4-amat4) 43 | - [lookAt()](#lookatoutmat4-eyevec3-centervec3-upvec3) 44 | - [multiply()](#multiplyoutmat4-amat4-bmat4) 45 | - [ortho()](#orthooutmat4-leftnumber-rightnumber-bottomnumber-topnumber-nearnumber-farnumber) 46 | - [perspective()](#perspectiveoutmat4-fovynumber-aspectnumber-nearnumber-farnumber) 47 | - [perspectiveFromFieldOfView()](#perspectivefromfieldofviewoutmat4-fovobject-nearnumber-farnumber) 48 | - [rotate()](#rotateoutmat4-amat4-radnumber-axisvec3) 49 | - [rotateX()](#rotatexoutmat4-amat4-radnumber) 50 | - [rotateY()](#rotateyoutmat4-amat4-radnumber) 51 | - [rotateZ()](#rotatezoutmat4-amat4-radnumber) 52 | - [scale()](#scaleoutmat4-amat4-vvec3) 53 | - [str()](#strmatmat4) 54 | - [sub()](#suboutmat4-amat4-bmat4) 55 | - [translate()](#translateoutmat4-amat4-vvec3) 56 | - [transpose()](#transposeoutmat4-amat4) 57 | 58 | ## add(out:mat4, a:mat4, b:mat4) 59 | 60 | Adds two mat4's 61 | 62 | ## adjoint(out:mat4, a:mat4) 63 | 64 | Calculates the adjugate of a mat4 65 | 66 | ## clone(a:mat4) 67 | 68 | Creates a new mat4 initialized with values from an existing matrix 69 | 70 | ## copy(out:mat4, a:mat4) 71 | 72 | Copy the values from one mat4 to another 73 | 74 | ## create() 75 | 76 | Creates a new identity mat4 77 | 78 | ## determinant(a:mat4) 79 | 80 | Calculates the determinant of a mat4 81 | 82 | ## fromQuat(out:mat4, q:quat4) 83 | 84 | Creates a matrix from a quaternion rotation. 85 | 86 | ## fromRotation(out:mat4, rad:number, axis:vec3) 87 | 88 | Creates a matrix from a given angle around a given axis 89 | This is equivalent to (but much faster than): 90 | 91 | ```js 92 | mat4.identity(dest); 93 | mat4.rotate(dest, dest, rad, axis); 94 | ``` 95 | 96 | ## fromRotationTranslation(out:mat4, q:quat4, v:vec3) 97 | 98 | Creates a matrix from a quaternion rotation and vector translation. This is equivalent to (but much faster than): 99 | 100 | ```js 101 | mat4.identity(dest); 102 | mat4.translate(dest, vec); 103 | var quatMat = mat4.create(); 104 | quat4.toMat4(quat, quatMat); 105 | mat4.multiply(dest, quatMat); 106 | ``` 107 | 108 | ## fromScaling(out:mat4, v:vec3) 109 | Creates a matrix from a vector scaling. This is equivalent to (but much faster than): 110 | 111 | ```js 112 | mat4.identity(dest); 113 | mat4.translate(dest, dest, vec); 114 | ``` 115 | 116 | ## fromTranslation(out:mat4, v:vec3) 117 | Creates a matrix from a vector translation. This is equivalent to (but much faster than): 118 | 119 | ```js 120 | mat4.identity(dest); 121 | mat4.translate(dest, dest, vec); 122 | ``` 123 | 124 | ## fromTranslation(out:mat4, v:vec3) 125 | Creates a matrix from a vector translation 126 | This is equivalent to (but much faster than): 127 | 128 | ```js 129 | mat4.identity(dest); 130 | mat4.translate(dest, dest, vec); 131 | ``` 132 | 133 | ## fromXRotation(out:mat4, rad:Number) 134 | 135 | Creates a matrix from the given angle around the X axis 136 | This is equivalent to (but much faster than): 137 | 138 | ```js 139 | mat4.identity(dest) 140 | mat4.rotateX(dest, dest, rad) 141 | ``` 142 | 143 | ## fromYRotation(out:mat4, rad:Number) 144 | 145 | Creates a matrix from the given angle around the Y axis 146 | This is equivalent to (but much faster than): 147 | 148 | ```js 149 | mat4.identity(dest) 150 | mat4.rotateY(dest, dest, rad) 151 | ``` 152 | 153 | ## fromZRotation(out:mat4, rad:Number) 154 | 155 | Creates a matrix from the given angle around the Z axis 156 | This is equivalent to (but much faster than): 157 | 158 | ```js 159 | mat4.identity(dest) 160 | mat4.rotateZ(dest, dest, rad) 161 | ``` 162 | 163 | ## frustum(out:mat4, left:Number, right:Number, bottom:Number, top:Number, near:Number, far:Number) 164 | 165 | Generates a frustum matrix with the given bounds 166 | 167 | ## identity(out:mat4) 168 | 169 | Set a mat4 to the identity matrix 170 | 171 | ## invert(out:mat4, a:mat4) 172 | 173 | Inverts a mat4 174 | 175 | ## lookAt(out:mat4, eye:vec3, center:vec3, up:vec3) 176 | 177 | Generates a look-at matrix with the given eye position, focal point, and up axis 178 | 179 | ## multiply(out:mat4, a:mat4, b:mat4) 180 | 181 | Multiplies two mat4's 182 | 183 | ## ortho(out:mat4, left:number, right:number, bottom:number, top:number, near:number, far:number) 184 | 185 | Generates a orthogonal projection matrix with the given bounds 186 | 187 | ## perspective(out:mat4, fovy:number, aspect:number, near:number, far:number) 188 | 189 | Generates a perspective projection matrix with the given bounds 190 | 191 | ## perspectiveFromFieldOfView(out:mat4, fov:object, near:number, far:number) 192 | 193 | Generates a perspective projection matrix with the given field of view. 194 | 195 | ## rotate(out:mat4, a:mat4, rad:Number, axis:vec3) 196 | 197 | Rotates a mat4 by the given angle 198 | 199 | ## rotateX(out:mat4, a:mat4, rad:Number) 200 | 201 | Rotates a matrix by the given angle around the X axis 202 | 203 | ## rotateY(out:mat4, a:mat4, rad:Number) 204 | 205 | Rotates a matrix by the given angle around the Y axis 206 | 207 | ## rotateZ(out:mat4, a:mat4, rad:Number) 208 | 209 | Rotates a matrix by the given angle around the Z axis 210 | 211 | ## scale(out:mat4, a:mat4, v:vec3) 212 | 213 | Scales the mat4 by the dimensions in the given vec3 214 | 215 | ## str(mat:mat4) 216 | 217 | Returns a string representation of a mat4 218 | 219 | ## sub(out:mat4, a:mat4, b:mat4) 220 | 221 | Subtracts two mat4's 222 | 223 | ## translate(out:mat4, a:mat4, v:vec3) 224 | 225 | Translate a mat4 by the given vector 226 | 227 | ## transpose(out:mat4, a:mat4) 228 | 229 | Transpose the values of a mat4 230 | 231 | ## License 232 | 233 | [zlib](http://en.wikipedia.org/wiki/Zlib_License). See [LICENSE.md](https://github.com/stackgl/gl-mat4/blob/master/LICENSE.md) for details. 234 | -------------------------------------------------------------------------------- /add.js: -------------------------------------------------------------------------------- 1 | module.exports = add; 2 | 3 | /** 4 | * Adds two mat4's 5 | * 6 | * @param {mat4} the first operand 7 | * @param {mat4} the second operand 8 | * @returns {mat4} out 9 | */ 10 | function add(out, a, b) { 11 | out[0] = a[0] + b[0]; 12 | out[1] = a[1] + b[1]; 13 | out[2] = a[2] + b[2]; 14 | out[3] = a[3] + b[3]; 15 | out[4] = a[4] + b[4]; 16 | out[5] = a[5] + b[5]; 17 | out[6] = a[6] + b[6]; 18 | out[7] = a[7] + b[7]; 19 | out[8] = a[8] + b[8]; 20 | out[9] = a[9] + b[9]; 21 | out[10] = a[10] + b[10]; 22 | out[11] = a[11] + b[11]; 23 | out[12] = a[12] + b[12]; 24 | out[13] = a[13] + b[13]; 25 | out[14] = a[14] + b[14]; 26 | out[15] = a[15] + b[15]; 27 | return out; 28 | }; 29 | -------------------------------------------------------------------------------- /adjoint.js: -------------------------------------------------------------------------------- 1 | module.exports = adjoint; 2 | 3 | /** 4 | * Calculates the adjugate of a mat4 5 | * 6 | * @param {mat4} out the receiving matrix 7 | * @param {mat4} a the source matrix 8 | * @returns {mat4} out 9 | */ 10 | function adjoint(out, a) { 11 | var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3], 12 | a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7], 13 | a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11], 14 | a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; 15 | 16 | out[0] = (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22)); 17 | out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22)); 18 | out[2] = (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12)); 19 | out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12)); 20 | out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22)); 21 | out[5] = (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22)); 22 | out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12)); 23 | out[7] = (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12)); 24 | out[8] = (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21)); 25 | out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21)); 26 | out[10] = (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11)); 27 | out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11)); 28 | out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21)); 29 | out[13] = (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21)); 30 | out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11)); 31 | out[15] = (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11)); 32 | return out; 33 | }; -------------------------------------------------------------------------------- /clone.js: -------------------------------------------------------------------------------- 1 | module.exports = clone; 2 | 3 | /** 4 | * Creates a new mat4 initialized with values from an existing matrix 5 | * 6 | * @param {mat4} a matrix to clone 7 | * @returns {mat4} a new 4x4 matrix 8 | */ 9 | function clone(a) { 10 | var out = new Float32Array(16); 11 | out[0] = a[0]; 12 | out[1] = a[1]; 13 | out[2] = a[2]; 14 | out[3] = a[3]; 15 | out[4] = a[4]; 16 | out[5] = a[5]; 17 | out[6] = a[6]; 18 | out[7] = a[7]; 19 | out[8] = a[8]; 20 | out[9] = a[9]; 21 | out[10] = a[10]; 22 | out[11] = a[11]; 23 | out[12] = a[12]; 24 | out[13] = a[13]; 25 | out[14] = a[14]; 26 | out[15] = a[15]; 27 | return out; 28 | }; -------------------------------------------------------------------------------- /copy.js: -------------------------------------------------------------------------------- 1 | module.exports = copy; 2 | 3 | /** 4 | * Copy the values from one mat4 to another 5 | * 6 | * @param {mat4} out the receiving matrix 7 | * @param {mat4} a the source matrix 8 | * @returns {mat4} out 9 | */ 10 | function copy(out, a) { 11 | out[0] = a[0]; 12 | out[1] = a[1]; 13 | out[2] = a[2]; 14 | out[3] = a[3]; 15 | out[4] = a[4]; 16 | out[5] = a[5]; 17 | out[6] = a[6]; 18 | out[7] = a[7]; 19 | out[8] = a[8]; 20 | out[9] = a[9]; 21 | out[10] = a[10]; 22 | out[11] = a[11]; 23 | out[12] = a[12]; 24 | out[13] = a[13]; 25 | out[14] = a[14]; 26 | out[15] = a[15]; 27 | return out; 28 | }; -------------------------------------------------------------------------------- /create.js: -------------------------------------------------------------------------------- 1 | module.exports = create; 2 | 3 | /** 4 | * Creates a new identity mat4 5 | * 6 | * @returns {mat4} a new 4x4 matrix 7 | */ 8 | function create() { 9 | var out = new Float32Array(16); 10 | out[0] = 1; 11 | out[1] = 0; 12 | out[2] = 0; 13 | out[3] = 0; 14 | out[4] = 0; 15 | out[5] = 1; 16 | out[6] = 0; 17 | out[7] = 0; 18 | out[8] = 0; 19 | out[9] = 0; 20 | out[10] = 1; 21 | out[11] = 0; 22 | out[12] = 0; 23 | out[13] = 0; 24 | out[14] = 0; 25 | out[15] = 1; 26 | return out; 27 | }; -------------------------------------------------------------------------------- /determinant.js: -------------------------------------------------------------------------------- 1 | module.exports = determinant; 2 | 3 | /** 4 | * Calculates the determinant of a mat4 5 | * 6 | * @param {mat4} a the source matrix 7 | * @returns {Number} determinant of a 8 | */ 9 | function determinant(a) { 10 | var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3], 11 | a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7], 12 | a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11], 13 | a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15], 14 | 15 | b00 = a00 * a11 - a01 * a10, 16 | b01 = a00 * a12 - a02 * a10, 17 | b02 = a00 * a13 - a03 * a10, 18 | b03 = a01 * a12 - a02 * a11, 19 | b04 = a01 * a13 - a03 * a11, 20 | b05 = a02 * a13 - a03 * a12, 21 | b06 = a20 * a31 - a21 * a30, 22 | b07 = a20 * a32 - a22 * a30, 23 | b08 = a20 * a33 - a23 * a30, 24 | b09 = a21 * a32 - a22 * a31, 25 | b10 = a21 * a33 - a23 * a31, 26 | b11 = a22 * a33 - a23 * a32; 27 | 28 | // Calculate the determinant 29 | return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; 30 | }; -------------------------------------------------------------------------------- /fromQuat.js: -------------------------------------------------------------------------------- 1 | module.exports = fromQuat; 2 | 3 | /** 4 | * Creates a matrix from a quaternion rotation. 5 | * 6 | * @param {mat4} out mat4 receiving operation result 7 | * @param {quat4} q Rotation quaternion 8 | * @returns {mat4} out 9 | */ 10 | function fromQuat(out, q) { 11 | var x = q[0], y = q[1], z = q[2], w = q[3], 12 | x2 = x + x, 13 | y2 = y + y, 14 | z2 = z + z, 15 | 16 | xx = x * x2, 17 | yx = y * x2, 18 | yy = y * y2, 19 | zx = z * x2, 20 | zy = z * y2, 21 | zz = z * z2, 22 | wx = w * x2, 23 | wy = w * y2, 24 | wz = w * z2; 25 | 26 | out[0] = 1 - yy - zz; 27 | out[1] = yx + wz; 28 | out[2] = zx - wy; 29 | out[3] = 0; 30 | 31 | out[4] = yx - wz; 32 | out[5] = 1 - xx - zz; 33 | out[6] = zy + wx; 34 | out[7] = 0; 35 | 36 | out[8] = zx + wy; 37 | out[9] = zy - wx; 38 | out[10] = 1 - xx - yy; 39 | out[11] = 0; 40 | 41 | out[12] = 0; 42 | out[13] = 0; 43 | out[14] = 0; 44 | out[15] = 1; 45 | 46 | return out; 47 | }; -------------------------------------------------------------------------------- /fromRotation.js: -------------------------------------------------------------------------------- 1 | module.exports = fromRotation 2 | 3 | /** 4 | * Creates a matrix from a given angle around a given axis 5 | * This is equivalent to (but much faster than): 6 | * 7 | * mat4.identity(dest) 8 | * mat4.rotate(dest, dest, rad, axis) 9 | * 10 | * @param {mat4} out mat4 receiving operation result 11 | * @param {Number} rad the angle to rotate the matrix by 12 | * @param {vec3} axis the axis to rotate around 13 | * @returns {mat4} out 14 | */ 15 | function fromRotation(out, rad, axis) { 16 | var s, c, t 17 | var x = axis[0] 18 | var y = axis[1] 19 | var z = axis[2] 20 | var len = Math.sqrt(x * x + y * y + z * z) 21 | 22 | if (Math.abs(len) < 0.000001) { 23 | return null 24 | } 25 | 26 | len = 1 / len 27 | x *= len 28 | y *= len 29 | z *= len 30 | 31 | s = Math.sin(rad) 32 | c = Math.cos(rad) 33 | t = 1 - c 34 | 35 | // Perform rotation-specific matrix multiplication 36 | out[0] = x * x * t + c 37 | out[1] = y * x * t + z * s 38 | out[2] = z * x * t - y * s 39 | out[3] = 0 40 | out[4] = x * y * t - z * s 41 | out[5] = y * y * t + c 42 | out[6] = z * y * t + x * s 43 | out[7] = 0 44 | out[8] = x * z * t + y * s 45 | out[9] = y * z * t - x * s 46 | out[10] = z * z * t + c 47 | out[11] = 0 48 | out[12] = 0 49 | out[13] = 0 50 | out[14] = 0 51 | out[15] = 1 52 | return out 53 | } 54 | -------------------------------------------------------------------------------- /fromRotationTranslation.js: -------------------------------------------------------------------------------- 1 | module.exports = fromRotationTranslation; 2 | 3 | /** 4 | * Creates a matrix from a quaternion rotation and vector translation 5 | * This is equivalent to (but much faster than): 6 | * 7 | * mat4.identity(dest); 8 | * mat4.translate(dest, vec); 9 | * var quatMat = mat4.create(); 10 | * quat4.toMat4(quat, quatMat); 11 | * mat4.multiply(dest, quatMat); 12 | * 13 | * @param {mat4} out mat4 receiving operation result 14 | * @param {quat4} q Rotation quaternion 15 | * @param {vec3} v Translation vector 16 | * @returns {mat4} out 17 | */ 18 | function fromRotationTranslation(out, q, v) { 19 | // Quaternion math 20 | var x = q[0], y = q[1], z = q[2], w = q[3], 21 | x2 = x + x, 22 | y2 = y + y, 23 | z2 = z + z, 24 | 25 | xx = x * x2, 26 | xy = x * y2, 27 | xz = x * z2, 28 | yy = y * y2, 29 | yz = y * z2, 30 | zz = z * z2, 31 | wx = w * x2, 32 | wy = w * y2, 33 | wz = w * z2; 34 | 35 | out[0] = 1 - (yy + zz); 36 | out[1] = xy + wz; 37 | out[2] = xz - wy; 38 | out[3] = 0; 39 | out[4] = xy - wz; 40 | out[5] = 1 - (xx + zz); 41 | out[6] = yz + wx; 42 | out[7] = 0; 43 | out[8] = xz + wy; 44 | out[9] = yz - wx; 45 | out[10] = 1 - (xx + yy); 46 | out[11] = 0; 47 | out[12] = v[0]; 48 | out[13] = v[1]; 49 | out[14] = v[2]; 50 | out[15] = 1; 51 | 52 | return out; 53 | }; -------------------------------------------------------------------------------- /fromScaling.js: -------------------------------------------------------------------------------- 1 | module.exports = fromScaling 2 | 3 | /** 4 | * Creates a matrix from a vector scaling 5 | * This is equivalent to (but much faster than): 6 | * 7 | * mat4.identity(dest) 8 | * mat4.scale(dest, dest, vec) 9 | * 10 | * @param {mat4} out mat4 receiving operation result 11 | * @param {vec3} v Scaling vector 12 | * @returns {mat4} out 13 | */ 14 | function fromScaling(out, v) { 15 | out[0] = v[0] 16 | out[1] = 0 17 | out[2] = 0 18 | out[3] = 0 19 | out[4] = 0 20 | out[5] = v[1] 21 | out[6] = 0 22 | out[7] = 0 23 | out[8] = 0 24 | out[9] = 0 25 | out[10] = v[2] 26 | out[11] = 0 27 | out[12] = 0 28 | out[13] = 0 29 | out[14] = 0 30 | out[15] = 1 31 | return out 32 | } 33 | -------------------------------------------------------------------------------- /fromTranslation.js: -------------------------------------------------------------------------------- 1 | module.exports = fromTranslation 2 | 3 | /** 4 | * Creates a matrix from a vector translation 5 | * This is equivalent to (but much faster than): 6 | * 7 | * mat4.identity(dest) 8 | * mat4.translate(dest, dest, vec) 9 | * 10 | * @param {mat4} out mat4 receiving operation result 11 | * @param {vec3} v Translation vector 12 | * @returns {mat4} out 13 | */ 14 | function fromTranslation(out, v) { 15 | out[0] = 1 16 | out[1] = 0 17 | out[2] = 0 18 | out[3] = 0 19 | out[4] = 0 20 | out[5] = 1 21 | out[6] = 0 22 | out[7] = 0 23 | out[8] = 0 24 | out[9] = 0 25 | out[10] = 1 26 | out[11] = 0 27 | out[12] = v[0] 28 | out[13] = v[1] 29 | out[14] = v[2] 30 | out[15] = 1 31 | return out 32 | } 33 | -------------------------------------------------------------------------------- /fromXRotation.js: -------------------------------------------------------------------------------- 1 | module.exports = fromXRotation 2 | 3 | /** 4 | * Creates a matrix from the given angle around the X axis 5 | * This is equivalent to (but much faster than): 6 | * 7 | * mat4.identity(dest) 8 | * mat4.rotateX(dest, dest, rad) 9 | * 10 | * @param {mat4} out mat4 receiving operation result 11 | * @param {Number} rad the angle to rotate the matrix by 12 | * @returns {mat4} out 13 | */ 14 | function fromXRotation(out, rad) { 15 | var s = Math.sin(rad), 16 | c = Math.cos(rad) 17 | 18 | // Perform axis-specific matrix multiplication 19 | out[0] = 1 20 | out[1] = 0 21 | out[2] = 0 22 | out[3] = 0 23 | out[4] = 0 24 | out[5] = c 25 | out[6] = s 26 | out[7] = 0 27 | out[8] = 0 28 | out[9] = -s 29 | out[10] = c 30 | out[11] = 0 31 | out[12] = 0 32 | out[13] = 0 33 | out[14] = 0 34 | out[15] = 1 35 | return out 36 | } -------------------------------------------------------------------------------- /fromYRotation.js: -------------------------------------------------------------------------------- 1 | module.exports = fromYRotation 2 | 3 | /** 4 | * Creates a matrix from the given angle around the Y axis 5 | * This is equivalent to (but much faster than): 6 | * 7 | * mat4.identity(dest) 8 | * mat4.rotateY(dest, dest, rad) 9 | * 10 | * @param {mat4} out mat4 receiving operation result 11 | * @param {Number} rad the angle to rotate the matrix by 12 | * @returns {mat4} out 13 | */ 14 | function fromYRotation(out, rad) { 15 | var s = Math.sin(rad), 16 | c = Math.cos(rad) 17 | 18 | // Perform axis-specific matrix multiplication 19 | out[0] = c 20 | out[1] = 0 21 | out[2] = -s 22 | out[3] = 0 23 | out[4] = 0 24 | out[5] = 1 25 | out[6] = 0 26 | out[7] = 0 27 | out[8] = s 28 | out[9] = 0 29 | out[10] = c 30 | out[11] = 0 31 | out[12] = 0 32 | out[13] = 0 33 | out[14] = 0 34 | out[15] = 1 35 | return out 36 | } -------------------------------------------------------------------------------- /fromZRotation.js: -------------------------------------------------------------------------------- 1 | module.exports = fromZRotation 2 | 3 | /** 4 | * Creates a matrix from the given angle around the Z axis 5 | * This is equivalent to (but much faster than): 6 | * 7 | * mat4.identity(dest) 8 | * mat4.rotateZ(dest, dest, rad) 9 | * 10 | * @param {mat4} out mat4 receiving operation result 11 | * @param {Number} rad the angle to rotate the matrix by 12 | * @returns {mat4} out 13 | */ 14 | function fromZRotation(out, rad) { 15 | var s = Math.sin(rad), 16 | c = Math.cos(rad) 17 | 18 | // Perform axis-specific matrix multiplication 19 | out[0] = c 20 | out[1] = s 21 | out[2] = 0 22 | out[3] = 0 23 | out[4] = -s 24 | out[5] = c 25 | out[6] = 0 26 | out[7] = 0 27 | out[8] = 0 28 | out[9] = 0 29 | out[10] = 1 30 | out[11] = 0 31 | out[12] = 0 32 | out[13] = 0 33 | out[14] = 0 34 | out[15] = 1 35 | return out 36 | } -------------------------------------------------------------------------------- /frustum.js: -------------------------------------------------------------------------------- 1 | module.exports = frustum; 2 | 3 | /** 4 | * Generates a frustum matrix with the given bounds 5 | * 6 | * @param {mat4} out mat4 frustum matrix will be written into 7 | * @param {Number} left Left bound of the frustum 8 | * @param {Number} right Right bound of the frustum 9 | * @param {Number} bottom Bottom bound of the frustum 10 | * @param {Number} top Top bound of the frustum 11 | * @param {Number} near Near bound of the frustum 12 | * @param {Number} far Far bound of the frustum 13 | * @returns {mat4} out 14 | */ 15 | function frustum(out, left, right, bottom, top, near, far) { 16 | var rl = 1 / (right - left), 17 | tb = 1 / (top - bottom), 18 | nf = 1 / (near - far); 19 | out[0] = (near * 2) * rl; 20 | out[1] = 0; 21 | out[2] = 0; 22 | out[3] = 0; 23 | out[4] = 0; 24 | out[5] = (near * 2) * tb; 25 | out[6] = 0; 26 | out[7] = 0; 27 | out[8] = (right + left) * rl; 28 | out[9] = (top + bottom) * tb; 29 | out[10] = (far + near) * nf; 30 | out[11] = -1; 31 | out[12] = 0; 32 | out[13] = 0; 33 | out[14] = (far * near * 2) * nf; 34 | out[15] = 0; 35 | return out; 36 | }; -------------------------------------------------------------------------------- /identity.js: -------------------------------------------------------------------------------- 1 | module.exports = identity; 2 | 3 | /** 4 | * Set a mat4 to the identity matrix 5 | * 6 | * @param {mat4} out the receiving matrix 7 | * @returns {mat4} out 8 | */ 9 | function identity(out) { 10 | out[0] = 1; 11 | out[1] = 0; 12 | out[2] = 0; 13 | out[3] = 0; 14 | out[4] = 0; 15 | out[5] = 1; 16 | out[6] = 0; 17 | out[7] = 0; 18 | out[8] = 0; 19 | out[9] = 0; 20 | out[10] = 1; 21 | out[11] = 0; 22 | out[12] = 0; 23 | out[13] = 0; 24 | out[14] = 0; 25 | out[15] = 1; 26 | return out; 27 | }; -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | add: require('./add') 3 | , create: require('./create') 4 | , clone: require('./clone') 5 | , copy: require('./copy') 6 | , identity: require('./identity') 7 | , transpose: require('./transpose') 8 | , invert: require('./invert') 9 | , adjoint: require('./adjoint') 10 | , determinant: require('./determinant') 11 | , multiply: require('./multiply') 12 | , translate: require('./translate') 13 | , scale: require('./scale') 14 | , rotate: require('./rotate') 15 | , rotateX: require('./rotateX') 16 | , rotateY: require('./rotateY') 17 | , rotateZ: require('./rotateZ') 18 | , fromRotation: require('./fromRotation') 19 | , fromRotationTranslation: require('./fromRotationTranslation') 20 | , fromScaling: require('./fromScaling') 21 | , fromTranslation: require('./fromTranslation') 22 | , fromXRotation: require('./fromXRotation') 23 | , fromYRotation: require('./fromYRotation') 24 | , fromZRotation: require('./fromZRotation') 25 | , fromQuat: require('./fromQuat') 26 | , frustum: require('./frustum') 27 | , perspective: require('./perspective') 28 | , perspectiveFromFieldOfView: require('./perspectiveFromFieldOfView') 29 | , ortho: require('./ortho') 30 | , lookAt: require('./lookAt') 31 | , str: require('./str') 32 | , sub: require('./sub') 33 | } 34 | -------------------------------------------------------------------------------- /invert.js: -------------------------------------------------------------------------------- 1 | module.exports = invert; 2 | 3 | /** 4 | * Inverts a mat4 5 | * 6 | * @param {mat4} out the receiving matrix 7 | * @param {mat4} a the source matrix 8 | * @returns {mat4} out 9 | */ 10 | function invert(out, a) { 11 | var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3], 12 | a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7], 13 | a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11], 14 | a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15], 15 | 16 | b00 = a00 * a11 - a01 * a10, 17 | b01 = a00 * a12 - a02 * a10, 18 | b02 = a00 * a13 - a03 * a10, 19 | b03 = a01 * a12 - a02 * a11, 20 | b04 = a01 * a13 - a03 * a11, 21 | b05 = a02 * a13 - a03 * a12, 22 | b06 = a20 * a31 - a21 * a30, 23 | b07 = a20 * a32 - a22 * a30, 24 | b08 = a20 * a33 - a23 * a30, 25 | b09 = a21 * a32 - a22 * a31, 26 | b10 = a21 * a33 - a23 * a31, 27 | b11 = a22 * a33 - a23 * a32, 28 | 29 | // Calculate the determinant 30 | det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; 31 | 32 | if (!det) { 33 | return null; 34 | } 35 | det = 1.0 / det; 36 | 37 | out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; 38 | out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; 39 | out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; 40 | out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; 41 | out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; 42 | out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; 43 | out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; 44 | out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; 45 | out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; 46 | out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; 47 | out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; 48 | out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; 49 | out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; 50 | out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; 51 | out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; 52 | out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; 53 | 54 | return out; 55 | }; -------------------------------------------------------------------------------- /lookAt.js: -------------------------------------------------------------------------------- 1 | var identity = require('./identity'); 2 | 3 | module.exports = lookAt; 4 | 5 | /** 6 | * Generates a look-at matrix with the given eye position, focal point, and up axis 7 | * 8 | * @param {mat4} out mat4 frustum matrix will be written into 9 | * @param {vec3} eye Position of the viewer 10 | * @param {vec3} center Point the viewer is looking at 11 | * @param {vec3} up vec3 pointing up 12 | * @returns {mat4} out 13 | */ 14 | function lookAt(out, eye, center, up) { 15 | var x0, x1, x2, y0, y1, y2, z0, z1, z2, len, 16 | eyex = eye[0], 17 | eyey = eye[1], 18 | eyez = eye[2], 19 | upx = up[0], 20 | upy = up[1], 21 | upz = up[2], 22 | centerx = center[0], 23 | centery = center[1], 24 | centerz = center[2]; 25 | 26 | if (Math.abs(eyex - centerx) < 0.000001 && 27 | Math.abs(eyey - centery) < 0.000001 && 28 | Math.abs(eyez - centerz) < 0.000001) { 29 | return identity(out); 30 | } 31 | 32 | z0 = eyex - centerx; 33 | z1 = eyey - centery; 34 | z2 = eyez - centerz; 35 | 36 | len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2); 37 | z0 *= len; 38 | z1 *= len; 39 | z2 *= len; 40 | 41 | x0 = upy * z2 - upz * z1; 42 | x1 = upz * z0 - upx * z2; 43 | x2 = upx * z1 - upy * z0; 44 | len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2); 45 | if (!len) { 46 | x0 = 0; 47 | x1 = 0; 48 | x2 = 0; 49 | } else { 50 | len = 1 / len; 51 | x0 *= len; 52 | x1 *= len; 53 | x2 *= len; 54 | } 55 | 56 | y0 = z1 * x2 - z2 * x1; 57 | y1 = z2 * x0 - z0 * x2; 58 | y2 = z0 * x1 - z1 * x0; 59 | 60 | len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2); 61 | if (!len) { 62 | y0 = 0; 63 | y1 = 0; 64 | y2 = 0; 65 | } else { 66 | len = 1 / len; 67 | y0 *= len; 68 | y1 *= len; 69 | y2 *= len; 70 | } 71 | 72 | out[0] = x0; 73 | out[1] = y0; 74 | out[2] = z0; 75 | out[3] = 0; 76 | out[4] = x1; 77 | out[5] = y1; 78 | out[6] = z1; 79 | out[7] = 0; 80 | out[8] = x2; 81 | out[9] = y2; 82 | out[10] = z2; 83 | out[11] = 0; 84 | out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez); 85 | out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez); 86 | out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez); 87 | out[15] = 1; 88 | 89 | return out; 90 | }; -------------------------------------------------------------------------------- /multiply.js: -------------------------------------------------------------------------------- 1 | module.exports = multiply; 2 | 3 | /** 4 | * Multiplies two mat4's 5 | * 6 | * @param {mat4} out the receiving matrix 7 | * @param {mat4} a the first operand 8 | * @param {mat4} b the second operand 9 | * @returns {mat4} out 10 | */ 11 | function multiply(out, a, b) { 12 | var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3], 13 | a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7], 14 | a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11], 15 | a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; 16 | 17 | // Cache only the current line of the second matrix 18 | var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; 19 | out[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30; 20 | out[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31; 21 | out[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32; 22 | out[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33; 23 | 24 | b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7]; 25 | out[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30; 26 | out[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31; 27 | out[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32; 28 | out[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33; 29 | 30 | b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11]; 31 | out[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30; 32 | out[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31; 33 | out[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32; 34 | out[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33; 35 | 36 | b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15]; 37 | out[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30; 38 | out[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31; 39 | out[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32; 40 | out[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33; 41 | return out; 42 | }; -------------------------------------------------------------------------------- /ortho.js: -------------------------------------------------------------------------------- 1 | module.exports = ortho; 2 | 3 | /** 4 | * Generates a orthogonal projection matrix with the given bounds 5 | * 6 | * @param {mat4} out mat4 frustum matrix will be written into 7 | * @param {number} left Left bound of the frustum 8 | * @param {number} right Right bound of the frustum 9 | * @param {number} bottom Bottom bound of the frustum 10 | * @param {number} top Top bound of the frustum 11 | * @param {number} near Near bound of the frustum 12 | * @param {number} far Far bound of the frustum 13 | * @returns {mat4} out 14 | */ 15 | function ortho(out, left, right, bottom, top, near, far) { 16 | var lr = 1 / (left - right), 17 | bt = 1 / (bottom - top), 18 | nf = 1 / (near - far); 19 | out[0] = -2 * lr; 20 | out[1] = 0; 21 | out[2] = 0; 22 | out[3] = 0; 23 | out[4] = 0; 24 | out[5] = -2 * bt; 25 | out[6] = 0; 26 | out[7] = 0; 27 | out[8] = 0; 28 | out[9] = 0; 29 | out[10] = 2 * nf; 30 | out[11] = 0; 31 | out[12] = (left + right) * lr; 32 | out[13] = (top + bottom) * bt; 33 | out[14] = (far + near) * nf; 34 | out[15] = 1; 35 | return out; 36 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gl-mat4", 3 | "version": "1.3.0", 4 | "description": "gl-matrix's mat4, split into smaller pieces", 5 | "main": "index.js", 6 | "scripts": { 7 | "get-docs": "cat *.js | dox --api" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/stackgl/gl-mat4" 12 | }, 13 | "keywords": [ 14 | "gl-matrix", 15 | "matrix", 16 | "math", 17 | "gl", 18 | "mat4", 19 | "mat4x4", 20 | "4x4", 21 | "mat", 22 | "vector", 23 | "maths" 24 | ], 25 | "license": "Zlib", 26 | "contributors": [ 27 | "Brandon Jones ", 28 | "Colin MacKenzie IV " 29 | ], 30 | "dependencies": {}, 31 | "devDependencies": { 32 | "dox": "git://github.com/hughsk/dox#api-context" 33 | }, 34 | "bugs": { 35 | "url": "https://github.com/stackgl/gl-mat4/issues" 36 | }, 37 | "homepage": "https://github.com/stackgl/gl-mat4" 38 | } 39 | -------------------------------------------------------------------------------- /perspective.js: -------------------------------------------------------------------------------- 1 | module.exports = perspective; 2 | 3 | /** 4 | * Generates a perspective projection matrix with the given bounds 5 | * 6 | * @param {mat4} out mat4 frustum matrix will be written into 7 | * @param {number} fovy Vertical field of view in radians 8 | * @param {number} aspect Aspect ratio. typically viewport width/height 9 | * @param {number} near Near bound of the frustum 10 | * @param {number} far Far bound of the frustum 11 | * @returns {mat4} out 12 | */ 13 | function perspective(out, fovy, aspect, near, far) { 14 | var f = 1.0 / Math.tan(fovy / 2), 15 | nf = 1 / (near - far); 16 | out[0] = f / aspect; 17 | out[1] = 0; 18 | out[2] = 0; 19 | out[3] = 0; 20 | out[4] = 0; 21 | out[5] = f; 22 | out[6] = 0; 23 | out[7] = 0; 24 | out[8] = 0; 25 | out[9] = 0; 26 | out[10] = (far + near) * nf; 27 | out[11] = -1; 28 | out[12] = 0; 29 | out[13] = 0; 30 | out[14] = (2 * far * near) * nf; 31 | out[15] = 0; 32 | return out; 33 | }; -------------------------------------------------------------------------------- /perspectiveFromFieldOfView.js: -------------------------------------------------------------------------------- 1 | module.exports = perspectiveFromFieldOfView; 2 | 3 | /** 4 | * Generates a perspective projection matrix with the given field of view. 5 | * This is primarily useful for generating projection matrices to be used 6 | * with the still experiemental WebVR API. 7 | * 8 | * @param {mat4} out mat4 frustum matrix will be written into 9 | * @param {number} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees 10 | * @param {number} near Near bound of the frustum 11 | * @param {number} far Far bound of the frustum 12 | * @returns {mat4} out 13 | */ 14 | function perspectiveFromFieldOfView(out, fov, near, far) { 15 | var upTan = Math.tan(fov.upDegrees * Math.PI/180.0), 16 | downTan = Math.tan(fov.downDegrees * Math.PI/180.0), 17 | leftTan = Math.tan(fov.leftDegrees * Math.PI/180.0), 18 | rightTan = Math.tan(fov.rightDegrees * Math.PI/180.0), 19 | xScale = 2.0 / (leftTan + rightTan), 20 | yScale = 2.0 / (upTan + downTan); 21 | 22 | out[0] = xScale; 23 | out[1] = 0.0; 24 | out[2] = 0.0; 25 | out[3] = 0.0; 26 | out[4] = 0.0; 27 | out[5] = yScale; 28 | out[6] = 0.0; 29 | out[7] = 0.0; 30 | out[8] = -((leftTan - rightTan) * xScale * 0.5); 31 | out[9] = ((upTan - downTan) * yScale * 0.5); 32 | out[10] = far / (near - far); 33 | out[11] = -1.0; 34 | out[12] = 0.0; 35 | out[13] = 0.0; 36 | out[14] = (far * near) / (near - far); 37 | out[15] = 0.0; 38 | return out; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /rotate.js: -------------------------------------------------------------------------------- 1 | module.exports = rotate; 2 | 3 | /** 4 | * Rotates a mat4 by the given angle 5 | * 6 | * @param {mat4} out the receiving matrix 7 | * @param {mat4} a the matrix to rotate 8 | * @param {Number} rad the angle to rotate the matrix by 9 | * @param {vec3} axis the axis to rotate around 10 | * @returns {mat4} out 11 | */ 12 | function rotate(out, a, rad, axis) { 13 | var x = axis[0], y = axis[1], z = axis[2], 14 | len = Math.sqrt(x * x + y * y + z * z), 15 | s, c, t, 16 | a00, a01, a02, a03, 17 | a10, a11, a12, a13, 18 | a20, a21, a22, a23, 19 | b00, b01, b02, 20 | b10, b11, b12, 21 | b20, b21, b22; 22 | 23 | if (Math.abs(len) < 0.000001) { return null; } 24 | 25 | len = 1 / len; 26 | x *= len; 27 | y *= len; 28 | z *= len; 29 | 30 | s = Math.sin(rad); 31 | c = Math.cos(rad); 32 | t = 1 - c; 33 | 34 | a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; 35 | a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; 36 | a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; 37 | 38 | // Construct the elements of the rotation matrix 39 | b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s; 40 | b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s; 41 | b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c; 42 | 43 | // Perform rotation-specific matrix multiplication 44 | out[0] = a00 * b00 + a10 * b01 + a20 * b02; 45 | out[1] = a01 * b00 + a11 * b01 + a21 * b02; 46 | out[2] = a02 * b00 + a12 * b01 + a22 * b02; 47 | out[3] = a03 * b00 + a13 * b01 + a23 * b02; 48 | out[4] = a00 * b10 + a10 * b11 + a20 * b12; 49 | out[5] = a01 * b10 + a11 * b11 + a21 * b12; 50 | out[6] = a02 * b10 + a12 * b11 + a22 * b12; 51 | out[7] = a03 * b10 + a13 * b11 + a23 * b12; 52 | out[8] = a00 * b20 + a10 * b21 + a20 * b22; 53 | out[9] = a01 * b20 + a11 * b21 + a21 * b22; 54 | out[10] = a02 * b20 + a12 * b21 + a22 * b22; 55 | out[11] = a03 * b20 + a13 * b21 + a23 * b22; 56 | 57 | if (a !== out) { // If the source and destination differ, copy the unchanged last row 58 | out[12] = a[12]; 59 | out[13] = a[13]; 60 | out[14] = a[14]; 61 | out[15] = a[15]; 62 | } 63 | return out; 64 | }; -------------------------------------------------------------------------------- /rotateX.js: -------------------------------------------------------------------------------- 1 | module.exports = rotateX; 2 | 3 | /** 4 | * Rotates a matrix by the given angle around the X axis 5 | * 6 | * @param {mat4} out the receiving matrix 7 | * @param {mat4} a the matrix to rotate 8 | * @param {Number} rad the angle to rotate the matrix by 9 | * @returns {mat4} out 10 | */ 11 | function rotateX(out, a, rad) { 12 | var s = Math.sin(rad), 13 | c = Math.cos(rad), 14 | a10 = a[4], 15 | a11 = a[5], 16 | a12 = a[6], 17 | a13 = a[7], 18 | a20 = a[8], 19 | a21 = a[9], 20 | a22 = a[10], 21 | a23 = a[11]; 22 | 23 | if (a !== out) { // If the source and destination differ, copy the unchanged rows 24 | out[0] = a[0]; 25 | out[1] = a[1]; 26 | out[2] = a[2]; 27 | out[3] = a[3]; 28 | out[12] = a[12]; 29 | out[13] = a[13]; 30 | out[14] = a[14]; 31 | out[15] = a[15]; 32 | } 33 | 34 | // Perform axis-specific matrix multiplication 35 | out[4] = a10 * c + a20 * s; 36 | out[5] = a11 * c + a21 * s; 37 | out[6] = a12 * c + a22 * s; 38 | out[7] = a13 * c + a23 * s; 39 | out[8] = a20 * c - a10 * s; 40 | out[9] = a21 * c - a11 * s; 41 | out[10] = a22 * c - a12 * s; 42 | out[11] = a23 * c - a13 * s; 43 | return out; 44 | }; -------------------------------------------------------------------------------- /rotateY.js: -------------------------------------------------------------------------------- 1 | module.exports = rotateY; 2 | 3 | /** 4 | * Rotates a matrix by the given angle around the Y axis 5 | * 6 | * @param {mat4} out the receiving matrix 7 | * @param {mat4} a the matrix to rotate 8 | * @param {Number} rad the angle to rotate the matrix by 9 | * @returns {mat4} out 10 | */ 11 | function rotateY(out, a, rad) { 12 | var s = Math.sin(rad), 13 | c = Math.cos(rad), 14 | a00 = a[0], 15 | a01 = a[1], 16 | a02 = a[2], 17 | a03 = a[3], 18 | a20 = a[8], 19 | a21 = a[9], 20 | a22 = a[10], 21 | a23 = a[11]; 22 | 23 | if (a !== out) { // If the source and destination differ, copy the unchanged rows 24 | out[4] = a[4]; 25 | out[5] = a[5]; 26 | out[6] = a[6]; 27 | out[7] = a[7]; 28 | out[12] = a[12]; 29 | out[13] = a[13]; 30 | out[14] = a[14]; 31 | out[15] = a[15]; 32 | } 33 | 34 | // Perform axis-specific matrix multiplication 35 | out[0] = a00 * c - a20 * s; 36 | out[1] = a01 * c - a21 * s; 37 | out[2] = a02 * c - a22 * s; 38 | out[3] = a03 * c - a23 * s; 39 | out[8] = a00 * s + a20 * c; 40 | out[9] = a01 * s + a21 * c; 41 | out[10] = a02 * s + a22 * c; 42 | out[11] = a03 * s + a23 * c; 43 | return out; 44 | }; -------------------------------------------------------------------------------- /rotateZ.js: -------------------------------------------------------------------------------- 1 | module.exports = rotateZ; 2 | 3 | /** 4 | * Rotates a matrix by the given angle around the Z axis 5 | * 6 | * @param {mat4} out the receiving matrix 7 | * @param {mat4} a the matrix to rotate 8 | * @param {Number} rad the angle to rotate the matrix by 9 | * @returns {mat4} out 10 | */ 11 | function rotateZ(out, a, rad) { 12 | var s = Math.sin(rad), 13 | c = Math.cos(rad), 14 | a00 = a[0], 15 | a01 = a[1], 16 | a02 = a[2], 17 | a03 = a[3], 18 | a10 = a[4], 19 | a11 = a[5], 20 | a12 = a[6], 21 | a13 = a[7]; 22 | 23 | if (a !== out) { // If the source and destination differ, copy the unchanged last row 24 | out[8] = a[8]; 25 | out[9] = a[9]; 26 | out[10] = a[10]; 27 | out[11] = a[11]; 28 | out[12] = a[12]; 29 | out[13] = a[13]; 30 | out[14] = a[14]; 31 | out[15] = a[15]; 32 | } 33 | 34 | // Perform axis-specific matrix multiplication 35 | out[0] = a00 * c + a10 * s; 36 | out[1] = a01 * c + a11 * s; 37 | out[2] = a02 * c + a12 * s; 38 | out[3] = a03 * c + a13 * s; 39 | out[4] = a10 * c - a00 * s; 40 | out[5] = a11 * c - a01 * s; 41 | out[6] = a12 * c - a02 * s; 42 | out[7] = a13 * c - a03 * s; 43 | return out; 44 | }; -------------------------------------------------------------------------------- /scale.js: -------------------------------------------------------------------------------- 1 | module.exports = scale; 2 | 3 | /** 4 | * Scales the mat4 by the dimensions in the given vec3 5 | * 6 | * @param {mat4} out the receiving matrix 7 | * @param {mat4} a the matrix to scale 8 | * @param {vec3} v the vec3 to scale the matrix by 9 | * @returns {mat4} out 10 | **/ 11 | function scale(out, a, v) { 12 | var x = v[0], y = v[1], z = v[2]; 13 | 14 | out[0] = a[0] * x; 15 | out[1] = a[1] * x; 16 | out[2] = a[2] * x; 17 | out[3] = a[3] * x; 18 | out[4] = a[4] * y; 19 | out[5] = a[5] * y; 20 | out[6] = a[6] * y; 21 | out[7] = a[7] * y; 22 | out[8] = a[8] * z; 23 | out[9] = a[9] * z; 24 | out[10] = a[10] * z; 25 | out[11] = a[11] * z; 26 | out[12] = a[12]; 27 | out[13] = a[13]; 28 | out[14] = a[14]; 29 | out[15] = a[15]; 30 | return out; 31 | }; -------------------------------------------------------------------------------- /str.js: -------------------------------------------------------------------------------- 1 | module.exports = str; 2 | 3 | /** 4 | * Returns a string representation of a mat4 5 | * 6 | * @param {mat4} mat matrix to represent as a string 7 | * @returns {String} string representation of the matrix 8 | */ 9 | function str(a) { 10 | return 'mat4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + 11 | a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' + 12 | a[8] + ', ' + a[9] + ', ' + a[10] + ', ' + a[11] + ', ' + 13 | a[12] + ', ' + a[13] + ', ' + a[14] + ', ' + a[15] + ')'; 14 | }; -------------------------------------------------------------------------------- /sub.js: -------------------------------------------------------------------------------- 1 | module.exports = sub; 2 | 3 | /** 4 | * Subtracts two mat4's 5 | * 6 | * @param {mat4} the first operand 7 | * @param {mat4} the second operand 8 | * @returns {mat4} out 9 | */ 10 | function sub(out, a, b) { 11 | out[0] = a[0] - b[0]; 12 | out[1] = a[1] - b[1]; 13 | out[2] = a[2] - b[2]; 14 | out[3] = a[3] - b[3]; 15 | out[4] = a[4] - b[4]; 16 | out[5] = a[5] - b[5]; 17 | out[6] = a[6] - b[6]; 18 | out[7] = a[7] - b[7]; 19 | out[8] = a[8] - b[8]; 20 | out[9] = a[9] - b[9]; 21 | out[10] = a[10] - b[10]; 22 | out[11] = a[11] - b[11]; 23 | out[12] = a[12] - b[12]; 24 | out[13] = a[13] - b[13]; 25 | out[14] = a[14] - b[14]; 26 | out[15] = a[15] - b[15]; 27 | return out; 28 | }; 29 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | //TODO: move tests from gl-matrix 2 | 3 | console.log( require('../').create() ) -------------------------------------------------------------------------------- /tools/parser.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs') 2 | var path = require('path') 3 | 4 | //TODO: curl this in? 5 | //https://raw.githubusercontent.com/toji/gl-matrix/master/src/gl-matrix/mat4.js 6 | // ^ had to manually remove aliases like 'mul' from the above before parsing 7 | var orig = fs.readFileSync(__dirname+'/original.js', 'utf8') 8 | 9 | //TODO: common module that exports these? 10 | orig = orig.replace(/GLMAT\_EPSILON/g, '0.000001') 11 | .replace(/GLMAT\_ARRAY\_TYPE/g, 'Float32Array') 12 | .replace(/GLMAT\_RANDOM/g, 'Math.random') 13 | 14 | // var block = /(\/\*[^]*?\*\/)/g 15 | // var func = /mat4\.([a-z0-9\-\_]+).*\=.*function/ig 16 | 17 | var intro = 'var mat4 = {};' 18 | var start = orig.indexOf(intro) 19 | if (start===-1) 20 | throw new Error('not valid file') 21 | orig = orig.substring(start+intro.length) 22 | 23 | //matches blocks + function name 24 | var reg = /(\/\*[^]*?\*\/)\s*mat4\.([a-z0-9\-\_]+).*\=.*function/ig 25 | 26 | var match 27 | var start = 0, 28 | end = null, 29 | lastMatch = null 30 | 31 | var allNames = [] 32 | 33 | while (match = reg.exec(orig)) { 34 | if (lastMatch !== null) { 35 | end = match.index 36 | var name = lastMatch[2].trim() 37 | var body = orig.substring( start, end ) 38 | var file = 'module.exports = '+name+';\n\n' 39 | file += lastMatch[1]+'\nfunction '+name+body.trim() 40 | 41 | var filename = name+'.js' 42 | 43 | fs.writeFile(filename, file, function(err) { 44 | if (err) 45 | console.error("Error writing file", filename, err) 46 | }) 47 | allNames.push(name) 48 | } 49 | 50 | start = reg.lastIndex 51 | lastMatch = match 52 | } 53 | 54 | var entry = 'module.exports = {\n' 55 | allNames.forEach(function(name, i) { 56 | entry += ' ' 57 | if (i!==0) 58 | entry += ', ' 59 | entry += name+": require('./"+name+"')\n" 60 | }) 61 | entry += '}' 62 | 63 | fs.writeFile('index.js', entry, function(err) { 64 | if (err) 65 | console.error("Error writing index", err) 66 | }) -------------------------------------------------------------------------------- /translate.js: -------------------------------------------------------------------------------- 1 | module.exports = translate; 2 | 3 | /** 4 | * Translate a mat4 by the given vector 5 | * 6 | * @param {mat4} out the receiving matrix 7 | * @param {mat4} a the matrix to translate 8 | * @param {vec3} v vector to translate by 9 | * @returns {mat4} out 10 | */ 11 | function translate(out, a, v) { 12 | var x = v[0], y = v[1], z = v[2], 13 | a00, a01, a02, a03, 14 | a10, a11, a12, a13, 15 | a20, a21, a22, a23; 16 | 17 | if (a === out) { 18 | out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; 19 | out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; 20 | out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; 21 | out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; 22 | } else { 23 | a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; 24 | a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; 25 | a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; 26 | 27 | out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03; 28 | out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13; 29 | out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23; 30 | 31 | out[12] = a00 * x + a10 * y + a20 * z + a[12]; 32 | out[13] = a01 * x + a11 * y + a21 * z + a[13]; 33 | out[14] = a02 * x + a12 * y + a22 * z + a[14]; 34 | out[15] = a03 * x + a13 * y + a23 * z + a[15]; 35 | } 36 | 37 | return out; 38 | }; -------------------------------------------------------------------------------- /transpose.js: -------------------------------------------------------------------------------- 1 | module.exports = transpose; 2 | 3 | /** 4 | * Transpose the values of a mat4 5 | * 6 | * @param {mat4} out the receiving matrix 7 | * @param {mat4} a the source matrix 8 | * @returns {mat4} out 9 | */ 10 | function transpose(out, a) { 11 | // If we are transposing ourselves we can skip a few steps but have to cache some values 12 | if (out === a) { 13 | var a01 = a[1], a02 = a[2], a03 = a[3], 14 | a12 = a[6], a13 = a[7], 15 | a23 = a[11]; 16 | 17 | out[1] = a[4]; 18 | out[2] = a[8]; 19 | out[3] = a[12]; 20 | out[4] = a01; 21 | out[6] = a[9]; 22 | out[7] = a[13]; 23 | out[8] = a02; 24 | out[9] = a12; 25 | out[11] = a[14]; 26 | out[12] = a03; 27 | out[13] = a13; 28 | out[14] = a23; 29 | } else { 30 | out[0] = a[0]; 31 | out[1] = a[4]; 32 | out[2] = a[8]; 33 | out[3] = a[12]; 34 | out[4] = a[1]; 35 | out[5] = a[5]; 36 | out[6] = a[9]; 37 | out[7] = a[13]; 38 | out[8] = a[2]; 39 | out[9] = a[6]; 40 | out[10] = a[10]; 41 | out[11] = a[14]; 42 | out[12] = a[3]; 43 | out[13] = a[7]; 44 | out[14] = a[11]; 45 | out[15] = a[15]; 46 | } 47 | 48 | return out; 49 | }; --------------------------------------------------------------------------------