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

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2015-07-19 13:56:17 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2015-07-19 16:40:53 +0300
commit9c2c5413b26d7664b780ef42c21eea7826c6dc5f (patch)
tree2a17dda6bdb2d86bb1615b65d0770be4b27a964e /io_scene_fbx/fbx_utils.py
parent8e62ba483ef5e56667f1601b9f7c08a58a5ba986 (diff)
Fix T45487: fbx exporting weird keyframes.
Previous 'simplifying' code was not handling correctly micro-fluctuations around zero (caused by ugly float precision issues). Rewrote it more or less completely, new code is simpler and only based on relative difference (by default, it keys each time the diff is above 1e-4, and above 1e-4 * magnitude_of_values). Might produce more keys in some cases, but at least 'noise' shall never be exported again.
Diffstat (limited to 'io_scene_fbx/fbx_utils.py')
-rw-r--r--io_scene_fbx/fbx_utils.py42
1 files changed, 18 insertions, 24 deletions
diff --git a/io_scene_fbx/fbx_utils.py b/io_scene_fbx/fbx_utils.py
index c4ae3383..56442a37 100644
--- a/io_scene_fbx/fbx_utils.py
+++ b/io_scene_fbx/fbx_utils.py
@@ -770,49 +770,43 @@ class AnimationCurveNodeWrapper:
def simplify(self, fac, step, force_keep=False):
"""
Simplifies sampled curves by only enabling samples when:
- * their values differ significantly from the previous sample ones, or
- * their values differ significantly from the previous validated sample ones, or
- * the previous validated samples are far enough from current ones in time.
+ * their values relatively differ from the previous sample ones.
"""
if not self._keys:
return
# So that, with default factor and step values (1), we get:
- max_frame_diff = step * fac * 10 # max step of 10 frames.
- value_diff_fac = fac / 1000 # min value evolution: 0.1% of whole range.
- min_significant_diff = 1.0e-5
+ min_reldiff_fac = fac * 1.0e-3 # min relative value evolution: 0.1% of current 'order of magnitude'.
+ min_absdiff_fac = 0.1 # A tenth of reldiff...
keys = self._keys
- extremums = tuple((min(values), max(values)) for values in zip(*(k[1] for k in keys)))
- min_diffs = tuple(max((mx - mn) * value_diff_fac, min_significant_diff) for mn, mx in extremums)
-
p_currframe, p_key, p_key_write = keys[0]
- p_keyed = [(p_currframe - max_frame_diff, val) for val in p_key]
+ p_keyed = list(p_key)
are_keyed = [False] * len(p_key)
for currframe, key, key_write in keys:
for idx, (val, p_val) in enumerate(zip(key, p_key)):
key_write[idx] = False
- p_keyedframe, p_keyedval = p_keyed[idx]
+ p_keyedval = p_keyed[idx]
if val == p_val:
# Never write keyframe when value is exactly the same as prev one!
continue
- if abs(val - p_val) >= min_diffs[idx]:
+ # This is contracted form of relative + absolute-near-zero difference:
+ # absdiff = abs(a - b)
+ # if absdiff < min_reldiff_fac * min_absdiff_fac:
+ # return False
+ # return (absdiff / ((abs(a) + abs(b)) / 2)) > min_reldiff_fac
+ # Note that we ignore the '/ 2' part here, since it's not much significant for us.
+ if abs(val - p_val) > (min_reldiff_fac * max(abs(val) + abs(p_val), min_absdiff_fac)):
# If enough difference from previous sampled value, key this value *and* the previous one!
key_write[idx] = True
p_key_write[idx] = True
- p_keyed[idx] = (currframe, val)
+ p_keyed[idx] = val
+ are_keyed[idx] = True
+ elif abs(val - p_keyedval) > (min_reldiff_fac * max((abs(val) + abs(p_keyedval)), min_absdiff_fac)):
+ # Else, if enough difference from previous keyed value, key this value only!
+ key_write[idx] = True
+ p_keyed[idx] = val
are_keyed[idx] = True
- else:
- frame_diff = currframe - p_keyedframe
- val_diff = abs(val - p_keyedval)
- if ((val_diff >= min_diffs[idx]) or
- ((val_diff >= min_significant_diff) and (frame_diff >= max_frame_diff))):
- # Else, if enough difference from previous keyed value
- # (or any significant difference and max gap between keys is reached),
- # key this value only!
- key_write[idx] = True
- p_keyed[idx] = (currframe, val)
- are_keyed[idx] = True
p_currframe, p_key, p_key_write = currframe, key, key_write
# If we write nothing (action doing nothing) and are in 'force_keep' mode, we key everything! :P