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
path: root/source
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2014-03-19 17:19:35 +0400
committerJoshua Leung <aligorith@gmail.com>2014-03-19 17:23:03 +0400
commitf0ac7294fafcd12abc83aa706f41af909ddad96d (patch)
treee748b0f38846d5ab24d96d40628fcbf459605f63 /source
parentd2660a079c9b950180aa000265267116bbd7c875 (diff)
Fix T39207: FCurve evaluation regressions following 2aff243
This commit attempts to fix some of the FCurve evaluation regressions arising from an earlier commit to speed up the process using binary search. Further tweaks may still be needed though to get this to an acceptable level of reliability (namely, tuning the threshold defining which keyframes get considered "close together"). Since we're still in an early stage of the 2.71 dev cycle, for now it's still worth trying to get this working instead of simply reverting this (which can still be done later if it proves too problematic). Specific fixes: * The previous code was somewhat dangerous in that it allowed out-of-bounds accessing of memory when a == 0. It turns out this was more common than originally anticipated (as the assert I added here ended up failing in the "action_bug.blend" file in the report) * Tweaked the code used to test for closely-spaced points so that the "Clive.blend" example for driver curves won't fail. The approach used here has the downside though that since "exact" uses a might coarser threshold for equality, there may be some precision loss issues causing backwards compat issues (namely with closely spaced keyframes, or for certain NLA strips). For now, I've left in some debug prints that can be enabled by running Blender in debug mode (i.e. "blender -d"), which can provide some useful tuning info should we need to look more into our approach here.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/fcurve.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 55c6df534c4..8121293691b 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -2041,20 +2041,21 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
/* evaltime occurs somewhere in the middle of the curve */
/* - use binary search to find appropriate keyframes */
a = binarysearch_bezt_index(bezts, evaltime, fcu->totvert, &exact);
- BLI_assert(a > 0); /* a == 0, prevbezt = invalid access */
+ if (G.f & G_DEBUG) printf("eval fcurve '%s' - %f => %d/%d, %d\n", fcu->rna_path, evaltime, a, fcu->totvert, exact);
- bezt = bezts;
- bezt += a;
- prevbezt = bezt - 1;
+ bezt = bezts + a;
+ prevbezt = (a > 0) ? bezt - 1 : bezt;
/* use if the key is directly on the frame, rare cases this is needed else we get 0.0 instead. */
- /* NOTE: Although we could just check if exact == true here, the thresholds for equality are
- * different (0.01 for exact, vs 1e-8 for SMALL_NUMBER). For backwards compatibility,
- * and to avoid introducing regressions for a few rare cases, let's keep the old
- * method/thresholds here for now.
- * -- Aligorith (2014Mar14)
+ /* XXX: the threshold for "exact" is BEZT_BINARYSEARCH_THRESH (currently 0.01), while older versions
+ * used a finer threshold (1e-8 or "SMALL_NUMBER"). In order to avoid problems introduced in
+ * 2aff243 (such as those mentioned in T39207 - specifically, in the "Clive.blend" example),
+ * we need a coarser threshold to avoid this slipping right through. However, 0.01 may be
+ * too much when dealing with some driver curves, so we'll need to revisit this in due course
+ * when problematic files arise.
+ * -- Aligorith (2014Mar19)
*/
- if (fabsf(bezt->vec[1][0] - evaltime) < SMALL_NUMBER) {
+ if ((fabsf(bezt->vec[1][0] - evaltime) < SMALL_NUMBER) || (exact)) {
cvalue = bezt->vec[1][1];
}
/* evaltime occurs within the interval defined by these two keyframes */
@@ -2102,6 +2103,9 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
}
}
}
+ else {
+ if (G.f & G_DEBUG) printf(" ERROR: failed eval - p=%f b=%f, t=%f (%f)\n", prevbezt->vec[1][0], bezt->vec[1][0], evaltime, fabsf(bezt->vec[1][0] - evaltime));
+ }
}
/* return value */