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:
authorStefan Werner <stefan.werner@tangent-animation.com>2021-08-02 10:28:54 +0300
committerStefan Werner <stefan.werner@tangent-animation.com>2021-08-02 10:28:54 +0300
commit34e8d79c3edbc58fd242cec0c1f2bed4e43855af (patch)
tree36c70e63515af2bd8ea840102493028faec37971 /source/blender/blenkernel/intern/anim_sys.c
parent465fb31ed275618ec71e4925ab94bd4a9b077a12 (diff)
parent48722e8971133dbe14ecc6825a2451637df77eab (diff)
Merge branch 'master' into cycles_texture_cache
Diffstat (limited to 'source/blender/blenkernel/intern/anim_sys.c')
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c134
1 files changed, 128 insertions, 6 deletions
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 6164d4921b0..fae75762cde 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -148,8 +148,11 @@ KeyingSet *BKE_keyingset_add(
/* allocate new KeyingSet */
ks = MEM_callocN(sizeof(KeyingSet), "KeyingSet");
- BLI_strncpy(
- ks->idname, (idname) ? idname : (name) ? name : DATA_("KeyingSet"), sizeof(ks->idname));
+ BLI_strncpy(ks->idname,
+ (idname) ? idname :
+ (name) ? name :
+ DATA_("KeyingSet"),
+ sizeof(ks->idname));
BLI_strncpy(ks->name, (name) ? name : (idname) ? idname : DATA_("Keying Set"), sizeof(ks->name));
ks->flag = flag;
@@ -621,6 +624,115 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr,
}
}
+/* This function assumes that the quaternion is fully keyed, and is stored in array index order. */
+static void animsys_quaternion_evaluate_fcurves(PathResolvedRNA quat_rna,
+ FCurve *first_fcurve,
+ const AnimationEvalContext *anim_eval_context,
+ float r_quaternion[4])
+{
+ FCurve *quat_curve_fcu = first_fcurve;
+ for (int prop_index = 0; prop_index < 4; ++prop_index, quat_curve_fcu = quat_curve_fcu->next) {
+ /* Big fat assumption that the quaternion is fully keyed, and stored in order. */
+ BLI_assert(STREQ(quat_curve_fcu->rna_path, first_fcurve->rna_path) &&
+ quat_curve_fcu->array_index == prop_index);
+
+ quat_rna.prop_index = prop_index;
+ r_quaternion[prop_index] = calculate_fcurve(&quat_rna, quat_curve_fcu, anim_eval_context);
+ }
+}
+
+/* This function assumes that the quaternion is fully keyed, and is stored in array index order. */
+static void animsys_blend_fcurves_quaternion(PathResolvedRNA *anim_rna,
+ FCurve *first_fcurve,
+ const AnimationEvalContext *anim_eval_context,
+ const float blend_factor)
+{
+ float current_quat[4];
+ RNA_property_float_get_array(&anim_rna->ptr, anim_rna->prop, current_quat);
+
+ float target_quat[4];
+ animsys_quaternion_evaluate_fcurves(*anim_rna, first_fcurve, anim_eval_context, target_quat);
+
+ float blended_quat[4];
+ interp_qt_qtqt(blended_quat, current_quat, target_quat, blend_factor);
+
+ RNA_property_float_set_array(&anim_rna->ptr, anim_rna->prop, blended_quat);
+}
+
+/* LERP between current value (blend_factor=0.0) and the value from the FCurve (blend_factor=1.0)
+ */
+static void animsys_blend_in_fcurves(PointerRNA *ptr,
+ ListBase *fcurves,
+ const AnimationEvalContext *anim_eval_context,
+ const float blend_factor)
+{
+ char *channel_to_skip = NULL;
+ int num_channels_to_skip = 0;
+ LISTBASE_FOREACH (FCurve *, fcu, fcurves) {
+
+ if (num_channels_to_skip) {
+ /* For skipping already-handled rotation channels. Rotation channels are handled per group,
+ * and not per individual channel. */
+ BLI_assert(channel_to_skip != NULL);
+ if (STREQ(channel_to_skip, fcu->rna_path)) {
+ /* This is indeed the channel we want to skip. */
+ num_channels_to_skip--;
+ continue;
+ }
+ }
+
+ if (!is_fcurve_evaluatable(fcu)) {
+ continue;
+ }
+
+ PathResolvedRNA anim_rna;
+ if (!BKE_animsys_rna_path_resolve(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
+ continue;
+ }
+
+ if (STREQ(RNA_property_identifier(anim_rna.prop), "rotation_quaternion")) {
+ animsys_blend_fcurves_quaternion(&anim_rna, fcu, anim_eval_context, blend_factor);
+
+ /* Skip the next three channels, because those have already been handled here. */
+ MEM_SAFE_FREE(channel_to_skip);
+ channel_to_skip = BLI_strdup(fcu->rna_path);
+ num_channels_to_skip = 3;
+ continue;
+ }
+ /* TODO(Sybren): do something similar as above for Euler and Axis/Angle representations. */
+
+ const float fcurve_value = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
+
+ float current_value;
+ float value_to_write;
+ if (BKE_animsys_read_from_rna_path(&anim_rna, &current_value)) {
+ value_to_write = (1 - blend_factor) * current_value + blend_factor * fcurve_value;
+
+ switch (RNA_property_type(anim_rna.prop)) {
+ case PROP_BOOLEAN:
+ /* Without this, anything less than 1.0 is converted to 'False' by
+ * ANIMSYS_FLOAT_AS_BOOL(). This is probably not desirable for blends, where anything
+ * above a 50% blend should act more like the FCurve than like the current value. */
+ case PROP_INT:
+ case PROP_ENUM:
+ value_to_write = roundf(value_to_write);
+ break;
+ default:
+ /* All other types are just handled as float, and value_to_write is already correct. */
+ break;
+ }
+ }
+ else {
+ /* Unable to read the current value for blending, so just apply the FCurve value instead. */
+ value_to_write = fcurve_value;
+ }
+
+ BKE_animsys_write_to_rna_path(&anim_rna, value_to_write);
+ }
+
+ MEM_SAFE_FREE(channel_to_skip);
+}
+
/* ***************************************** */
/* Driver Evaluation */
@@ -769,6 +881,16 @@ void animsys_evaluate_action(PointerRNA *ptr,
animsys_evaluate_fcurves(ptr, &act->curves, anim_eval_context, flush_to_original);
}
+/* Evaluate Action and blend it into the current values of the animated properties. */
+void animsys_blend_in_action(PointerRNA *ptr,
+ bAction *act,
+ const AnimationEvalContext *anim_eval_context,
+ const float blend_factor)
+{
+ action_idcode_patch_check(ptr->owner_id, act);
+ animsys_blend_in_fcurves(ptr, &act->curves, anim_eval_context, blend_factor);
+}
+
/* ***************************************** */
/* NLA System - Evaluation */
@@ -1828,7 +1950,7 @@ static void nlaevalchan_blendOrcombine(NlaEvalChannelSnapshot *lower_necs,
return;
}
default:
- BLI_assert("Mix mode should've been handled");
+ BLI_assert_msg(0, "Mix mode should've been handled");
}
return;
}
@@ -1841,7 +1963,7 @@ static void nlaevalchan_blendOrcombine(NlaEvalChannelSnapshot *lower_necs,
return;
}
default:
- BLI_assert("Blend mode should've been handled");
+ BLI_assert_msg(0, "Blend mode should've been handled");
}
}
@@ -1991,7 +2113,7 @@ static void nlaevalchan_blendOrcombine_get_inverted_upper_evalchan(
return;
}
default:
- BLI_assert("Mix mode should've been handled");
+ BLI_assert_msg(0, "Mix mode should've been handled");
}
return;
}
@@ -2004,7 +2126,7 @@ static void nlaevalchan_blendOrcombine_get_inverted_upper_evalchan(
return;
}
default:
- BLI_assert("Blend mode should've been handled");
+ BLI_assert_msg(0, "Blend mode should've been handled");
}
}