├── .gitignore ├── .npmignore ├── LICENSE.md ├── README.md ├── add.js ├── angle.js ├── ceil.js ├── clone.js ├── copy.js ├── create.js ├── cross.js ├── dist.js ├── distance.js ├── div.js ├── divide.js ├── dot.js ├── epsilon.js ├── equals.js ├── exactEquals.js ├── floor.js ├── forEach.js ├── fromValues.js ├── index.js ├── inverse.js ├── len.js ├── length.js ├── lerp.js ├── max.js ├── min.js ├── mul.js ├── multiply.js ├── negate.js ├── normalize.js ├── package.json ├── random.js ├── rotateX.js ├── rotateY.js ├── rotateZ.js ├── round.js ├── scale.js ├── scaleAndAdd.js ├── set.js ├── sqrDist.js ├── sqrLen.js ├── squaredDistance.js ├── squaredLength.js ├── sub.js ├── subtract.js ├── test └── index.js ├── transformMat3.js ├── transformMat4.js └── transformQuat.js /.gitignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | node_modules 3 | *.log 4 | .DS_Store 5 | bundle.js 6 | tools/original.js 7 | README.stub.md 8 | tools/** -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | node_modules 3 | *.log 4 | .DS_Store 5 | bundle.js 6 | test 7 | test.js 8 | demo/ 9 | tools/ 10 | 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-vec3 2 | 3 | [![stable](http://badges.github.io/stability-badges/dist/stable.svg)](http://github.com/badges/stability-badges) 4 | 5 | Part of a fork of [@toji](http://github.com/toji)'s 6 | [gl-matrix](http://github.com/toji/gl-matrix) split into smaller pieces: this 7 | package contains `glMatrix.vec3`. 8 | 9 | ## Usage 10 | 11 | [![NPM](https://nodei.co/npm/gl-vec3.png)](https://nodei.co/npm/gl-vec3/) 12 | 13 | ### `vec3 = require('gl-vec3')` 14 | 15 | Will load all of the module's functionality and expose it on a single 16 | object. Note that any of the methods may also be required directly 17 | from their files. 18 | 19 | For example, the following are equivalent: 20 | 21 | ``` javascript 22 | var scale = require('gl-vec3').scale 23 | var scale = require('gl-vec3/scale') 24 | ``` 25 | 26 | ## API 27 | 28 | - [add()](#addoutvec3-avec3-bvec3) 29 | - [angle()](#angleavec3-bvec3) 30 | - [clone()](#cloneavec3) 31 | - [ceil()](#ceiloutvec3-avec3) 32 | - [copy()](#copyoutvec3-avec3) 33 | - [create()](#create) 34 | - [cross()](#crossoutvec3-avec3-bvec3) 35 | - [distance()](#distanceavec3-bvec3) 36 | - [dist()](#distanceavec3-bvec3) 37 | - [divide()](#divideoutvec3-avec3-bvec3) 38 | - [div()](#divideoutvec3-avec3-bvec3) 39 | - [dot()](#dotavec3-bvec3) 40 | - [equals()](#equalsavec3-bvec3) 41 | - [exactEquals()](#exactequalsavec3-bvec3) 42 | - [floor()](#flooroutvec3-avec3) 43 | - [forEach()](#foreachaarray-stridenumber-offsetnumber-countnumber-fnfunction-argobject) 44 | - [fromValues()](#fromvaluesxnumber-ynumber-znumber) 45 | - [inverse()](#inverseoutvec3-avec3) 46 | - [length()](#lengthavec3) 47 | - [len()](#lengthavec3) 48 | - [lerp()](#lerpoutvec3-avec3-bvec3-tnumber) 49 | - [max()](#maxoutvec3-avec3-bvec3) 50 | - [min()](#minoutvec3-avec3-bvec3) 51 | - [multiply()](#multiplyoutvec3-avec3-bvec3) 52 | - [mul()](#multiplyoutvec3-avec3-bvec3) 53 | - [negate()](#negateoutvec3-avec3) 54 | - [normalize()](#normalizeoutvec3-avec3) 55 | - [random()](#randomoutvec3-scalenumber) 56 | - [rotateX()](#rotatexoutvec3-avec3-bvec3-cnumber) 57 | - [rotateY()](#rotateyoutvec3-avec3-bvec3-cnumber) 58 | - [rotateZ()](#rotatezoutvec3-avec3-bvec3-cnumber) 59 | - [round()](#roundoutvec3-avec3) 60 | - [scale()](#scaleoutvec3-avec3-bnumber) 61 | - [scaleAndAdd()](#scaleandaddoutvec3-avec3-bvec3-scalenumber) 62 | - [set()](#setoutvec3-xnumber-ynumber-znumber) 63 | - [squaredDistance()](#squareddistanceavec3-bvec3) 64 | - [sqrDist()](#squareddistanceavec3-bvec3) 65 | - [squaredLength()](#squaredlengthavec3) 66 | - [sqrLen()](#squaredlengthavec3) 67 | - [subtract()](#subtractoutvec3-avec3-bvec3) 68 | - [sub()](#subtractoutvec3-avec3-bvec3) 69 | - [transformMat3()](#transformmat3outvec3-avec3-mmat3) 70 | - [transformMat4()](#transformmat4outvec3-avec3-mmat4) 71 | - [transformQuat()](#transformquatoutvec3-avec3-qquat) 72 | 73 | ## add(out:vec3, a:vec3, b:vec3) 74 | 75 | Adds two vec3's 76 | 77 | ## angle(a:vec3, b:vec3) 78 | 79 | Get the angle between two 3D vectors 80 | 81 | ## ceil(out:vec3, a:vec3) 82 | 83 | `Math.ceil` the components of a vec3 84 | 85 | ## clone(a:vec3) 86 | 87 | Creates a new vec3 initialized with values from an existing vector 88 | 89 | ## copy(out:vec3, a:vec3) 90 | 91 | Copy the values from one vec3 to another 92 | 93 | ## create() 94 | 95 | Creates a new, empty vec3 96 | 97 | ## cross(out:vec3, a:vec3, b:vec3) 98 | 99 | Computes the cross product of two vec3's 100 | 101 | ## distance(a:vec3, b:vec3) 102 | 103 | Calculates the euclidian distance between two vec3's. Aliased as `dist` 104 | 105 | ## divide(out:vec3, a:vec3, b:vec3) 106 | 107 | Divides two vec3's. Aliased as `div` 108 | 109 | ## dot(a:vec3, b:vec3) 110 | 111 | Calculates the dot product of two vec3's 112 | 113 | ## equals(a:vec3, b:vec3) 114 | 115 | Returns whether or not the vectors have approximately the same elements in the same position. 116 | 117 | ## exactEquals(a:vec3, b:vec3) 118 | 119 | Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===) 120 | 121 | ## floor(out:vec3, a:vec3) 122 | 123 | `Math.floor` the components of a vec3 124 | 125 | ## forEach(a:Array, stride:Number, offset:Number, count:Number, fn:Function, [arg]:Object) 126 | 127 | Perform some operation over an array of vec3s. 128 | 129 | ## fromValues(x:Number, y:Number, z:Number) 130 | 131 | Creates a new vec3 initialized with the given values 132 | 133 | ## inverse(out:vec3, a:vec3) 134 | 135 | Returns the inverse of the components of a vec3 136 | 137 | ## length(a:vec3) 138 | 139 | Calculates the length of a vec3. Aliased as `len` 140 | 141 | ## lerp(out:vec3, a:vec3, b:vec3, t:Number) 142 | 143 | Performs a linear interpolation between two vec3's 144 | 145 | ## max(out:vec3, a:vec3, b:vec3) 146 | 147 | Returns the maximum of two vec3's 148 | 149 | ## min(out:vec3, a:vec3, b:vec3) 150 | 151 | Returns the minimum of two vec3's 152 | 153 | ## multiply(out:vec3, a:vec3, b:vec3) 154 | 155 | Multiplies two vec3's. Aliased as `mul` 156 | 157 | ## negate(out:vec3, a:vec3) 158 | 159 | Negates the components of a vec3 160 | 161 | ## normalize(out:vec3, a:vec3) 162 | 163 | Normalize a vec3 164 | 165 | ## random(out:vec3, [scale]:Number) 166 | 167 | Generates a random vector with the given scale 168 | 169 | ## rotateX(out:vec3, a:vec3, b:vec3, c:Number) 170 | 171 | Rotate a 3D vector around the x-axis 172 | 173 | ## rotateY(out:vec3, a:vec3, b:vec3, c:Number) 174 | 175 | Rotate a 3D vector around the y-axis 176 | 177 | ## rotateZ(out:vec3, a:vec3, b:vec3, c:Number) 178 | 179 | Rotate a 3D vector around the z-axis 180 | 181 | ## round(out:vec3, a:vec3) 182 | 183 | `Math.round` the components of a vec3 184 | 185 | ## scale(out:vec3, a:vec3, b:Number) 186 | 187 | Scales a vec3 by a scalar number 188 | 189 | ## scaleAndAdd(out:vec3, a:vec3, b:vec3, scale:Number) 190 | 191 | Adds two vec3's after scaling the second operand by a scalar value 192 | 193 | ## set(out:vec3, x:Number, y:Number, z:Number) 194 | 195 | Set the components of a vec3 to the given values 196 | 197 | ## squaredDistance(a:vec3, b:vec3) 198 | 199 | Calculates the squared euclidian distance between two vec3's. Aliased as `sqrDist` 200 | 201 | ## squaredLength(a:vec3) 202 | 203 | Calculates the squared length of a vec3. Aliased as `sqrLen` 204 | 205 | ## subtract(out:vec3, a:vec3, b:vec3) 206 | 207 | Subtracts vector b from vector a. Aliased as `sub` 208 | 209 | ## transformMat3(out:vec3, a:vec3, m:mat3) 210 | 211 | Transforms the vec3 with a mat3. 212 | 213 | ## transformMat4(out:vec3, a:vec3, m:mat4) 214 | 215 | Transforms the vec3 with a mat4. 216 | 4th vector component is implicitly '1' 217 | 218 | ## transformQuat(out:vec3, a:vec3, q:quat) 219 | 220 | Transforms the vec3 with a quat 221 | 222 | ## License 223 | 224 | [zlib](http://en.wikipedia.org/wiki/Zlib_License). See [LICENSE.md](https://github.com/stackgl/gl-vec3/blob/master/LICENSE.md) for details. 225 | -------------------------------------------------------------------------------- /add.js: -------------------------------------------------------------------------------- 1 | module.exports = add; 2 | 3 | /** 4 | * Adds two vec3's 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a the first operand 8 | * @param {vec3} b the second operand 9 | * @returns {vec3} out 10 | */ 11 | function add(out, a, b) { 12 | out[0] = a[0] + b[0] 13 | out[1] = a[1] + b[1] 14 | out[2] = a[2] + b[2] 15 | return out 16 | } -------------------------------------------------------------------------------- /angle.js: -------------------------------------------------------------------------------- 1 | module.exports = angle 2 | 3 | var fromValues = require('./fromValues') 4 | var normalize = require('./normalize') 5 | var dot = require('./dot') 6 | 7 | /** 8 | * Get the angle between two 3D vectors 9 | * @param {vec3} a The first operand 10 | * @param {vec3} b The second operand 11 | * @returns {Number} The angle in radians 12 | */ 13 | function angle(a, b) { 14 | var tempA = fromValues(a[0], a[1], a[2]) 15 | var tempB = fromValues(b[0], b[1], b[2]) 16 | 17 | normalize(tempA, tempA) 18 | normalize(tempB, tempB) 19 | 20 | var cosine = dot(tempA, tempB) 21 | 22 | if(cosine > 1.0){ 23 | return 0 24 | } else { 25 | return Math.acos(cosine) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ceil.js: -------------------------------------------------------------------------------- 1 | module.exports = ceil 2 | 3 | /** 4 | * Math.ceil the components of a vec3 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a vector to ceil 8 | * @returns {vec3} out 9 | */ 10 | function ceil(out, a) { 11 | out[0] = Math.ceil(a[0]) 12 | out[1] = Math.ceil(a[1]) 13 | out[2] = Math.ceil(a[2]) 14 | return out 15 | } 16 | -------------------------------------------------------------------------------- /clone.js: -------------------------------------------------------------------------------- 1 | module.exports = clone; 2 | 3 | /** 4 | * Creates a new vec3 initialized with values from an existing vector 5 | * 6 | * @param {vec3} a vector to clone 7 | * @returns {vec3} a new 3D vector 8 | */ 9 | function clone(a) { 10 | var out = new Float32Array(3) 11 | out[0] = a[0] 12 | out[1] = a[1] 13 | out[2] = a[2] 14 | return out 15 | } -------------------------------------------------------------------------------- /copy.js: -------------------------------------------------------------------------------- 1 | module.exports = copy; 2 | 3 | /** 4 | * Copy the values from one vec3 to another 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a the source vector 8 | * @returns {vec3} out 9 | */ 10 | function copy(out, a) { 11 | out[0] = a[0] 12 | out[1] = a[1] 13 | out[2] = a[2] 14 | return out 15 | } -------------------------------------------------------------------------------- /create.js: -------------------------------------------------------------------------------- 1 | module.exports = create; 2 | 3 | /** 4 | * Creates a new, empty vec3 5 | * 6 | * @returns {vec3} a new 3D vector 7 | */ 8 | function create() { 9 | var out = new Float32Array(3) 10 | out[0] = 0 11 | out[1] = 0 12 | out[2] = 0 13 | return out 14 | } -------------------------------------------------------------------------------- /cross.js: -------------------------------------------------------------------------------- 1 | module.exports = cross; 2 | 3 | /** 4 | * Computes the cross product of two vec3's 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a the first operand 8 | * @param {vec3} b the second operand 9 | * @returns {vec3} out 10 | */ 11 | function cross(out, a, b) { 12 | var ax = a[0], ay = a[1], az = a[2], 13 | bx = b[0], by = b[1], bz = b[2] 14 | 15 | out[0] = ay * bz - az * by 16 | out[1] = az * bx - ax * bz 17 | out[2] = ax * by - ay * bx 18 | return out 19 | } -------------------------------------------------------------------------------- /dist.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./distance') 2 | -------------------------------------------------------------------------------- /distance.js: -------------------------------------------------------------------------------- 1 | module.exports = distance; 2 | 3 | /** 4 | * Calculates the euclidian distance between two vec3's 5 | * 6 | * @param {vec3} a the first operand 7 | * @param {vec3} b the second operand 8 | * @returns {Number} distance between a and b 9 | */ 10 | function distance(a, b) { 11 | var x = b[0] - a[0], 12 | y = b[1] - a[1], 13 | z = b[2] - a[2] 14 | return Math.sqrt(x*x + y*y + z*z) 15 | } -------------------------------------------------------------------------------- /div.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./divide') 2 | -------------------------------------------------------------------------------- /divide.js: -------------------------------------------------------------------------------- 1 | module.exports = divide; 2 | 3 | /** 4 | * Divides two vec3's 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a the first operand 8 | * @param {vec3} b the second operand 9 | * @returns {vec3} out 10 | */ 11 | function divide(out, a, b) { 12 | out[0] = a[0] / b[0] 13 | out[1] = a[1] / b[1] 14 | out[2] = a[2] / b[2] 15 | return out 16 | } -------------------------------------------------------------------------------- /dot.js: -------------------------------------------------------------------------------- 1 | module.exports = dot; 2 | 3 | /** 4 | * Calculates the dot product of two vec3's 5 | * 6 | * @param {vec3} a the first operand 7 | * @param {vec3} b the second operand 8 | * @returns {Number} dot product of a and b 9 | */ 10 | function dot(a, b) { 11 | return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] 12 | } -------------------------------------------------------------------------------- /epsilon.js: -------------------------------------------------------------------------------- 1 | module.exports = 0.000001 2 | -------------------------------------------------------------------------------- /equals.js: -------------------------------------------------------------------------------- 1 | module.exports = equals 2 | 3 | var EPSILON = require('./epsilon') 4 | 5 | /** 6 | * Returns whether or not the vectors have approximately the same elements in the same position. 7 | * 8 | * @param {vec3} a The first vector. 9 | * @param {vec3} b The second vector. 10 | * @returns {Boolean} True if the vectors are equal, false otherwise. 11 | */ 12 | function equals(a, b) { 13 | var a0 = a[0] 14 | var a1 = a[1] 15 | var a2 = a[2] 16 | var b0 = b[0] 17 | var b1 = b[1] 18 | var b2 = b[2] 19 | return (Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && 20 | Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && 21 | Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2))) 22 | } 23 | -------------------------------------------------------------------------------- /exactEquals.js: -------------------------------------------------------------------------------- 1 | module.exports = exactEquals 2 | 3 | /** 4 | * Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===) 5 | * 6 | * @param {vec3} a The first vector. 7 | * @param {vec3} b The second vector. 8 | * @returns {Boolean} True if the vectors are equal, false otherwise. 9 | */ 10 | function exactEquals(a, b) { 11 | return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] 12 | } 13 | -------------------------------------------------------------------------------- /floor.js: -------------------------------------------------------------------------------- 1 | module.exports = floor 2 | 3 | /** 4 | * Math.floor the components of a vec3 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a vector to floor 8 | * @returns {vec3} out 9 | */ 10 | function floor(out, a) { 11 | out[0] = Math.floor(a[0]) 12 | out[1] = Math.floor(a[1]) 13 | out[2] = Math.floor(a[2]) 14 | return out 15 | } 16 | -------------------------------------------------------------------------------- /forEach.js: -------------------------------------------------------------------------------- 1 | module.exports = forEach; 2 | 3 | var vec = require('./create')() 4 | 5 | /** 6 | * Perform some operation over an array of vec3s. 7 | * 8 | * @param {Array} a the array of vectors to iterate over 9 | * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed 10 | * @param {Number} offset Number of elements to skip at the beginning of the array 11 | * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array 12 | * @param {Function} fn Function to call for each vector in the array 13 | * @param {Object} [arg] additional argument to pass to fn 14 | * @returns {Array} a 15 | * @function 16 | */ 17 | function forEach(a, stride, offset, count, fn, arg) { 18 | var i, l 19 | if(!stride) { 20 | stride = 3 21 | } 22 | 23 | if(!offset) { 24 | offset = 0 25 | } 26 | 27 | if(count) { 28 | l = Math.min((count * stride) + offset, a.length) 29 | } else { 30 | l = a.length 31 | } 32 | 33 | for(i = offset; i < l; i += stride) { 34 | vec[0] = a[i] 35 | vec[1] = a[i+1] 36 | vec[2] = a[i+2] 37 | fn(vec, vec, arg) 38 | a[i] = vec[0] 39 | a[i+1] = vec[1] 40 | a[i+2] = vec[2] 41 | } 42 | 43 | return a 44 | } -------------------------------------------------------------------------------- /fromValues.js: -------------------------------------------------------------------------------- 1 | module.exports = fromValues; 2 | 3 | /** 4 | * Creates a new vec3 initialized with the given values 5 | * 6 | * @param {Number} x X component 7 | * @param {Number} y Y component 8 | * @param {Number} z Z component 9 | * @returns {vec3} a new 3D vector 10 | */ 11 | function fromValues(x, y, z) { 12 | var out = new Float32Array(3) 13 | out[0] = x 14 | out[1] = y 15 | out[2] = z 16 | return out 17 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | EPSILON: require('./epsilon') 3 | , create: require('./create') 4 | , clone: require('./clone') 5 | , angle: require('./angle') 6 | , fromValues: require('./fromValues') 7 | , copy: require('./copy') 8 | , set: require('./set') 9 | , equals: require('./equals') 10 | , exactEquals: require('./exactEquals') 11 | , add: require('./add') 12 | , subtract: require('./subtract') 13 | , sub: require('./sub') 14 | , multiply: require('./multiply') 15 | , mul: require('./mul') 16 | , divide: require('./divide') 17 | , div: require('./div') 18 | , min: require('./min') 19 | , max: require('./max') 20 | , floor: require('./floor') 21 | , ceil: require('./ceil') 22 | , round: require('./round') 23 | , scale: require('./scale') 24 | , scaleAndAdd: require('./scaleAndAdd') 25 | , distance: require('./distance') 26 | , dist: require('./dist') 27 | , squaredDistance: require('./squaredDistance') 28 | , sqrDist: require('./sqrDist') 29 | , length: require('./length') 30 | , len: require('./len') 31 | , squaredLength: require('./squaredLength') 32 | , sqrLen: require('./sqrLen') 33 | , negate: require('./negate') 34 | , inverse: require('./inverse') 35 | , normalize: require('./normalize') 36 | , dot: require('./dot') 37 | , cross: require('./cross') 38 | , lerp: require('./lerp') 39 | , random: require('./random') 40 | , transformMat4: require('./transformMat4') 41 | , transformMat3: require('./transformMat3') 42 | , transformQuat: require('./transformQuat') 43 | , rotateX: require('./rotateX') 44 | , rotateY: require('./rotateY') 45 | , rotateZ: require('./rotateZ') 46 | , forEach: require('./forEach') 47 | } 48 | -------------------------------------------------------------------------------- /inverse.js: -------------------------------------------------------------------------------- 1 | module.exports = inverse; 2 | 3 | /** 4 | * Returns the inverse of the components of a vec3 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a vector to invert 8 | * @returns {vec3} out 9 | */ 10 | function inverse(out, a) { 11 | out[0] = 1.0 / a[0] 12 | out[1] = 1.0 / a[1] 13 | out[2] = 1.0 / a[2] 14 | return out 15 | } -------------------------------------------------------------------------------- /len.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./length') 2 | -------------------------------------------------------------------------------- /length.js: -------------------------------------------------------------------------------- 1 | module.exports = length; 2 | 3 | /** 4 | * Calculates the length of a vec3 5 | * 6 | * @param {vec3} a vector to calculate length of 7 | * @returns {Number} length of a 8 | */ 9 | function length(a) { 10 | var x = a[0], 11 | y = a[1], 12 | z = a[2] 13 | return Math.sqrt(x*x + y*y + z*z) 14 | } -------------------------------------------------------------------------------- /lerp.js: -------------------------------------------------------------------------------- 1 | module.exports = lerp; 2 | 3 | /** 4 | * Performs a linear interpolation between two vec3's 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a the first operand 8 | * @param {vec3} b the second operand 9 | * @param {Number} t interpolation amount between the two inputs 10 | * @returns {vec3} out 11 | */ 12 | function lerp(out, a, b, t) { 13 | var ax = a[0], 14 | ay = a[1], 15 | az = a[2] 16 | out[0] = ax + t * (b[0] - ax) 17 | out[1] = ay + t * (b[1] - ay) 18 | out[2] = az + t * (b[2] - az) 19 | return out 20 | } -------------------------------------------------------------------------------- /max.js: -------------------------------------------------------------------------------- 1 | module.exports = max; 2 | 3 | /** 4 | * Returns the maximum of two vec3's 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a the first operand 8 | * @param {vec3} b the second operand 9 | * @returns {vec3} out 10 | */ 11 | function max(out, a, b) { 12 | out[0] = Math.max(a[0], b[0]) 13 | out[1] = Math.max(a[1], b[1]) 14 | out[2] = Math.max(a[2], b[2]) 15 | return out 16 | } -------------------------------------------------------------------------------- /min.js: -------------------------------------------------------------------------------- 1 | module.exports = min; 2 | 3 | /** 4 | * Returns the minimum of two vec3's 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a the first operand 8 | * @param {vec3} b the second operand 9 | * @returns {vec3} out 10 | */ 11 | function min(out, a, b) { 12 | out[0] = Math.min(a[0], b[0]) 13 | out[1] = Math.min(a[1], b[1]) 14 | out[2] = Math.min(a[2], b[2]) 15 | return out 16 | } -------------------------------------------------------------------------------- /mul.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./multiply') 2 | -------------------------------------------------------------------------------- /multiply.js: -------------------------------------------------------------------------------- 1 | module.exports = multiply; 2 | 3 | /** 4 | * Multiplies two vec3's 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a the first operand 8 | * @param {vec3} b the second operand 9 | * @returns {vec3} out 10 | */ 11 | function multiply(out, a, b) { 12 | out[0] = a[0] * b[0] 13 | out[1] = a[1] * b[1] 14 | out[2] = a[2] * b[2] 15 | return out 16 | } -------------------------------------------------------------------------------- /negate.js: -------------------------------------------------------------------------------- 1 | module.exports = negate; 2 | 3 | /** 4 | * Negates the components of a vec3 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a vector to negate 8 | * @returns {vec3} out 9 | */ 10 | function negate(out, a) { 11 | out[0] = -a[0] 12 | out[1] = -a[1] 13 | out[2] = -a[2] 14 | return out 15 | } -------------------------------------------------------------------------------- /normalize.js: -------------------------------------------------------------------------------- 1 | module.exports = normalize; 2 | 3 | /** 4 | * Normalize a vec3 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a vector to normalize 8 | * @returns {vec3} out 9 | */ 10 | function normalize(out, a) { 11 | var x = a[0], 12 | y = a[1], 13 | z = a[2] 14 | var len = x*x + y*y + z*z 15 | if (len > 0) { 16 | //TODO: evaluate use of glm_invsqrt here? 17 | len = 1 / Math.sqrt(len) 18 | out[0] = a[0] * len 19 | out[1] = a[1] * len 20 | out[2] = a[2] * len 21 | } 22 | return out 23 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gl-vec3", 3 | "version": "1.1.3", 4 | "description": "gl-matrix's vec3, split into smaller pieces", 5 | "main": "index.js", 6 | "license": { 7 | "type": "zlib", 8 | "url": "http://github.com/stackgl/gl-vec3/blob/master/LICENSE.md" 9 | }, 10 | "contributors": [ 11 | "Brandon Jones ", 12 | "Colin MacKenzie IV " 13 | ], 14 | "dependencies": {}, 15 | "devDependencies": { 16 | "dox": "git://github.com/hughsk/dox#api-context", 17 | "tape": "^4.8.0" 18 | }, 19 | "scripts": { 20 | "get-docs": "cat *.js | dox --api", 21 | "test": "node test/index.js" 22 | }, 23 | "keywords": [ 24 | "gl-matrix", 25 | "matrix", 26 | "math", 27 | "gl", 28 | "vec3", 29 | "vec", 30 | "3d", 31 | "vector", 32 | "maths", 33 | "add", 34 | "angle", 35 | "clone", 36 | "copy", 37 | "create", 38 | "cross", 39 | "distance", 40 | "divide", 41 | "dot", 42 | "forEach", 43 | "fromValues", 44 | "inverse", 45 | "length", 46 | "lerp", 47 | "max", 48 | "min", 49 | "multiply", 50 | "negate", 51 | "normalize", 52 | "random", 53 | "rotateX", 54 | "rotateY", 55 | "rotateZ", 56 | "scale", 57 | "scaleAndAdd", 58 | "set", 59 | "squaredDistance", 60 | "squaredLength", 61 | "subtract", 62 | "transformMat3", 63 | "transformMat4", 64 | "transformQuat" 65 | ], 66 | "repository": { 67 | "type": "git", 68 | "url": "git://github.com/stackgl/gl-vec3.git" 69 | }, 70 | "homepage": "https://github.com/stackgl/gl-vec3", 71 | "bugs": { 72 | "url": "https://github.com/stackgl/gl-vec3/issues" 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /random.js: -------------------------------------------------------------------------------- 1 | module.exports = random; 2 | 3 | /** 4 | * Generates a random vector with the given scale 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned 8 | * @returns {vec3} out 9 | */ 10 | function random(out, scale) { 11 | scale = scale || 1.0 12 | 13 | var r = Math.random() * 2.0 * Math.PI 14 | var z = (Math.random() * 2.0) - 1.0 15 | var zScale = Math.sqrt(1.0-z*z) * scale 16 | 17 | out[0] = Math.cos(r) * zScale 18 | out[1] = Math.sin(r) * zScale 19 | out[2] = z * scale 20 | return out 21 | } -------------------------------------------------------------------------------- /rotateX.js: -------------------------------------------------------------------------------- 1 | module.exports = rotateX; 2 | 3 | /** 4 | * Rotate a 3D vector around the x-axis 5 | * @param {vec3} out The receiving vec3 6 | * @param {vec3} a The vec3 point to rotate 7 | * @param {vec3} b The origin of the rotation 8 | * @param {Number} c The angle of rotation 9 | * @returns {vec3} out 10 | */ 11 | function rotateX(out, a, b, c){ 12 | var by = b[1] 13 | var bz = b[2] 14 | 15 | // Translate point to the origin 16 | var py = a[1] - by 17 | var pz = a[2] - bz 18 | 19 | var sc = Math.sin(c) 20 | var cc = Math.cos(c) 21 | 22 | // perform rotation and translate to correct position 23 | out[0] = a[0] 24 | out[1] = by + py * cc - pz * sc 25 | out[2] = bz + py * sc + pz * cc 26 | 27 | return out 28 | } 29 | -------------------------------------------------------------------------------- /rotateY.js: -------------------------------------------------------------------------------- 1 | module.exports = rotateY; 2 | 3 | /** 4 | * Rotate a 3D vector around the y-axis 5 | * @param {vec3} out The receiving vec3 6 | * @param {vec3} a The vec3 point to rotate 7 | * @param {vec3} b The origin of the rotation 8 | * @param {Number} c The angle of rotation 9 | * @returns {vec3} out 10 | */ 11 | function rotateY(out, a, b, c){ 12 | var bx = b[0] 13 | var bz = b[2] 14 | 15 | // translate point to the origin 16 | var px = a[0] - bx 17 | var pz = a[2] - bz 18 | 19 | var sc = Math.sin(c) 20 | var cc = Math.cos(c) 21 | 22 | // perform rotation and translate to correct position 23 | out[0] = bx + pz * sc + px * cc 24 | out[1] = a[1] 25 | out[2] = bz + pz * cc - px * sc 26 | 27 | return out 28 | } 29 | -------------------------------------------------------------------------------- /rotateZ.js: -------------------------------------------------------------------------------- 1 | module.exports = rotateZ; 2 | 3 | /** 4 | * Rotate a 3D vector around the z-axis 5 | * @param {vec3} out The receiving vec3 6 | * @param {vec3} a The vec3 point to rotate 7 | * @param {vec3} b The origin of the rotation 8 | * @param {Number} c The angle of rotation 9 | * @returns {vec3} out 10 | */ 11 | function rotateZ(out, a, b, c){ 12 | var bx = b[0] 13 | var by = b[1] 14 | 15 | //Translate point to the origin 16 | var px = a[0] - bx 17 | var py = a[1] - by 18 | 19 | var sc = Math.sin(c) 20 | var cc = Math.cos(c) 21 | 22 | // perform rotation and translate to correct position 23 | out[0] = bx + px * cc - py * sc 24 | out[1] = by + px * sc + py * cc 25 | out[2] = a[2] 26 | 27 | return out 28 | } 29 | -------------------------------------------------------------------------------- /round.js: -------------------------------------------------------------------------------- 1 | module.exports = round 2 | 3 | /** 4 | * Math.round the components of a vec3 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a vector to round 8 | * @returns {vec3} out 9 | */ 10 | function round(out, a) { 11 | out[0] = Math.round(a[0]) 12 | out[1] = Math.round(a[1]) 13 | out[2] = Math.round(a[2]) 14 | return out 15 | } 16 | -------------------------------------------------------------------------------- /scale.js: -------------------------------------------------------------------------------- 1 | module.exports = scale; 2 | 3 | /** 4 | * Scales a vec3 by a scalar number 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a the vector to scale 8 | * @param {Number} b amount to scale the vector by 9 | * @returns {vec3} out 10 | */ 11 | function scale(out, a, b) { 12 | out[0] = a[0] * b 13 | out[1] = a[1] * b 14 | out[2] = a[2] * b 15 | return out 16 | } -------------------------------------------------------------------------------- /scaleAndAdd.js: -------------------------------------------------------------------------------- 1 | module.exports = scaleAndAdd; 2 | 3 | /** 4 | * Adds two vec3's after scaling the second operand by a scalar value 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a the first operand 8 | * @param {vec3} b the second operand 9 | * @param {Number} scale the amount to scale b by before adding 10 | * @returns {vec3} out 11 | */ 12 | function scaleAndAdd(out, a, b, scale) { 13 | out[0] = a[0] + (b[0] * scale) 14 | out[1] = a[1] + (b[1] * scale) 15 | out[2] = a[2] + (b[2] * scale) 16 | return out 17 | } -------------------------------------------------------------------------------- /set.js: -------------------------------------------------------------------------------- 1 | module.exports = set; 2 | 3 | /** 4 | * Set the components of a vec3 to the given values 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {Number} x X component 8 | * @param {Number} y Y component 9 | * @param {Number} z Z component 10 | * @returns {vec3} out 11 | */ 12 | function set(out, x, y, z) { 13 | out[0] = x 14 | out[1] = y 15 | out[2] = z 16 | return out 17 | } -------------------------------------------------------------------------------- /sqrDist.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./squaredDistance') 2 | -------------------------------------------------------------------------------- /sqrLen.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./squaredLength') 2 | -------------------------------------------------------------------------------- /squaredDistance.js: -------------------------------------------------------------------------------- 1 | module.exports = squaredDistance; 2 | 3 | /** 4 | * Calculates the squared euclidian distance between two vec3's 5 | * 6 | * @param {vec3} a the first operand 7 | * @param {vec3} b the second operand 8 | * @returns {Number} squared distance between a and b 9 | */ 10 | function squaredDistance(a, b) { 11 | var x = b[0] - a[0], 12 | y = b[1] - a[1], 13 | z = b[2] - a[2] 14 | return x*x + y*y + z*z 15 | } -------------------------------------------------------------------------------- /squaredLength.js: -------------------------------------------------------------------------------- 1 | module.exports = squaredLength; 2 | 3 | /** 4 | * Calculates the squared length of a vec3 5 | * 6 | * @param {vec3} a vector to calculate squared length of 7 | * @returns {Number} squared length of a 8 | */ 9 | function squaredLength(a) { 10 | var x = a[0], 11 | y = a[1], 12 | z = a[2] 13 | return x*x + y*y + z*z 14 | } -------------------------------------------------------------------------------- /sub.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./subtract') 2 | -------------------------------------------------------------------------------- /subtract.js: -------------------------------------------------------------------------------- 1 | module.exports = subtract; 2 | 3 | /** 4 | * Subtracts vector b from vector a 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a the first operand 8 | * @param {vec3} b the second operand 9 | * @returns {vec3} out 10 | */ 11 | function subtract(out, a, b) { 12 | out[0] = a[0] - b[0] 13 | out[1] = a[1] - b[1] 14 | out[2] = a[2] - b[2] 15 | return out 16 | } -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | var test = require('tape') 2 | var vec3 = require('../') 3 | var EPSILON = require('../epsilon') 4 | 5 | test('add', function (t) { 6 | var result = vec3.add([], [0, 1, 2], [3, 4, 5]) 7 | t.deepEqual(result, [3, 5, 7]) 8 | t.end() 9 | }) 10 | 11 | test('angle', function (t) { 12 | var result = vec3.angle([3, 4, 5], [6, 7, 8]) 13 | t.ok(Math.abs(0.08523986989116927 - result) < EPSILON) 14 | t.end() 15 | }) 16 | 17 | test('ceil', function (t) { 18 | var result = vec3.ceil([], [5.2, 6.5, 7.9]) 19 | t.deepEqual(result, [6, 7, 8]) 20 | t.end() 21 | }) 22 | 23 | test('clone', function (t) { 24 | var result = vec3.clone([5, 6, 7]) 25 | t.deepEqual(result, [5, 6, 7]) 26 | t.end() 27 | }) 28 | 29 | test('copy', function (t) { 30 | var result = vec3.copy([], [5, 6, 7]) 31 | t.deepEqual(result, [5, 6, 7]) 32 | t.end() 33 | }) 34 | 35 | test('create', function (t) { 36 | var result = vec3.create() 37 | t.deepEqual(result, [0, 0, 0]) 38 | t.end() 39 | }) 40 | 41 | test('cross', function (t) { 42 | var result = vec3.cross([], [3, 4, 5], [6, 7, 8]) 43 | t.deepEqual(result, [-3, 6, -3]) 44 | t.end() 45 | }) 46 | 47 | test('distance', function (t) { 48 | var result = vec3.distance([1, 2, 3], [4, 6, 7]) 49 | t.ok(Math.abs(result - 6.4031242374328485) < EPSILON) 50 | t.end() 51 | }) 52 | 53 | test('dist', function (t) { 54 | var result = vec3.dist([1, 2, 3], [4, 6, 7]) 55 | t.ok(Math.abs(result - 6.4031242374328485) < EPSILON) 56 | t.end() 57 | }) 58 | 59 | test('divide', function (t) { 60 | var result = vec3.divide([], [8, 4, 2], [2, 1, 0.5]) 61 | t.deepEqual(result, [4, 4, 4]) 62 | t.end() 63 | }) 64 | 65 | test('div', function (t) { 66 | var result = vec3.div([], [8, 4, 2], [2, 1, 0.5]) 67 | t.deepEqual(result, [4, 4, 4]) 68 | t.end() 69 | }) 70 | 71 | test('dot', function (t) { 72 | var result = vec3.dot([3, 4, 5], [6, 7, 8]) 73 | t.deepEqual(result, 86) 74 | t.end() 75 | }) 76 | 77 | test('equals', function (t) { 78 | t.ok(vec3.equals([3 + EPSILON, 5 - EPSILON, 4 + EPSILON], [3, 5, 4])) 79 | t.notOk(vec3.equals([3 + EPSILON * 10, 5, 4], [3, 5, 4])) 80 | t.notOk(vec3.equals([3, 5 - EPSILON * 10, 4], [3, 5, 4])) 81 | t.notOk(vec3.equals([3, 5, 4 + EPSILON * 10], [3, 5, 4])) 82 | t.end() 83 | }) 84 | 85 | test('exactEquals', function (t) { 86 | t.ok(vec3.exactEquals([3, 5, 4], [3, 5, 4])) 87 | t.notOk(vec3.exactEquals([3 + EPSILON, 5, 4], [3, 5, 4])) 88 | t.notOk(vec3.exactEquals([3, 5 + EPSILON, 4], [3, 5, 4])) 89 | t.notOk(vec3.exactEquals([3, 5, 4 + EPSILON], [3, 5, 4])) 90 | t.end() 91 | }) 92 | 93 | test('floor', function (t) { 94 | var result = vec3.floor([], [5.2, 6.6, 7.9]) 95 | t.deepEqual(result, [5, 6, 7]) 96 | t.end() 97 | }) 98 | 99 | test('forEach', function (t) { 100 | var a = [null, 101 | 0, 1, 2, null, 102 | 3, 4, 5, null 103 | ] 104 | 105 | function addConstant (out, a, val) { 106 | out[0] = a[0] + val 107 | out[1] = a[1] + val 108 | out[2] = a[2] + val 109 | return out 110 | } 111 | 112 | vec3.forEach(a, 4, 1, 2, addConstant, 7) 113 | 114 | t.deepEqual(a, [null, 7, 8, 9, null, 10, 11, 12, null]) 115 | t.end() 116 | }) 117 | 118 | test('fromValues', function (t) { 119 | var result = vec3.fromValues(2, 3, 4) 120 | t.deepEqual(result, [2, 3, 4]) 121 | t.end() 122 | }) 123 | 124 | test('inverse', function (t) { 125 | var result = vec3.inverse([], [2, 4, 8]) 126 | t.deepEqual(result, [0.5, 0.25, 0.125]) 127 | t.end() 128 | }) 129 | 130 | test('length', function (t) { 131 | var result = vec3.length([3, 4, 5]) 132 | t.ok(Math.abs(result - 7.0710678118654755) < EPSILON) 133 | t.end() 134 | }) 135 | 136 | test('len', function (t) { 137 | var result = vec3.len([3, 4, 5]) 138 | t.ok(Math.abs(result - 7.0710678118654755) < EPSILON) 139 | t.end() 140 | }) 141 | 142 | test('lerp', function (t) { 143 | var result = vec3.lerp([], [3, 4, 5], [6, 7, 8], 0.25) 144 | t.deepEqual(result, [3.75, 4.75, 5.75]) 145 | t.end() 146 | }) 147 | 148 | test('max', function (t) { 149 | var result = vec3.max([], [3, 7, 2], [5, 6, 4]) 150 | t.deepEqual(result, [5, 7, 4]) 151 | t.end() 152 | }) 153 | 154 | test('min', function (t) { 155 | var result = vec3.min([], [3, 7, 8], [5, 6, 2]) 156 | t.deepEqual(result, [3, 6, 2]) 157 | t.end() 158 | }) 159 | 160 | test('multiply', function (t) { 161 | var result = vec3.multiply([], [3, 4, 5], [6, 7, 8]) 162 | t.deepEqual(result, [18, 28, 40]) 163 | t.end() 164 | }) 165 | 166 | test('mul', function (t) { 167 | var result = vec3.mul([], [3, 4, 5], [6, 7, 8]) 168 | t.deepEqual(result, [18, 28, 40]) 169 | t.end() 170 | }) 171 | 172 | test('negate', function (t) { 173 | var result = vec3.negate([], [3, 4, 5]) 174 | t.deepEqual(result, [-3, -4, -5]) 175 | t.end() 176 | }) 177 | 178 | test('normalize', function (t) { 179 | var result = vec3.normalize([], [3, 4, 5]) 180 | t.ok(Math.abs(result[0] - 0.4242640687119285) < EPSILON) 181 | t.ok(Math.abs(result[1] - 0.565685424949238) < EPSILON) 182 | t.ok(Math.abs(result[2] - 0.7071067811865475) < EPSILON) 183 | t.end() 184 | }) 185 | 186 | test('random', function (t) { 187 | var result = vec3.random([], 5) 188 | for (var i = 0; i < 10; i++) { 189 | var len = Math.sqrt(result[0] * result[0] + result[1] * result[1] + result[2] * result[2]) 190 | t.ok(Math.abs(5 - len) <= EPSILON) 191 | } 192 | t.end() 193 | }) 194 | 195 | test('rotateX', function (t) { 196 | var result = vec3.rotateX([], [3, 4, 5], [6, 7, 8], Math.PI) 197 | t.deepEqual(result, [3, 10, 11]) 198 | t.end() 199 | }) 200 | 201 | test('rotateY', function (t) { 202 | var result = vec3.rotateY([], [3, 4, 5], [6, 7, 8], Math.PI) 203 | t.deepEqual(result, [9, 4, 11]) 204 | t.end() 205 | }) 206 | 207 | test('rotateZ', function (t) { 208 | var result = vec3.rotateZ([], [3, 4, 5], [6, 7, 8], Math.PI) 209 | t.deepEqual(result, [9, 10, 5]) 210 | t.end() 211 | }) 212 | 213 | test('scale', function (t) { 214 | var result = vec3.scale([], [3, 4, 5], 2) 215 | t.deepEqual(result, [6, 8, 10]) 216 | t.end() 217 | }) 218 | 219 | test('scaleAndAdd', function (t) { 220 | var result = vec3.scaleAndAdd([], [3, 4, 5], [6, 7, 8], 2) 221 | t.deepEqual(result, [15, 18, 21]) 222 | t.end() 223 | }) 224 | 225 | test('round', function (t) { 226 | var result = vec3.round([], [5.2, 6.6, 8.5]) 227 | t.deepEqual(result, [5, 7, 9]) 228 | t.end() 229 | }) 230 | 231 | test('set', function (t) { 232 | var result = vec3.set([], 3, 4, 5) 233 | t.deepEqual(result, [3, 4, 5]) 234 | t.end() 235 | }) 236 | 237 | test('squaredDistance', function (t) { 238 | var result = vec3.squaredDistance([3, 4, 5], [6, 7, 8]) 239 | t.deepEqual(result, 27) 240 | t.end() 241 | }) 242 | 243 | test('sqrDist', function (t) { 244 | var result = vec3.sqrDist([3, 4, 5], [6, 7, 8]) 245 | t.deepEqual(result, 27) 246 | t.end() 247 | }) 248 | 249 | test('squaredLength', function (t) { 250 | var result = vec3.squaredLength([3, 4, 5]) 251 | t.deepEqual(result, 50) 252 | t.end() 253 | }) 254 | 255 | test('sqrLen', function (t) { 256 | var result = vec3.sqrLen([3, 4, 5]) 257 | t.deepEqual(result, 50) 258 | t.end() 259 | }) 260 | 261 | test('subtract', function (t) { 262 | var result = vec3.subtract([], [3, 4, 5], [6, 7, 8]) 263 | t.deepEqual(result, [-3, -3, -3]) 264 | t.end() 265 | }) 266 | 267 | test('sub', function (t) { 268 | var result = vec3.subtract([], [3, 4, 5], [6, 7, 8]) 269 | t.deepEqual(result, [-3, -3, -3]) 270 | t.end() 271 | }) 272 | 273 | test('transformMat3', function (t) { 274 | var result = vec3.transformMat3([], [3, 4, 5], [ 275 | 5, 6, 7, 276 | 8, 9, 10, 277 | 11, 12, 13 278 | ]) 279 | t.deepEqual(result, [102, 114, 126]) 280 | t.end() 281 | }) 282 | 283 | test('transformMat4', function (t) { 284 | var result = vec3.transformMat4([], [3, 4, 5], [ 285 | 5, 6, 7, 8, 286 | 9, 10, 11, 12, 287 | 13, 14, 15, 16, 288 | 17, 18, 19, 20 289 | ]) 290 | t.ok(Math.abs(0.7732558139534884 - result[0]) < EPSILON) 291 | t.ok(Math.abs(0.8488372093023255 - result[1]) < EPSILON) 292 | t.ok(Math.abs(0.9244186046511628 - result[2]) < EPSILON) 293 | t.end() 294 | }) 295 | 296 | test('transformQuat', function (t) { 297 | var result = vec3.transformQuat([], [3, 4, 5], [6, 7, 8, 9]) 298 | t.deepEqual(result, [882, 824, 1090]) 299 | t.end() 300 | }) 301 | -------------------------------------------------------------------------------- /transformMat3.js: -------------------------------------------------------------------------------- 1 | module.exports = transformMat3; 2 | 3 | /** 4 | * Transforms the vec3 with a mat3. 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a the vector to transform 8 | * @param {mat4} m the 3x3 matrix to transform with 9 | * @returns {vec3} out 10 | */ 11 | function transformMat3(out, a, m) { 12 | var x = a[0], y = a[1], z = a[2] 13 | out[0] = x * m[0] + y * m[3] + z * m[6] 14 | out[1] = x * m[1] + y * m[4] + z * m[7] 15 | out[2] = x * m[2] + y * m[5] + z * m[8] 16 | return out 17 | } -------------------------------------------------------------------------------- /transformMat4.js: -------------------------------------------------------------------------------- 1 | module.exports = transformMat4; 2 | 3 | /** 4 | * Transforms the vec3 with a mat4. 5 | * 4th vector component is implicitly '1' 6 | * 7 | * @param {vec3} out the receiving vector 8 | * @param {vec3} a the vector to transform 9 | * @param {mat4} m matrix to transform with 10 | * @returns {vec3} out 11 | */ 12 | function transformMat4(out, a, m) { 13 | var x = a[0], y = a[1], z = a[2], 14 | w = m[3] * x + m[7] * y + m[11] * z + m[15] 15 | w = w || 1.0 16 | out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w 17 | out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w 18 | out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w 19 | return out 20 | } -------------------------------------------------------------------------------- /transformQuat.js: -------------------------------------------------------------------------------- 1 | module.exports = transformQuat; 2 | 3 | /** 4 | * Transforms the vec3 with a quat 5 | * 6 | * @param {vec3} out the receiving vector 7 | * @param {vec3} a the vector to transform 8 | * @param {quat} q quaternion to transform with 9 | * @returns {vec3} out 10 | */ 11 | function transformQuat(out, a, q) { 12 | // benchmarks: http://jsperf.com/quaternion-transform-vec3-implementations 13 | 14 | var x = a[0], y = a[1], z = a[2], 15 | qx = q[0], qy = q[1], qz = q[2], qw = q[3], 16 | 17 | // calculate quat * vec 18 | ix = qw * x + qy * z - qz * y, 19 | iy = qw * y + qz * x - qx * z, 20 | iz = qw * z + qx * y - qy * x, 21 | iw = -qx * x - qy * y - qz * z 22 | 23 | // calculate result * inverse quat 24 | out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy 25 | out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz 26 | out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx 27 | return out 28 | } --------------------------------------------------------------------------------