Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / third_party / tvcm / third_party / gl-matrix / src / gl-matrix / quat.js
1 /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
2
3 Redistribution and use in source and binary forms, with or without modification,
4 are permitted provided that the following conditions are met:
5
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.
11
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. */
22
23 /**
24  * @class Quaternion
25  * @name quat
26  */
27 var quat = {};
28
29 /**
30  * Creates a new identity quat
31  *
32  * @returns {quat} a new quaternion
33  */
34 quat.create = function() {
35     var out = new GLMAT_ARRAY_TYPE(4);
36     out[0] = 0;
37     out[1] = 0;
38     out[2] = 0;
39     out[3] = 1;
40     return out;
41 };
42
43 /**
44  * Creates a new quat initialized with values from an existing quaternion
45  *
46  * @param {quat} a quaternion to clone
47  * @returns {quat} a new quaternion
48  * @function
49  */
50 quat.clone = vec4.clone;
51
52 /**
53  * Creates a new quat initialized with the given values
54  *
55  * @param {Number} x X component
56  * @param {Number} y Y component
57  * @param {Number} z Z component
58  * @param {Number} w W component
59  * @returns {quat} a new quaternion
60  * @function
61  */
62 quat.fromValues = vec4.fromValues;
63
64 /**
65  * Copy the values from one quat to another
66  *
67  * @param {quat} out the receiving quaternion
68  * @param {quat} a the source quaternion
69  * @returns {quat} out
70  * @function
71  */
72 quat.copy = vec4.copy;
73
74 /**
75  * Set the components of a quat to the given values
76  *
77  * @param {quat} out the receiving quaternion
78  * @param {Number} x X component
79  * @param {Number} y Y component
80  * @param {Number} z Z component
81  * @param {Number} w W component
82  * @returns {quat} out
83  * @function
84  */
85 quat.set = vec4.set;
86
87 /**
88  * Set a quat to the identity quaternion
89  *
90  * @param {quat} out the receiving quaternion
91  * @returns {quat} out
92  */
93 quat.identity = function(out) {
94     out[0] = 0;
95     out[1] = 0;
96     out[2] = 0;
97     out[3] = 1;
98     return out;
99 };
100
101 /**
102  * Sets a quat from the given angle and rotation axis,
103  * then returns it.
104  *
105  * @param {quat} out the receiving quaternion
106  * @param {vec3} axis the axis around which to rotate
107  * @param {Number} rad the angle in radians
108  * @returns {quat} out
109  **/
110 quat.setAxisAngle = function(out, axis, rad) {
111     rad = rad * 0.5;
112     var s = Math.sin(rad);
113     out[0] = s * axis[0];
114     out[1] = s * axis[1];
115     out[2] = s * axis[2];
116     out[3] = Math.cos(rad);
117     return out;
118 };
119
120 /**
121  * Adds two quat's
122  *
123  * @param {quat} out the receiving quaternion
124  * @param {quat} a the first operand
125  * @param {quat} b the second operand
126  * @returns {quat} out
127  * @function
128  */
129 quat.add = vec4.add;
130
131 /**
132  * Multiplies two quat's
133  *
134  * @param {quat} out the receiving quaternion
135  * @param {quat} a the first operand
136  * @param {quat} b the second operand
137  * @returns {quat} out
138  */
139 quat.multiply = function(out, a, b) {
140     var ax = a[0], ay = a[1], az = a[2], aw = a[3],
141         bx = b[0], by = b[1], bz = b[2], bw = b[3];
142
143     out[0] = ax * bw + aw * bx + ay * bz - az * by;
144     out[1] = ay * bw + aw * by + az * bx - ax * bz;
145     out[2] = az * bw + aw * bz + ax * by - ay * bx;
146     out[3] = aw * bw - ax * bx - ay * by - az * bz;
147     return out;
148 };
149
150 /**
151  * Alias for {@link quat.multiply}
152  * @function
153  */
154 quat.mul = quat.multiply;
155
156 /**
157  * Scales a quat by a scalar number
158  *
159  * @param {quat} out the receiving vector
160  * @param {quat} a the vector to scale
161  * @param {Number} b amount to scale the vector by
162  * @returns {quat} out
163  * @function
164  */
165 quat.scale = vec4.scale;
166
167 /**
168  * Rotates a quaternion by the given angle around the X axis
169  *
170  * @param {quat} out quat receiving operation result
171  * @param {quat} a quat to rotate
172  * @param {number} rad angle (in radians) to rotate
173  * @returns {quat} out
174  */
175 quat.rotateX = function (out, a, rad) {
176     rad *= 0.5; 
177
178     var ax = a[0], ay = a[1], az = a[2], aw = a[3],
179         bx = Math.sin(rad), bw = Math.cos(rad);
180
181     out[0] = ax * bw + aw * bx;
182     out[1] = ay * bw + az * bx;
183     out[2] = az * bw - ay * bx;
184     out[3] = aw * bw - ax * bx;
185     return out;
186 };
187
188 /**
189  * Rotates a quaternion by the given angle around the Y axis
190  *
191  * @param {quat} out quat receiving operation result
192  * @param {quat} a quat to rotate
193  * @param {number} rad angle (in radians) to rotate
194  * @returns {quat} out
195  */
196 quat.rotateY = function (out, a, rad) {
197     rad *= 0.5; 
198
199     var ax = a[0], ay = a[1], az = a[2], aw = a[3],
200         by = Math.sin(rad), bw = Math.cos(rad);
201
202     out[0] = ax * bw - az * by;
203     out[1] = ay * bw + aw * by;
204     out[2] = az * bw + ax * by;
205     out[3] = aw * bw - ay * by;
206     return out;
207 };
208
209 /**
210  * Rotates a quaternion by the given angle around the Z axis
211  *
212  * @param {quat} out quat receiving operation result
213  * @param {quat} a quat to rotate
214  * @param {number} rad angle (in radians) to rotate
215  * @returns {quat} out
216  */
217 quat.rotateZ = function (out, a, rad) {
218     rad *= 0.5; 
219
220     var ax = a[0], ay = a[1], az = a[2], aw = a[3],
221         bz = Math.sin(rad), bw = Math.cos(rad);
222
223     out[0] = ax * bw + ay * bz;
224     out[1] = ay * bw - ax * bz;
225     out[2] = az * bw + aw * bz;
226     out[3] = aw * bw - az * bz;
227     return out;
228 };
229
230 /**
231  * Calculates the W component of a quat from the X, Y, and Z components.
232  * Assumes that quaternion is 1 unit in length.
233  * Any existing W component will be ignored.
234  *
235  * @param {quat} out the receiving quaternion
236  * @param {quat} a quat to calculate W component of
237  * @returns {quat} out
238  */
239 quat.calculateW = function (out, a) {
240     var x = a[0], y = a[1], z = a[2];
241
242     out[0] = x;
243     out[1] = y;
244     out[2] = z;
245     out[3] = -Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z));
246     return out;
247 };
248
249 /**
250  * Calculates the dot product of two quat's
251  *
252  * @param {quat} a the first operand
253  * @param {quat} b the second operand
254  * @returns {Number} dot product of a and b
255  * @function
256  */
257 quat.dot = vec4.dot;
258
259 /**
260  * Performs a linear interpolation between two quat's
261  *
262  * @param {quat} out the receiving quaternion
263  * @param {quat} a the first operand
264  * @param {quat} b the second operand
265  * @param {Number} t interpolation amount between the two inputs
266  * @returns {quat} out
267  * @function
268  */
269 quat.lerp = vec4.lerp;
270
271 /**
272  * Performs a spherical linear interpolation between two quat
273  *
274  * @param {quat} out the receiving quaternion
275  * @param {quat} a the first operand
276  * @param {quat} b the second operand
277  * @param {Number} t interpolation amount between the two inputs
278  * @returns {quat} out
279  */
280 quat.slerp = function (out, a, b, t) {
281     var ax = a[0], ay = a[1], az = a[2], aw = a[3],
282         bx = b[0], by = b[1], bz = b[2], bw = b[3];
283
284     var cosHalfTheta = ax * bx + ay * by + az * bz + aw * bw,
285         halfTheta,
286         sinHalfTheta,
287         ratioA,
288         ratioB;
289
290     if (Math.abs(cosHalfTheta) >= 1.0) {
291         if (out !== a) {
292             out[0] = ax;
293             out[1] = ay;
294             out[2] = az;
295             out[3] = aw;
296         }
297         return out;
298     }
299
300     halfTheta = Math.acos(cosHalfTheta);
301     sinHalfTheta = Math.sqrt(1.0 - cosHalfTheta * cosHalfTheta);
302
303     if (Math.abs(sinHalfTheta) < 0.001) {
304         out[0] = (ax * 0.5 + bx * 0.5);
305         out[1] = (ay * 0.5 + by * 0.5);
306         out[2] = (az * 0.5 + bz * 0.5);
307         out[3] = (aw * 0.5 + bw * 0.5);
308         return out;
309     }
310
311     ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta;
312     ratioB = Math.sin(t * halfTheta) / sinHalfTheta;
313
314     out[0] = (ax * ratioA + bx * ratioB);
315     out[1] = (ay * ratioA + by * ratioB);
316     out[2] = (az * ratioA + bz * ratioB);
317     out[3] = (aw * ratioA + bw * ratioB);
318
319     return out;
320 };
321
322 /**
323  * Calculates the inverse of a quat
324  *
325  * @param {quat} out the receiving quaternion
326  * @param {quat} a quat to calculate inverse of
327  * @returns {quat} out
328  */
329 quat.invert = function(out, a) {
330     var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
331         dot = a0*a0 + a1*a1 + a2*a2 + a3*a3,
332         invDot = dot ? 1.0/dot : 0;
333     
334     // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0
335
336     out[0] = -a0*invDot;
337     out[1] = -a1*invDot;
338     out[2] = -a2*invDot;
339     out[3] = a3*invDot;
340     return out;
341 };
342
343 /**
344  * Calculates the conjugate of a quat
345  * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result.
346  *
347  * @param {quat} out the receiving quaternion
348  * @param {quat} a quat to calculate conjugate of
349  * @returns {quat} out
350  */
351 quat.conjugate = function (out, a) {
352     out[0] = -a[0];
353     out[1] = -a[1];
354     out[2] = -a[2];
355     out[3] = a[3];
356     return out;
357 };
358
359 /**
360  * Calculates the length of a quat
361  *
362  * @param {quat} a vector to calculate length of
363  * @returns {Number} length of a
364  * @function
365  */
366 quat.length = vec4.length;
367
368 /**
369  * Alias for {@link quat.length}
370  * @function
371  */
372 quat.len = quat.length;
373
374 /**
375  * Calculates the squared length of a quat
376  *
377  * @param {quat} a vector to calculate squared length of
378  * @returns {Number} squared length of a
379  * @function
380  */
381 quat.squaredLength = vec4.squaredLength;
382
383 /**
384  * Alias for {@link quat.squaredLength}
385  * @function
386  */
387 quat.sqrLen = quat.squaredLength;
388
389 /**
390  * Normalize a quat
391  *
392  * @param {quat} out the receiving quaternion
393  * @param {quat} a quaternion to normalize
394  * @returns {quat} out
395  * @function
396  */
397 quat.normalize = vec4.normalize;
398
399 /**
400  * Creates a quaternion from the given 3x3 rotation matrix.
401  *
402  * @param {quat} out the receiving quaternion
403  * @param {mat3} m rotation matrix
404  * @returns {quat} out
405  * @function
406  */
407 quat.fromMat3 = (function() {
408     var s_iNext = [1,2,0];
409     return function(out, m) {
410         // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
411         // article "Quaternion Calculus and Fast Animation".
412         var fTrace = m[0] + m[4] + m[8];
413         var fRoot;
414
415         if ( fTrace > 0.0 ) {
416             // |w| > 1/2, may as well choose w > 1/2
417             fRoot = Math.sqrt(fTrace + 1.0);  // 2w
418             out[3] = 0.5 * fRoot;
419             fRoot = 0.5/fRoot;  // 1/(4w)
420             out[0] = (m[7]-m[5])*fRoot;
421             out[1] = (m[2]-m[6])*fRoot;
422             out[2] = (m[3]-m[1])*fRoot;
423         } else {
424             // |w| <= 1/2
425             var i = 0;
426             if ( m[4] > m[0] )
427               i = 1;
428             if ( m[8] > m[i*3+i] )
429               i = 2;
430             var j = s_iNext[i];
431             var k = s_iNext[j];
432             
433             fRoot = Math.sqrt(m[i*3+i]-m[j*3+j]-m[k*3+k] + 1.0);
434             out[i] = 0.5 * fRoot;
435             fRoot = 0.5 / fRoot;
436             out[3] = (m[k*3+j] - m[j*3+k]) * fRoot;
437             out[j] = (m[j*3+i] + m[i*3+j]) * fRoot;
438             out[k] = (m[k*3+i] + m[i*3+k]) * fRoot;
439         }
440         
441         return out;
442     };
443 })();
444
445 /**
446  * Returns a string representation of a quatenion
447  *
448  * @param {quat} vec vector to represent as a string
449  * @returns {String} string representation of the vector
450  */
451 quat.str = function (a) {
452     return 'quat(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
453 };
454
455 if(typeof(exports) !== 'undefined') {
456     exports.quat = quat;
457 }