Browse Source

Always use shortest path for Quaternion.slerp (also see: http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ Other Issues, Inverting Quaternions)

Marcel Jackwerth 14 years ago
parent
commit
d49f2d3281
1 changed files with 13 additions and 4 deletions
  1. 13 4
      src/core/Quaternion.js

+ 13 - 4
src/core/Quaternion.js

@@ -207,8 +207,17 @@ THREE.Quaternion.prototype = {
 
 
 THREE.Quaternion.slerp = function ( qa, qb, qm, t ) {
 THREE.Quaternion.slerp = function ( qa, qb, qm, t ) {
 
 
+	// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
+
 	var cosHalfTheta = qa.w * qb.w + qa.x * qb.x + qa.y * qb.y + qa.z * qb.z;
 	var cosHalfTheta = qa.w * qb.w + qa.x * qb.x + qa.y * qb.y + qa.z * qb.z;
 
 
+	if (cosHalfTheta < 0) {
+		qm.w = -qb.w; qm.x = -qb.x; qm.y = -qb.y; qm.z = qb.z;
+		cosHalfTheta = -cosHalfTheta;
+	} else {
+		qm.copy(qb);
+	}
+
 	if ( Math.abs( cosHalfTheta ) >= 1.0 ) {
 	if ( Math.abs( cosHalfTheta ) >= 1.0 ) {
 
 
 		qm.w = qa.w; qm.x = qa.x; qm.y = qa.y; qm.z = qa.z;
 		qm.w = qa.w; qm.x = qa.x; qm.y = qa.y; qm.z = qa.z;
@@ -233,10 +242,10 @@ THREE.Quaternion.slerp = function ( qa, qb, qm, t ) {
 	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; 
 
 
-	qm.w = ( qa.w * ratioA + qb.w * ratioB );
-	qm.x = ( qa.x * ratioA + qb.x * ratioB );
-	qm.y = ( qa.y * ratioA + qb.y * ratioB );
-	qm.z = ( qa.z * ratioA + qb.z * ratioB );
+	qm.w = ( qa.w * ratioA + qm.w * ratioB );
+	qm.x = ( qa.x * ratioA + qm.x * ratioB );
+	qm.y = ( qa.y * ratioA + qm.y * ratioB );
+	qm.z = ( qa.z * ratioA + qm.z * ratioB );
 
 
 	return qm;
 	return qm;