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 4 Dimensional Vector
30 * Creates a new, empty vec4
32 * @returns {vec4} a new 4D vector
34 vec4.create = function() {
35 var out = new GLMAT_ARRAY_TYPE(4);
44 * Creates a new vec4 initialized with values from an existing vector
46 * @param {vec4} a vector to clone
47 * @returns {vec4} a new 4D vector
49 vec4.clone = function(a) {
50 var out = new GLMAT_ARRAY_TYPE(4);
59 * Creates a new vec4 initialized with the given values
61 * @param {Number} x X component
62 * @param {Number} y Y component
63 * @param {Number} z Z component
64 * @param {Number} w W component
65 * @returns {vec4} a new 4D vector
67 vec4.fromValues = function(x, y, z, w) {
68 var out = new GLMAT_ARRAY_TYPE(4);
77 * Copy the values from one vec4 to another
79 * @param {vec4} out the receiving vector
80 * @param {vec4} a the source vector
83 vec4.copy = function(out, a) {
92 * Set the components of a vec4 to the given values
94 * @param {vec4} out the receiving vector
95 * @param {Number} x X component
96 * @param {Number} y Y component
97 * @param {Number} z Z component
98 * @param {Number} w W component
101 vec4.set = function(out, x, y, z, w) {
112 * @param {vec4} out the receiving vector
113 * @param {vec4} a the first operand
114 * @param {vec4} b the second operand
115 * @returns {vec4} out
117 vec4.add = function(out, a, b) {
118 out[0] = a[0] + b[0];
119 out[1] = a[1] + b[1];
120 out[2] = a[2] + b[2];
121 out[3] = a[3] + b[3];
126 * Subtracts two vec4's
128 * @param {vec4} out the receiving vector
129 * @param {vec4} a the first operand
130 * @param {vec4} b the second operand
131 * @returns {vec4} out
133 vec4.subtract = function(out, a, b) {
134 out[0] = a[0] - b[0];
135 out[1] = a[1] - b[1];
136 out[2] = a[2] - b[2];
137 out[3] = a[3] - b[3];
142 * Alias for {@link vec4.subtract}
145 vec4.sub = vec4.subtract;
148 * Multiplies two vec4's
150 * @param {vec4} out the receiving vector
151 * @param {vec4} a the first operand
152 * @param {vec4} b the second operand
153 * @returns {vec4} out
155 vec4.multiply = function(out, a, b) {
156 out[0] = a[0] * b[0];
157 out[1] = a[1] * b[1];
158 out[2] = a[2] * b[2];
159 out[3] = a[3] * b[3];
164 * Alias for {@link vec4.multiply}
167 vec4.mul = vec4.multiply;
172 * @param {vec4} out the receiving vector
173 * @param {vec4} a the first operand
174 * @param {vec4} b the second operand
175 * @returns {vec4} out
177 vec4.divide = function(out, a, b) {
178 out[0] = a[0] / b[0];
179 out[1] = a[1] / b[1];
180 out[2] = a[2] / b[2];
181 out[3] = a[3] / b[3];
186 * Alias for {@link vec4.divide}
189 vec4.div = vec4.divide;
192 * Returns the minimum of two vec4's
194 * @param {vec4} out the receiving vector
195 * @param {vec4} a the first operand
196 * @param {vec4} b the second operand
197 * @returns {vec4} out
199 vec4.min = function(out, a, b) {
200 out[0] = Math.min(a[0], b[0]);
201 out[1] = Math.min(a[1], b[1]);
202 out[2] = Math.min(a[2], b[2]);
203 out[3] = Math.min(a[3], b[3]);
208 * Returns the maximum of two vec4's
210 * @param {vec4} out the receiving vector
211 * @param {vec4} a the first operand
212 * @param {vec4} b the second operand
213 * @returns {vec4} out
215 vec4.max = function(out, a, b) {
216 out[0] = Math.max(a[0], b[0]);
217 out[1] = Math.max(a[1], b[1]);
218 out[2] = Math.max(a[2], b[2]);
219 out[3] = Math.max(a[3], b[3]);
224 * Scales a vec4 by a scalar number
226 * @param {vec4} out the receiving vector
227 * @param {vec4} a the vector to scale
228 * @param {Number} b amount to scale the vector by
229 * @returns {vec4} out
231 vec4.scale = function(out, a, b) {
240 * Calculates the euclidian distance between two vec4's
242 * @param {vec4} a the first operand
243 * @param {vec4} b the second operand
244 * @returns {Number} distance between a and b
246 vec4.distance = function(a, b) {
251 return Math.sqrt(x*x + y*y + z*z + w*w);
255 * Alias for {@link vec4.distance}
258 vec4.dist = vec4.distance;
261 * Calculates the squared euclidian distance between two vec4's
263 * @param {vec4} a the first operand
264 * @param {vec4} b the second operand
265 * @returns {Number} squared distance between a and b
267 vec4.squaredDistance = function(a, b) {
272 return x*x + y*y + z*z + w*w;
276 * Alias for {@link vec4.squaredDistance}
279 vec4.sqrDist = vec4.squaredDistance;
282 * Calculates the length of a vec4
284 * @param {vec4} a vector to calculate length of
285 * @returns {Number} length of a
287 vec4.length = function (a) {
292 return Math.sqrt(x*x + y*y + z*z + w*w);
296 * Alias for {@link vec4.length}
299 vec4.len = vec4.length;
302 * Calculates the squared length of a vec4
304 * @param {vec4} a vector to calculate squared length of
305 * @returns {Number} squared length of a
307 vec4.squaredLength = function (a) {
312 return x*x + y*y + z*z + w*w;
316 * Alias for {@link vec4.squaredLength}
319 vec4.sqrLen = vec4.squaredLength;
322 * Negates the components of a vec4
324 * @param {vec4} out the receiving vector
325 * @param {vec4} a vector to negate
326 * @returns {vec4} out
328 vec4.negate = function(out, a) {
339 * @param {vec4} out the receiving vector
340 * @param {vec4} a vector to normalize
341 * @returns {vec4} out
343 vec4.normalize = function(out, a) {
348 var len = x*x + y*y + z*z + w*w;
350 len = 1 / Math.sqrt(len);
360 * Calculates the dot product of two vec4's
362 * @param {vec4} a the first operand
363 * @param {vec4} b the second operand
364 * @returns {Number} dot product of a and b
366 vec4.dot = function (a, b) {
367 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
371 * Performs a linear interpolation between two vec4's
373 * @param {vec4} out the receiving vector
374 * @param {vec4} a the first operand
375 * @param {vec4} b the second operand
376 * @param {Number} t interpolation amount between the two inputs
377 * @returns {vec4} out
379 vec4.lerp = function (out, a, b, t) {
384 out[0] = ax + t * (b[0] - ax);
385 out[1] = ay + t * (b[1] - ay);
386 out[2] = az + t * (b[2] - az);
387 out[3] = aw + t * (b[3] - aw);
392 * Transforms the vec4 with a mat4.
394 * @param {vec4} out the receiving vector
395 * @param {vec4} a the vector to transform
396 * @param {mat4} m matrix to transform with
397 * @returns {vec4} out
399 vec4.transformMat4 = function(out, a, m) {
400 var x = a[0], y = a[1], z = a[2], w = a[3];
401 out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
402 out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
403 out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
404 out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
409 * Transforms the vec4 with a quat
411 * @param {vec4} out the receiving vector
412 * @param {vec4} a the vector to transform
413 * @param {quat} q quaternion to transform with
414 * @returns {vec4} out
416 vec4.transformQuat = function(out, a, q) {
417 var x = a[0], y = a[1], z = a[2],
418 qx = q[0], qy = q[1], qz = q[2], qw = q[3],
420 // calculate quat * vec
421 ix = qw * x + qy * z - qz * y,
422 iy = qw * y + qz * x - qx * z,
423 iz = qw * z + qx * y - qy * x,
424 iw = -qx * x - qy * y - qz * z;
426 // calculate result * inverse quat
427 out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
428 out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
429 out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
434 * Perform some operation over an array of vec4s.
436 * @param {Array} a the array of vectors to iterate over
437 * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed
438 * @param {Number} offset Number of elements to skip at the beginning of the array
439 * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array
440 * @param {Function} fn Function to call for each vector in the array
441 * @param {Object} [arg] additional argument to pass to fn
445 vec4.forEach = (function() {
446 var vec = vec4.create();
448 return function(a, stride, offset, count, fn, arg) {
459 l = Math.min((count * stride) + offset, a.length);
464 for(i = offset; i < l; i += stride) {
465 vec[0] = a[i]; vec[1] = a[i+1]; vec[2] = a[i+2]; vec[3] = a[i+3];
467 a[i] = vec[0]; a[i+1] = vec[1]; a[i+2] = vec[2]; a[i+3] = vec[3];
475 * Returns a string representation of a vector
477 * @param {vec4} vec vector to represent as a string
478 * @returns {String} string representation of the vector
480 vec4.str = function (a) {
481 return 'vec4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
484 if(typeof(exports) !== 'undefined') {