1 /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
3 Redistribution and use in source and binary forms, with or without modification,
4 are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright notice, this
7 list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright notice,
9 this list of conditions and the following disclaimer in the documentation
10 and/or other materials provided with the distribution.
12 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
13 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
16 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
24 * @class 3 Dimensional Vector
30 * Creates a new, empty vec3
32 * @returns {vec3} a new 3D vector
34 vec3.create = function() {
35 var out = new GLMAT_ARRAY_TYPE(3);
43 * Creates a new vec3 initialized with values from an existing vector
45 * @param {vec3} a vector to clone
46 * @returns {vec3} a new 3D vector
48 vec3.clone = function(a) {
49 var out = new GLMAT_ARRAY_TYPE(3);
57 * Creates a new vec3 initialized with the given values
59 * @param {Number} x X component
60 * @param {Number} y Y component
61 * @param {Number} z Z component
62 * @returns {vec3} a new 3D vector
64 vec3.fromValues = function(x, y, z) {
65 var out = new GLMAT_ARRAY_TYPE(3);
73 * Copy the values from one vec3 to another
75 * @param {vec3} out the receiving vector
76 * @param {vec3} a the source vector
79 vec3.copy = function(out, a) {
87 * Set the components of a vec3 to the given values
89 * @param {vec3} out the receiving vector
90 * @param {Number} x X component
91 * @param {Number} y Y component
92 * @param {Number} z Z component
95 vec3.set = function(out, x, y, z) {
105 * @param {vec3} out the receiving vector
106 * @param {vec3} a the first operand
107 * @param {vec3} b the second operand
108 * @returns {vec3} out
110 vec3.add = function(out, a, b) {
111 out[0] = a[0] + b[0];
112 out[1] = a[1] + b[1];
113 out[2] = a[2] + b[2];
118 * Subtracts two vec3's
120 * @param {vec3} out the receiving vector
121 * @param {vec3} a the first operand
122 * @param {vec3} b the second operand
123 * @returns {vec3} out
125 vec3.subtract = function(out, a, b) {
126 out[0] = a[0] - b[0];
127 out[1] = a[1] - b[1];
128 out[2] = a[2] - b[2];
133 * Alias for {@link vec3.subtract}
136 vec3.sub = vec3.subtract;
139 * Multiplies two vec3's
141 * @param {vec3} out the receiving vector
142 * @param {vec3} a the first operand
143 * @param {vec3} b the second operand
144 * @returns {vec3} out
146 vec3.multiply = function(out, a, b) {
147 out[0] = a[0] * b[0];
148 out[1] = a[1] * b[1];
149 out[2] = a[2] * b[2];
154 * Alias for {@link vec3.multiply}
157 vec3.mul = vec3.multiply;
162 * @param {vec3} out the receiving vector
163 * @param {vec3} a the first operand
164 * @param {vec3} b the second operand
165 * @returns {vec3} out
167 vec3.divide = function(out, a, b) {
168 out[0] = a[0] / b[0];
169 out[1] = a[1] / b[1];
170 out[2] = a[2] / b[2];
175 * Alias for {@link vec3.divide}
178 vec3.div = vec3.divide;
181 * Returns the minimum of two vec3's
183 * @param {vec3} out the receiving vector
184 * @param {vec3} a the first operand
185 * @param {vec3} b the second operand
186 * @returns {vec3} out
188 vec3.min = function(out, a, b) {
189 out[0] = Math.min(a[0], b[0]);
190 out[1] = Math.min(a[1], b[1]);
191 out[2] = Math.min(a[2], b[2]);
196 * Returns the maximum of two vec3's
198 * @param {vec3} out the receiving vector
199 * @param {vec3} a the first operand
200 * @param {vec3} b the second operand
201 * @returns {vec3} out
203 vec3.max = function(out, a, b) {
204 out[0] = Math.max(a[0], b[0]);
205 out[1] = Math.max(a[1], b[1]);
206 out[2] = Math.max(a[2], b[2]);
211 * Scales a vec3 by a scalar number
213 * @param {vec3} out the receiving vector
214 * @param {vec3} a the vector to scale
215 * @param {Number} b amount to scale the vector by
216 * @returns {vec3} out
218 vec3.scale = function(out, a, b) {
226 * Calculates the euclidian distance between two vec3's
228 * @param {vec3} a the first operand
229 * @param {vec3} b the second operand
230 * @returns {Number} distance between a and b
232 vec3.distance = function(a, b) {
236 return Math.sqrt(x*x + y*y + z*z);
240 * Alias for {@link vec3.distance}
243 vec3.dist = vec3.distance;
246 * Calculates the squared euclidian distance between two vec3's
248 * @param {vec3} a the first operand
249 * @param {vec3} b the second operand
250 * @returns {Number} squared distance between a and b
252 vec3.squaredDistance = function(a, b) {
256 return x*x + y*y + z*z;
260 * Alias for {@link vec3.squaredDistance}
263 vec3.sqrDist = vec3.squaredDistance;
266 * Calculates the length of a vec3
268 * @param {vec3} a vector to calculate length of
269 * @returns {Number} length of a
271 vec3.length = function (a) {
275 return Math.sqrt(x*x + y*y + z*z);
279 * Alias for {@link vec3.length}
282 vec3.len = vec3.length;
285 * Calculates the squared length of a vec3
287 * @param {vec3} a vector to calculate squared length of
288 * @returns {Number} squared length of a
290 vec3.squaredLength = function (a) {
294 return x*x + y*y + z*z;
298 * Alias for {@link vec3.squaredLength}
301 vec3.sqrLen = vec3.squaredLength;
304 * Negates the components of a vec3
306 * @param {vec3} out the receiving vector
307 * @param {vec3} a vector to negate
308 * @returns {vec3} out
310 vec3.negate = function(out, a) {
320 * @param {vec3} out the receiving vector
321 * @param {vec3} a vector to normalize
322 * @returns {vec3} out
324 vec3.normalize = function(out, a) {
328 var len = x*x + y*y + z*z;
330 //TODO: evaluate use of glm_invsqrt here?
331 len = 1 / Math.sqrt(len);
340 * Calculates the dot product of two vec3's
342 * @param {vec3} a the first operand
343 * @param {vec3} b the second operand
344 * @returns {Number} dot product of a and b
346 vec3.dot = function (a, b) {
347 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
351 * Computes the cross product of two vec3's
353 * @param {vec3} out the receiving vector
354 * @param {vec3} a the first operand
355 * @param {vec3} b the second operand
356 * @returns {vec3} out
358 vec3.cross = function(out, a, b) {
359 var ax = a[0], ay = a[1], az = a[2],
360 bx = b[0], by = b[1], bz = b[2];
362 out[0] = ay * bz - az * by;
363 out[1] = az * bx - ax * bz;
364 out[2] = ax * by - ay * bx;
369 * Performs a linear interpolation between two vec3's
371 * @param {vec3} out the receiving vector
372 * @param {vec3} a the first operand
373 * @param {vec3} b the second operand
374 * @param {Number} t interpolation amount between the two inputs
375 * @returns {vec3} out
377 vec3.lerp = function (out, a, b, t) {
381 out[0] = ax + t * (b[0] - ax);
382 out[1] = ay + t * (b[1] - ay);
383 out[2] = az + t * (b[2] - az);
388 * Transforms the vec3 with a mat4.
389 * 4th vector component is implicitly '1'
391 * @param {vec3} out the receiving vector
392 * @param {vec3} a the vector to transform
393 * @param {mat4} m matrix to transform with
394 * @returns {vec3} out
396 vec3.transformMat4 = function(out, a, m) {
397 var x = a[0], y = a[1], z = a[2];
398 out[0] = m[0] * x + m[4] * y + m[8] * z + m[12];
399 out[1] = m[1] * x + m[5] * y + m[9] * z + m[13];
400 out[2] = m[2] * x + m[6] * y + m[10] * z + m[14];
405 * Transforms the vec3 with a quat
407 * @param {vec3} out the receiving vector
408 * @param {vec3} a the vector to transform
409 * @param {quat} q quaternion to transform with
410 * @returns {vec3} out
412 vec3.transformQuat = function(out, a, q) {
413 var x = a[0], y = a[1], z = a[2],
414 qx = q[0], qy = q[1], qz = q[2], qw = q[3],
416 // calculate quat * vec
417 ix = qw * x + qy * z - qz * y,
418 iy = qw * y + qz * x - qx * z,
419 iz = qw * z + qx * y - qy * x,
420 iw = -qx * x - qy * y - qz * z;
422 // calculate result * inverse quat
423 out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
424 out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
425 out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
430 * Perform some operation over an array of vec3s.
432 * @param {Array} a the array of vectors to iterate over
433 * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed
434 * @param {Number} offset Number of elements to skip at the beginning of the array
435 * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array
436 * @param {Function} fn Function to call for each vector in the array
437 * @param {Object} [arg] additional argument to pass to fn
441 vec3.forEach = (function() {
442 var vec = vec3.create();
444 return function(a, stride, offset, count, fn, arg) {
455 l = Math.min((count * stride) + offset, a.length);
460 for(i = offset; i < l; i += stride) {
461 vec[0] = a[i]; vec[1] = a[i+1]; vec[2] = a[i+2];
463 a[i] = vec[0]; a[i+1] = vec[1]; a[i+2] = vec[2];
471 * Returns a string representation of a vector
473 * @param {vec3} vec vector to represent as a string
474 * @returns {String} string representation of the vector
476 vec3.str = function (a) {
477 return 'vec3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ')';
480 if(typeof(exports) !== 'undefined') {