[Bf-blender-cvs] [7f74c8c479e] temp_D10504_nla_keyframe_remap_upper_strips: NLA: Extract nlasnapshot_blend_get_inverted_upper_snapshot()
Wayde Moss
noreply at git.blender.org
Mon Feb 22 22:19:00 CET 2021
Commit: 7f74c8c479ecaa59d9ea6573373c17c3035e72a5
Author: Wayde Moss
Date: Wed Feb 17 00:47:14 2021 -0500
Branches: temp_D10504_nla_keyframe_remap_upper_strips
https://developer.blender.org/rB7f74c8c479ecaa59d9ea6573373c17c3035e72a5
NLA: Extract nlasnapshot_blend_get_inverted_upper_snapshot()
Extracts //nlasnapshot_blend_get_inverted_upper_snapshot()// from //BKE_animsys_nla_remap_keyframe_values()//
- This introduces a new struct member: `NlaEvalChannelSnapshot->invertible` which marks values which have successfully been inverted and can be further used for solving.
- //nlasnapshot_mark_all_invertible()// is unused in this patch but seemed generally useful when using snapshots for remapping. {D8867} would be able to make use of it.
- //nlasnapshot_blend_get_inverted_upper_snapshot()// has a variant //nlasnapshot_blend()// from {D10220}, but this patch doesn't depend on it at all. A third variant will later be added //nlasnapshot_blend_get_inverted_lower_snapshot()//. Altogether, these three functions allow solving for any of (lower_snapshot, upper_snapshot, blended_snapshot) given the other two.
No user functional changes
Differential Revision: https://developer.blender.org/D10222
===================================================================
M source/blender/blenkernel/intern/anim_sys.c
M source/blender/blenkernel/nla_private.h
===================================================================
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 4d490f8f76a..f4e59bc2728 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -1051,6 +1051,7 @@ static NlaEvalChannelSnapshot *nlaevalchan_snapshot_new(NlaEvalChannel *nec)
nec_snapshot->channel = nec;
nec_snapshot->length = length;
nlavalidmask_init(&nec_snapshot->blend_domain, length);
+ nlavalidmask_init(&nec_snapshot->remap_domain, length);
return nec_snapshot;
}
@@ -1061,6 +1062,7 @@ static void nlaevalchan_snapshot_free(NlaEvalChannelSnapshot *nec_snapshot)
BLI_assert(!nec_snapshot->is_base);
nlavalidmask_free(&nec_snapshot->blend_domain);
+ nlavalidmask_free(&nec_snapshot->remap_domain);
MEM_freeN(nec_snapshot);
}
@@ -2502,6 +2504,20 @@ void nlasnapshot_ensure_channels(NlaEvalData *eval_data, NlaEvalSnapshot *snapsh
}
}
+void nlasnapshot_enable_all_remap_domain(NlaEvalSnapshot *snapshot)
+{
+ for (int i = 0; i < snapshot->size; i++) {
+ NlaEvalChannelSnapshot *necs = nlaeval_snapshot_get(snapshot, i);
+ if (necs == NULL) {
+ continue;
+ }
+
+ for (int j = 0; j < necs->length; j++) {
+ BLI_BITMAP_ENABLE(necs->remap_domain.ptr, j);
+ }
+ }
+}
+
/** Blends the \a lower_snapshot with the \a upper_snapshot into \a r_blended_snapshot according
* to the given \a upper_blendmode and \a upper_influence.
*
@@ -2546,6 +2562,7 @@ void nlasnapshot_blend(NlaEvalData *eval_data,
if (upper_blendmode == NLASTRIP_MODE_COMBINE) {
const int mix_mode = nec->mix_mode;
+
if (mix_mode == NEC_MIX_QUATERNION) {
if (!BLI_BITMAP_TEST_BOOL(upper_necs->blend_domain.ptr, 0)) {
continue;
@@ -2555,6 +2572,8 @@ void nlasnapshot_blend(NlaEvalData *eval_data,
lower_necs->values, upper_necs->values, upper_influence, result_necs->values);
}
else {
+ BLI_assert(ELEM(mix_mode, NEC_MIX_ADD, NEC_MIX_AXIS_ANGLE, NEC_MIX_MULTIPLY));
+
for (int j = 0; j < length; j++) {
if (!BLI_BITMAP_TEST_BOOL(upper_necs->blend_domain.ptr, j)) {
continue;
@@ -2569,6 +2588,12 @@ void nlasnapshot_blend(NlaEvalData *eval_data,
}
}
else {
+ BLI_assert(ELEM(upper_blendmode,
+ NLASTRIP_MODE_ADD,
+ NLASTRIP_MODE_SUBTRACT,
+ NLASTRIP_MODE_MULTIPLY,
+ NLASTRIP_MODE_REPLACE));
+
for (int j = 0; j < length; j++) {
if (!BLI_BITMAP_TEST_BOOL(upper_necs->blend_domain.ptr, j)) {
continue;
@@ -2581,6 +2606,99 @@ void nlasnapshot_blend(NlaEvalData *eval_data,
}
}
+/** Using \a blended_snapshot and \a lower_snapshot, we can solve for the \a r_upper_snapshot.
+ *
+ * Only channels that exist within \a blended_snapshot are inverted.
+ *
+ * For \a r_upper_snapshot, disables \a NlaEvalChannelSnapshot->remap_domain for failed inversions.
+ * Only values within the \a remap_domain are processed.
+ */
+void nlasnapshot_blend_get_inverted_upper_snapshot(NlaEvalData *eval_data,
+ NlaEvalSnapshot *lower_snapshot,
+ NlaEvalSnapshot *blended_snapshot,
+ const short upper_blendmode,
+ const float upper_influence,
+ NlaEvalSnapshot *r_upper_snapshot)
+{
+ nlaeval_snapshot_ensure_size(r_upper_snapshot, eval_data->num_channels);
+
+ LISTBASE_FOREACH (NlaEvalChannel *, nec, &eval_data->channels) {
+ const int length = nec->base_snapshot.length;
+
+ NlaEvalChannelSnapshot *blended_necs = nlaeval_snapshot_get(blended_snapshot, nec->index);
+ if (blended_necs == NULL) {
+ /** We assume the caller only wants a subset of channels to be inverted, those that exist
+ * within \a blended_snapshot. */
+ continue;
+ }
+
+ NlaEvalChannelSnapshot *lower_necs = nlaeval_snapshot_get(lower_snapshot, nec->index);
+ if (lower_necs == NULL) {
+ lower_necs = nlaeval_snapshot_find_channel(lower_snapshot->base, nec);
+ }
+
+ NlaEvalChannelSnapshot *result_necs = nlaeval_snapshot_ensure_channel(r_upper_snapshot, nec);
+ if (upper_blendmode == NLASTRIP_MODE_COMBINE) {
+ const int mix_mode = nec->mix_mode;
+
+ if (mix_mode == NEC_MIX_QUATERNION) {
+ if (!BLI_BITMAP_TEST_BOOL(blended_necs->remap_domain.ptr, 0)) {
+ BLI_bitmap_set_all(result_necs->remap_domain.ptr, false, 4);
+ continue;
+ }
+
+ if (!nla_combine_quaternion_get_inverted_strip_values(
+ lower_necs->values, blended_necs->values, upper_influence, result_necs->values)) {
+ BLI_bitmap_set_all(result_necs->remap_domain.ptr, false, 4);
+ }
+ }
+ else {
+ BLI_assert(ELEM(mix_mode, NEC_MIX_ADD, NEC_MIX_AXIS_ANGLE, NEC_MIX_MULTIPLY));
+
+ for (int j = 0; j < length; j++) {
+ if (!BLI_BITMAP_TEST_BOOL(blended_necs->remap_domain.ptr, j)) {
+ BLI_BITMAP_DISABLE(result_necs->remap_domain.ptr, j);
+ continue;
+ }
+
+ if (!nla_combine_get_inverted_strip_value(mix_mode,
+ nec->base_snapshot.values[j],
+ lower_necs->values[j],
+ blended_necs->values[j],
+ upper_influence,
+ &result_necs->values[j])) {
+
+ BLI_BITMAP_DISABLE(result_necs->remap_domain.ptr, j);
+ }
+ }
+ }
+ }
+ else {
+ BLI_assert(ELEM(upper_blendmode,
+ NLASTRIP_MODE_ADD,
+ NLASTRIP_MODE_SUBTRACT,
+ NLASTRIP_MODE_MULTIPLY,
+ NLASTRIP_MODE_REPLACE));
+
+ for (int j = 0; j < length; j++) {
+ if (!BLI_BITMAP_TEST_BOOL(blended_necs->remap_domain.ptr, j)) {
+ BLI_BITMAP_DISABLE(result_necs->remap_domain.ptr, j);
+ continue;
+ }
+
+ if (!nla_blend_get_inverted_strip_value(upper_blendmode,
+ lower_necs->values[j],
+ blended_necs->values[j],
+ upper_influence,
+ &result_necs->values[j])) {
+
+ BLI_BITMAP_DISABLE(result_necs->remap_domain.ptr, j);
+ }
+ }
+ }
+ }
+}
+
/* ---------------------- */
/**
@@ -2675,74 +2793,66 @@ bool BKE_animsys_nla_remap_keyframe_values(struct NlaKeyframingContext *context,
return false;
}
- /* Find the evaluation channel for the NLA stack below current strip. */
- NlaEvalChannelKey key = {
- .ptr = *prop_ptr,
- .prop = prop,
- };
- /**
- * Remove lower NLA stack effects.
- *
- * Using the tweak strip's blended result and the lower snapshot value, we can solve for the
- * tweak strip value it must evaluate to.
- */
- NlaEvalData *const lower_eval_data = &context->lower_eval_data;
- NlaEvalChannel *const lower_nec = nlaevalchan_verify_key(lower_eval_data, NULL, &key);
+ /** Create \a blended_snapshot and fill with input \a values. */
+ NlaEvalData *eval_data = &context->lower_eval_data;
+ NlaEvalSnapshot blended_snapshot;
+ nlaeval_snapshot_init(&blended_snapshot, eval_data, NULL);
+ NlaEvalChannelSnapshot *blended_necs;
+ {
+ NlaEvalChannelKey key = {
+ .ptr = *prop_ptr,
+ .prop = prop,
+ };
+
+ NlaEvalChannel *nec = nlaevalchan_verify_key(eval_data, NULL, &key);
+ BLI_assert(nec);
+ if (nec->base_snapshot.length != count) {
+ BLI_assert(!"invalid value count");
+ nlaeval_snapshot_free_data(&blended_snapshot);
+ return false;
+ }
- if ((lower_nec->base_snapshot.length != count)) {
- BLI_assert(!"invalid value count");
- return false;
+ blended_necs = nlaeval_snapshot_ensure_channel(&blended_snapshot, nec);
+ memcpy(blended_necs->values, values, sizeof(float) * count);
+ BLI_bitmap_set_all(blended_necs->remap_domain.ptr, true, count);
}
- /* Invert the blending operation to compute the desired strip values. */
- NlaEvalChannelSnapshot *const lower_nec_snapshot = nlaeval_snapshot_find_channel(
- &lower_eval_data->eval_snapshot, lower_nec);
+ /** Remove lower NLA stack effects. */
+ nlasnapshot_blend_get_inverted_upper_snapshot(eval_data,
+ &context->lower_eval_data.eval_snapshot,
+ &blended_snapshot,
+ blend_mode,
+ influence,
+ &blended_snapshot);
- float *lower_values = lower_nec_snapshot->values;
-
- if (blend_mode == NLASTRIP_MODE_COMBINE) {
- /* Quaternion combine handles all sub-channels as a unit. */
- if (lower_nec->mix_mode == NEC_MIX_QUATERNION) {
- if (r_force_all == NULL) {
- return false;
- }
+ /** Write results into \a values. */
+ bool successful_remap = true;
+ if (blended_necs->channel->mix_mode == NEC_MIX_QUATERNION &&
+ blend_mode == NLASTRIP_MODE_COMBINE) {
+ if (r_force_all != NULL) {
*r_force_all = true;
-
- if (!nla_combine_quaternion_get_inverted_strip_values(
- lower_values, values, influence, values)) {
- return false;
- }
+ index = -1;
}
else {
- float *base_values = lower_nec->base_snapshot.values;
-
- for (int i = 0; i < count; i++) {
- if (ELEM(index, i, -1)) {
- if (!nla_combine_get_inverted_strip_value(lower_nec->mix_mode,
- base_values[i],
- lower_values[i],
- values[i],
- infl
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list