|
@@ -16,7 +16,80 @@ function Quaternion( x, y, z, w ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
-Quaternion.prototype = {
|
|
|
|
|
|
+Object.assign( Quaternion, {
|
|
|
|
+
|
|
|
|
+ slerp: function( qa, qb, qm, t ) {
|
|
|
|
+
|
|
|
|
+ return qm.copy( qa ).slerp( qb, t );
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ slerpFlat: function(
|
|
|
|
+ dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {
|
|
|
|
+
|
|
|
|
+ // fuzz-free, array-based Quaternion SLERP operation
|
|
|
|
+
|
|
|
|
+ var x0 = src0[ srcOffset0 + 0 ],
|
|
|
|
+ y0 = src0[ srcOffset0 + 1 ],
|
|
|
|
+ z0 = src0[ srcOffset0 + 2 ],
|
|
|
|
+ w0 = src0[ srcOffset0 + 3 ],
|
|
|
|
+
|
|
|
|
+ x1 = src1[ srcOffset1 + 0 ],
|
|
|
|
+ y1 = src1[ srcOffset1 + 1 ],
|
|
|
|
+ z1 = src1[ srcOffset1 + 2 ],
|
|
|
|
+ w1 = src1[ srcOffset1 + 3 ];
|
|
|
|
+
|
|
|
|
+ if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {
|
|
|
|
+
|
|
|
|
+ var s = 1 - t,
|
|
|
|
+
|
|
|
|
+ cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,
|
|
|
|
+
|
|
|
|
+ dir = ( cos >= 0 ? 1 : - 1 ),
|
|
|
|
+ sqrSin = 1 - cos * cos;
|
|
|
|
+
|
|
|
|
+ // Skip the Slerp for tiny steps to avoid numeric problems:
|
|
|
|
+ if ( sqrSin > Number.EPSILON ) {
|
|
|
|
+
|
|
|
|
+ var sin = Math.sqrt( sqrSin ),
|
|
|
|
+ len = Math.atan2( sin, cos * dir );
|
|
|
|
+
|
|
|
|
+ s = Math.sin( s * len ) / sin;
|
|
|
|
+ t = Math.sin( t * len ) / sin;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var tDir = t * dir;
|
|
|
|
+
|
|
|
|
+ x0 = x0 * s + x1 * tDir;
|
|
|
|
+ y0 = y0 * s + y1 * tDir;
|
|
|
|
+ z0 = z0 * s + z1 * tDir;
|
|
|
|
+ w0 = w0 * s + w1 * tDir;
|
|
|
|
+
|
|
|
|
+ // Normalize in case we just did a lerp:
|
|
|
|
+ if ( s === 1 - t ) {
|
|
|
|
+
|
|
|
|
+ var f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );
|
|
|
|
+
|
|
|
|
+ x0 *= f;
|
|
|
|
+ y0 *= f;
|
|
|
|
+ z0 *= f;
|
|
|
|
+ w0 *= f;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ dst[ dstOffset ] = x0;
|
|
|
|
+ dst[ dstOffset + 1 ] = y0;
|
|
|
|
+ dst[ dstOffset + 2 ] = z0;
|
|
|
|
+ dst[ dstOffset + 3 ] = w0;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+} );
|
|
|
|
+
|
|
|
|
+Object.assign( Quaternion.prototype, {
|
|
|
|
|
|
constructor: Quaternion,
|
|
constructor: Quaternion,
|
|
|
|
|
|
@@ -453,7 +526,7 @@ Quaternion.prototype = {
|
|
|
|
|
|
var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );
|
|
var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );
|
|
var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
|
|
var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
|
|
- ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
|
|
|
|
|
|
+ ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
|
|
|
|
|
|
this._w = ( w * ratioA + this._w * ratioB );
|
|
this._w = ( w * ratioA + this._w * ratioB );
|
|
this._x = ( x * ratioA + this._x * ratioB );
|
|
this._x = ( x * ratioA + this._x * ratioB );
|
|
@@ -511,79 +584,6 @@ Quaternion.prototype = {
|
|
|
|
|
|
onChangeCallback: function () {}
|
|
onChangeCallback: function () {}
|
|
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-Object.assign( Quaternion, {
|
|
|
|
-
|
|
|
|
- slerp: function( qa, qb, qm, t ) {
|
|
|
|
-
|
|
|
|
- return qm.copy( qa ).slerp( qb, t );
|
|
|
|
-
|
|
|
|
- },
|
|
|
|
-
|
|
|
|
- slerpFlat: function(
|
|
|
|
- dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {
|
|
|
|
-
|
|
|
|
- // fuzz-free, array-based Quaternion SLERP operation
|
|
|
|
-
|
|
|
|
- var x0 = src0[ srcOffset0 + 0 ],
|
|
|
|
- y0 = src0[ srcOffset0 + 1 ],
|
|
|
|
- z0 = src0[ srcOffset0 + 2 ],
|
|
|
|
- w0 = src0[ srcOffset0 + 3 ],
|
|
|
|
-
|
|
|
|
- x1 = src1[ srcOffset1 + 0 ],
|
|
|
|
- y1 = src1[ srcOffset1 + 1 ],
|
|
|
|
- z1 = src1[ srcOffset1 + 2 ],
|
|
|
|
- w1 = src1[ srcOffset1 + 3 ];
|
|
|
|
-
|
|
|
|
- if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {
|
|
|
|
-
|
|
|
|
- var s = 1 - t,
|
|
|
|
-
|
|
|
|
- cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,
|
|
|
|
-
|
|
|
|
- dir = ( cos >= 0 ? 1 : - 1 ),
|
|
|
|
- sqrSin = 1 - cos * cos;
|
|
|
|
-
|
|
|
|
- // Skip the Slerp for tiny steps to avoid numeric problems:
|
|
|
|
- if ( sqrSin > Number.EPSILON ) {
|
|
|
|
-
|
|
|
|
- var sin = Math.sqrt( sqrSin ),
|
|
|
|
- len = Math.atan2( sin, cos * dir );
|
|
|
|
-
|
|
|
|
- s = Math.sin( s * len ) / sin;
|
|
|
|
- t = Math.sin( t * len ) / sin;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- var tDir = t * dir;
|
|
|
|
-
|
|
|
|
- x0 = x0 * s + x1 * tDir;
|
|
|
|
- y0 = y0 * s + y1 * tDir;
|
|
|
|
- z0 = z0 * s + z1 * tDir;
|
|
|
|
- w0 = w0 * s + w1 * tDir;
|
|
|
|
-
|
|
|
|
- // Normalize in case we just did a lerp:
|
|
|
|
- if ( s === 1 - t ) {
|
|
|
|
-
|
|
|
|
- var f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );
|
|
|
|
-
|
|
|
|
- x0 *= f;
|
|
|
|
- y0 *= f;
|
|
|
|
- z0 *= f;
|
|
|
|
- w0 *= f;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- dst[ dstOffset ] = x0;
|
|
|
|
- dst[ dstOffset + 1 ] = y0;
|
|
|
|
- dst[ dstOffset + 2 ] = z0;
|
|
|
|
- dst[ dstOffset + 3 ] = w0;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
|