From b89a7ee8b956c96a1dcee995ea840feddc5d4b27 Mon Sep 17 00:00:00 2001 From: Pierre Frisch Date: Thu, 22 Dec 2011 07:25:50 -0800 Subject: First commit of Ninja to ninja-internal Signed-off-by: Valerio Virgillito --- .../RDGE/src/core/script/math/quat.js | 225 +++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 js/helper-classes/RDGE/src/core/script/math/quat.js (limited to 'js/helper-classes/RDGE/src/core/script/math/quat.js') diff --git a/js/helper-classes/RDGE/src/core/script/math/quat.js b/js/helper-classes/RDGE/src/core/script/math/quat.js new file mode 100644 index 00000000..5c2c8bb6 --- /dev/null +++ b/js/helper-classes/RDGE/src/core/script/math/quat.js @@ -0,0 +1,225 @@ +/* +This file contains proprietary software owned by Motorola Mobility, Inc.
+No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
+(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. +
*/ + + +/** +* quat = {} +* This library contains utility functions for operating on quaternions. +* -- +* TODO: +* -need to add more helper functions for generating quaternions from +* other representations (i.e. - eulers, angle-axis). +*/ +quat = {} + +/** +* vec4.string +*/ +quat.string = function(q) { + return "{ " + q[0] + ", " + q[1] + ", " + q[2] + ", " + q[3] + " }"; +} + +/** +* quat.verify +*/ +quat.verify = function(q) { + if (q == undefined || q.length == undefined || q.length < 4) { + return false; + } + + if (typeof (q[0]) != "number" || typeof (q[1]) != "number" || typeof (q[2]) != "number" || typeof (q[3]) != "number") { + return false; + } + + return true; +} + +/** +* quat.identity +*/ +quat.identity = function() { + return [0.0, 0.0, 0.0, 1.0]; +} + +/** +* quat.add +*/ +quat.add = function(a, b) { + return [ a[0] + b[0], + a[1] + b[1], + a[2] + b[2], + a[3] + b[3]]; +} + +/** +* quat.sub +*/ +quat.sub = function(a, b) { + return [ a[0] - b[0], + a[1] - b[1], + a[2] - b[2], + a[3] - b[3]]; +} + +/** +* quat.mul +*/ +quat.mul = function( a, b ) { + return [ a[3]*b[3] - a[0]*b[0] - a[1]*b[1] - a[2]*b[2], + a[3]*b[0] + a[0]*b[3] + a[1]*b[2] - a[2]*b[1], + a[3]*b[1] - a[0]*b[2] + a[1]*b[3] + a[2]*b[0], + a[3]*b[2] + a[0]*b[1] - a[1]*b[0] + a[2]*b[3] ]; +} + +/** +* quat.addMul +*/ +quat.addMul = function(a, b, s) { + if (s.length != undefined && s.length >= 4) { + return [a[0] + b[0] * s[0], a[1] + b[1] * s[1], a[2] + b[2] * s[2], a[3] + b[3] * s[3]]; + } else { + return [a[0] + b[0] * s, a[1] + b[1] * s, a[2] + b[2] * s, a[3] + b[3] * s]; + } +} + + +/** +* quat.scale +*/ +quat.scale = function(q, s) { + if (s.length != undefined && s.length >= 4) { + return [q[0] * s[0], q[1] * q[1], q[2] * s[2], q[3] * s[3]]; + } else { + return [q[0] * s, q[1] * s, q[2] * s, q[3] * s]; + } +} + +/** +* quat.lengthSq +*/ +quat.lengthSq = function(q) { + return q[0] * q[0] + + q[1] * q[1] + + q[2] * q[2] + + q[3] * q[3]; +} + +/** +* quat.length +*/ +quat.length = function(q) { + return Math.sqrt( q[0] * q[0] + + q[1] * q[1] + + q[2] * q[2] + + q[3] * q[3]); +} + +/** +* quat.normalize +*/ +quat.normalize = function(q) { + var l = Math.sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); + if (Math.abs(1.0 - l) > 0.0001) { + var ool = 1.0 / l; + return [q[0] * ool, q[1] * ool, q[2] * ool, q[3] * ool]; + } + return q; +} + +/** +* quat.inverse +*/ +quat.inverse = function(q) { + var n = vec4.lengthSq( q ); + if( n > 0.00001 ) { + n = 1.0 / n; + return [ q[0] * -n, q[1] * -n, q[2] * -n, q[3] ]; + } else { + // error condition + } + return q; +} + +/** +* quat.dot +*/ +quat.dot = function(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; +} + +/** +* quat.applyRotation +*/ +quat.applyRotation = function(q, v) { + return mat4.transformPoint(quat.toMatrix(q), v); +} + +/** +* quat.lerp +*/ +quat.lerp = function(q0, q1, t) { + return quat.normalize( [ q0[0] + (q1[0] - q0[0]) * t, q0[1] + (q1[1] - q0[1]) * t, q0[2] + (q1[2] - q0[2]) * t, q0[3] + (q1[3] - q0[3]) * t ] ); +} + +/** +* quat.slerp +*/ +quat.slerp = function(q0, q1, t) { + var c = quat.dot(q0, q1); // cosine of the angle + + // just lerp if the quats are "close" enough + if (c >= 0.9) { + return quat.lerp(q0, q1, t); + } + + var s = Math.sqrt(Math.abs(1.0 - c * c)); // sine of the angle + if (s < 0.001) + return q0; // too close + + var sign = c < 0.0 ? -1.0 : 1.0; + var angle = Math.asin(s); + + var invs = 1.0 / s; // sine^-1 + var coef0 = Math.sin((1.0 - t) * angle) * invs; // interp. coefficients + var coef1 = Math.sin(t * angle) * invs * sign; + + quat.scale(q0, coef0); + quat.scale(q1, coef1); + + return quat.normalize( quat.add(q0, q1) ); +} + +/** +* quat.toMatrix +*/ +quat.toMatrix = function(q) { + var tx = 2.0 * q[0]; + var ty = 2.0 * q[1]; + var tz = 2.0 * q[2]; + var twx = tx * q[3]; + var twy = ty * q[3]; + var twz = tz * q[3]; + var txx = tx * q[0]; + var txy = ty * q[0]; + var txz = tz * q[0]; + var tyy = ty * q[1]; + var tyz = tz * q[1]; + var tzz = tz * q[2]; + + return [ 1.0 - (tyy + tzz), + txy + twz, + txz - twy, + 0, + txy - twz, + 1.0 - (txx + tzz), + tyz + twx, + 0, + txz + twy, + tyz - twx, + 1.0 - (txx + tyy), + 0, 0, 0, 0, 1]; +} + -- cgit v1.2.3