OSDN Git Service

Quaternion: don't modify the parameter
authorXoppa <contact@xoppa.nl>
Wed, 24 Jul 2013 16:48:07 +0000 (18:48 +0200)
committerXoppa <contact@xoppa.nl>
Wed, 24 Jul 2013 16:48:07 +0000 (18:48 +0200)
gdx/src/com/badlogic/gdx/math/Quaternion.java

index 757510d..7e645b2 100644 (file)
@@ -384,17 +384,8 @@ public class Quaternion implements Serializable {
         * @param alpha alpha in the range [0,1]\r
         * @return this quaternion for chaining */\r
        public Quaternion slerp (Quaternion end, float alpha) {\r
-               if (this.equals(end)) {\r
-                       return this;\r
-               }\r
-\r
-               float result = dot(end);\r
-\r
-               if (result < 0.0) {\r
-                       // Negate the second quaternion and the result of the dot product\r
-                       end.mul(-1);\r
-                       result = -result;\r
-               }\r
+               final float dot = dot(end);\r
+               float absDot = dot < 0.f ? -dot : dot;\r
 \r
                // Set the first and second scale for the interpolation\r
                float scale0 = 1 - alpha;\r
@@ -402,24 +393,26 @@ public class Quaternion implements Serializable {
 \r
                // Check if the angle between the 2 quaternions was big enough to\r
                // warrant such calculations\r
-               if ((1 - result) > 0.1) {// Get the angle between the 2 quaternions,\r
+               if ((1 - absDot) > 0.1) {// Get the angle between the 2 quaternions,\r
                        // and then store the sin() of that angle\r
-                       final double theta = Math.acos(result);\r
-                       final double invSinTheta = 1f / Math.sin(theta);\r
+                       final double angle = Math.acos(absDot);\r
+                       final double invSinTheta = 1f / Math.sin(angle);\r
 \r
                        // Calculate the scale for q1 and q2, according to the angle and\r
                        // it's sine value\r
-                       scale0 = (float)(Math.sin((1 - alpha) * theta) * invSinTheta);\r
-                       scale1 = (float)(Math.sin((alpha * theta)) * invSinTheta);\r
+                       scale0 = (float)(Math.sin((1 - alpha) * angle) * invSinTheta);\r
+                       scale1 = (float)(Math.sin((alpha * angle)) * invSinTheta);\r
                }\r
 \r
+               if (dot < 0.f)\r
+                       scale1 = -scale1;\r
+               \r
                // Calculate the x, y, z and w values for the quaternion by using a\r
                // special form of linear interpolation for quaternions.\r
-               final float x = (scale0 * this.x) + (scale1 * end.x);\r
-               final float y = (scale0 * this.y) + (scale1 * end.y);\r
-               final float z = (scale0 * this.z) + (scale1 * end.z);\r
-               final float w = (scale0 * this.w) + (scale1 * end.w);\r
-               set(x, y, z, w);\r
+               x = (scale0 * x) + (scale1 * end.x);\r
+               y = (scale0 * y) + (scale1 * end.y);\r
+               z = (scale0 * z) + (scale1 * end.z);\r
+               w = (scale0 * w) + (scale1 * end.w);\r
 \r
                // Return the interpolated quaternion\r
                return this;\r