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:
authorWayde Moss <wbmoss_dev@yahoo.com>2020-11-27 07:21:03 +0300
committerWayde Moss <wbmoss_dev@yahoo.com>2020-12-10 07:16:59 +0300
commitd9280548ffd27a8baaa213012d4dbd8eefa5e423 (patch)
tree78154ccb0e30db1af1bd90961cd736d1d903ef8c
parentd40ea0b3f46e48efc7ef657a9fede502dce8619f (diff)
- used quaternion slerp through shortest angle for non full replace blends to fix issue of rotation through longer angle. Unsure if animator ever wants the opposite. If so, that makes things a bit more complicated for specifying which nla channels should have it applied.
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c53
1 files changed, 50 insertions, 3 deletions
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 96613de471d..17cf8423b12 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -2987,9 +2987,56 @@ static void nlaeval_snapshot_blend(NlaEvalData *nlaeval,
}
}
else {
- for (int j = 0; j < c_lower->length; j++) {
- c_lower->values[j] = nla_blend_value(
- upper_blendmode, c_lower->values[j], c_upper->values[j], upper_influence);
+
+ {
+ // blend, user quat slerp through shortest angle if non full replace.
+ // combine and the other blend modes shouldnt need this behavior since replace
+ // defines an absolute orientation while the others are offset and proportional types.
+ if (upper_blendmode == NLASTRIP_MODE_REPLACE && upper_influence < 1.0f) {
+ PropertySubType subtype = RNA_property_subtype(nec->key.prop);
+ int length = nec->base_snapshot.length;
+
+ if (subtype == PROP_QUATERNION && length == 4) {
+ // Todo: quaternion slerp through shorter angle
+ float lower_qt[4], upper_qt[4];
+ copy_qt_qt(upper_qt, c_upper->values);
+ copy_qt_qt(lower_qt, c_lower->values);
+
+ float result_qt[4];
+ interp_qt_qtqt(result_qt, lower_qt, upper_qt, upper_influence);
+
+ copy_qt_qt(c_lower->values, result_qt);
+ continue;
+ }
+ else if (subtype == PROP_AXISANGLE && length == 4) {
+ // Todo: quaternion slerp through shorter angle
+ float lower_qt[4], upper_qt[4];
+ axis_angle_to_quat(upper_qt, c_upper->values, c_upper->values[3]);
+ axis_angle_to_quat(lower_qt, c_lower->values, c_lower->values[3]);
+
+ float result_qt[4];
+ interp_qt_qtqt(result_qt, lower_qt, upper_qt, upper_influence);
+
+ quat_to_axis_angle(c_lower->values, &c_lower->values[3], result_qt);
+ continue;
+ }
+ else if (subtype == PROP_EULER && length == 3) {
+ // Todo: quaternion slerp through shorter angle
+ float lower_qt[4], upper_qt[4];
+ eul_to_quat(upper_qt, c_upper->values);
+ eul_to_quat(lower_qt, c_lower->values);
+
+ float result_qt[4];
+ interp_qt_qtqt(result_qt, lower_qt, upper_qt, upper_influence);
+
+ quat_to_eul(c_lower->values, result_qt);
+ continue;
+ }
+ }
+ for (int j = 0; j < c_lower->length; j++) {
+ c_lower->values[j] = nla_blend_value(
+ upper_blendmode, c_lower->values[j], c_upper->values[j], upper_influence);
+ }
}
}
}