Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2012-08-25 16:32:22 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-08-25 16:32:22 +0400
commit049811dabd87de6a6cb044cfe0730bb99c5583e1 (patch)
treea43e49261f5da3c3210e97b79f0cb758841b57d3 /source/blender/blenlib
parent043783c20b4f330c9d068d9000bfdc630977ff5d (diff)
don't use a while loop when in compatible_eul(). this is a low level rotation function called in many places so better to avoid iterations.
checked this function against the previous method using random rotation inputs and compared results, while this isnt exactly the same the results are very close and acceptable in both cases, also checked baking actions that the resulting FCurves are good and give matching rotations.
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r--source/blender/blenlib/intern/math_rotation.c94
1 files changed, 28 insertions, 66 deletions
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index 1698733dda7..d44e26aad08 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -1040,84 +1040,46 @@ void rotate_eul(float *beul, const char axis, const float ang)
}
-/* exported to transform.c */
-
/* order independent! */
void compatible_eul(float eul[3], const float oldrot[3])
{
- float dx, dy, dz;
+ /* we could use M_PI as pi_thresh: which is correct but 5.1 gives better results.
+ * Checked with baking actions to fcurves - campbell */
+ const float pi_thresh = (5.1f);
+ const float pi_x2 = (2.0f * (float)M_PI);
+
+ float deul[3];
+ unsigned int i;
/* correct differences of about 360 degrees first */
- dx = eul[0] - oldrot[0];
- dy = eul[1] - oldrot[1];
- dz = eul[2] - oldrot[2];
-
- while (fabsf(dx) > 5.1f) {
- if (dx > 0.0f) eul[0] -= 2.0f * (float)M_PI;
- else eul[0] += 2.0f * (float)M_PI;
- dx = eul[0] - oldrot[0];
- }
- while (fabsf(dy) > 5.1f) {
- if (dy > 0.0f) eul[1] -= 2.0f * (float)M_PI;
- else eul[1] += 2.0f * (float)M_PI;
- dy = eul[1] - oldrot[1];
- }
- while (fabsf(dz) > 5.1f) {
- if (dz > 0.0f) eul[2] -= 2.0f * (float)M_PI;
- else eul[2] += 2.0f * (float)M_PI;
- dz = eul[2] - oldrot[2];
+ for (i = 0; i < 3; i++) {
+ deul[i] = eul[i] - oldrot[i];
+ if (deul[i] > pi_thresh) {
+ eul[i] -= floorf(( deul[i] / pi_x2) + 0.5) * pi_x2;
+ deul[i] = eul[i] - oldrot[i];
+ }
+ else if (deul[i] < -pi_thresh) {
+ eul[i] += floorf((-deul[i] / pi_x2) + 0.5) * pi_x2;
+ deul[i] = eul[i] - oldrot[i];
+ }
}
/* is 1 of the axis rotations larger than 180 degrees and the other small? NO ELSE IF!! */
- if (fabsf(dx) > 3.2f && fabsf(dy) < 1.6f && fabsf(dz) < 1.6f) {
- if (dx > 0.0f) eul[0] -= 2.0f * (float)M_PI;
- else eul[0] += 2.0f * (float)M_PI;
+ if (fabsf(deul[0]) > 3.2f && fabsf(deul[1]) < 1.6f && fabsf(deul[2]) < 1.6f) {
+ if (deul[0] > 0.0f) eul[0] -= pi_x2;
+ else eul[0] += pi_x2;
}
- if (fabsf(dy) > 3.2f && fabsf(dz) < 1.6f && fabsf(dx) < 1.6f) {
- if (dy > 0.0f) eul[1] -= 2.0f * (float)M_PI;
- else eul[1] += 2.0f * (float)M_PI;
+ if (fabsf(deul[1]) > 3.2f && fabsf(deul[2]) < 1.6f && fabsf(deul[0]) < 1.6f) {
+ if (deul[1] > 0.0f) eul[1] -= pi_x2;
+ else eul[1] += pi_x2;
}
- if (fabsf(dz) > 3.2f && fabsf(dx) < 1.6f && fabsf(dy) < 1.6f) {
- if (dz > 0.0f) eul[2] -= 2.0f * (float)M_PI;
- else eul[2] += 2.0f * (float)M_PI;
+ if (fabsf(deul[2]) > 3.2f && fabsf(deul[0]) < 1.6f && fabsf(deul[1]) < 1.6f) {
+ if (deul[2] > 0.0f) eul[2] -= pi_x2;
+ else eul[2] += pi_x2;
}
- /* the method below was there from ancient days... but why! probably because the code sucks :)
- */
-#if 0
- /* calc again */
- dx = eul[0] - oldrot[0];
- dy = eul[1] - oldrot[1];
- dz = eul[2] - oldrot[2];
-
- /* special case, tested for x-z */
-
- if ((fabsf(dx) > 3.1f && fabsf(dz) > 1.5f) || (fabsf(dx) > 1.5f && fabsf(dz) > 3.1f)) {
- if (dx > 0.0f) eul[0] -= M_PI;
- else eul[0] += M_PI;
- if (eul[1] > 0.0) eul[1] = M_PI - eul[1];
- else eul[1] = -M_PI - eul[1];
- if (dz > 0.0f) eul[2] -= M_PI;
- else eul[2] += M_PI;
-
- }
- else if ((fabsf(dx) > 3.1f && fabsf(dy) > 1.5f) || (fabsf(dx) > 1.5f && fabsf(dy) > 3.1f)) {
- if (dx > 0.0f) eul[0] -= M_PI;
- else eul[0] += M_PI;
- if (dy > 0.0f) eul[1] -= M_PI;
- else eul[1] += M_PI;
- if (eul[2] > 0.0f) eul[2] = M_PI - eul[2];
- else eul[2] = -M_PI - eul[2];
- }
- else if ((fabsf(dy) > 3.1f && fabsf(dz) > 1.5f) || (fabsf(dy) > 1.5f && fabsf(dz) > 3.f1)) {
- if (eul[0] > 0.0f) eul[0] = M_PI - eul[0];
- else eul[0] = -M_PI - eul[0];
- if (dy > 0.0f) eul[1] -= M_PI;
- else eul[1] += M_PI;
- if (dz > 0.0f) eul[2] -= M_PI;
- else eul[2] += M_PI;
- }
-#endif
+#undef PI_THRESH
+#undef PI_2F
}
/* uses 2 methods to retrieve eulers, and picks the closest */