Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/anim_sys.c
| Show First 20 Lines • Show All 1,146 Lines • ▼ Show 20 Lines | static void nlaeval_snapshot_free_data(NlaEvalSnapshot *snapshot) | ||||
| snapshot->channels = NULL; | snapshot->channels = NULL; | ||||
| } | } | ||||
| /* ---------------------- */ | /* ---------------------- */ | ||||
| /* Free memory owned by this evaluation channel. */ | /* Free memory owned by this evaluation channel. */ | ||||
| static void nlaevalchan_free_data(NlaEvalChannel *nec) | static void nlaevalchan_free_data(NlaEvalChannel *nec) | ||||
| { | { | ||||
| nlavalidmask_free(&nec->valid); | nlavalidmask_free(&nec->domain); | ||||
| if (nec->blend_snapshot != NULL) { | if (nec->blend_snapshot != NULL) { | ||||
| nlaevalchan_snapshot_free(nec->blend_snapshot); | nlaevalchan_snapshot_free(nec->blend_snapshot); | ||||
| } | } | ||||
| } | } | ||||
| /* Initialize a full NLA evaluation state structure. */ | /* Initialize a full NLA evaluation state structure. */ | ||||
| static void nlaeval_init(NlaEvalData *nlaeval) | static void nlaeval_init(NlaEvalData *nlaeval) | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | static NlaEvalChannel *nlaevalchan_verify_key(NlaEvalData *nlaeval, | ||||
| nec->key = *key; | nec->key = *key; | ||||
| nec->owner = nlaeval; | nec->owner = nlaeval; | ||||
| nec->index = nlaeval->num_channels++; | nec->index = nlaeval->num_channels++; | ||||
| nec->is_array = is_array; | nec->is_array = is_array; | ||||
| nec->mix_mode = nlaevalchan_detect_mix_mode(key, length); | nec->mix_mode = nlaevalchan_detect_mix_mode(key, length); | ||||
| nlavalidmask_init(&nec->valid, length); | nlavalidmask_init(&nec->domain, length); | ||||
| nec->base_snapshot.channel = nec; | nec->base_snapshot.channel = nec; | ||||
| nec->base_snapshot.length = length; | nec->base_snapshot.length = length; | ||||
| nec->base_snapshot.is_base = true; | nec->base_snapshot.is_base = true; | ||||
| nlaevalchan_get_default_values(nec, nec->base_snapshot.values); | nlaevalchan_get_default_values(nec, nec->base_snapshot.values); | ||||
| /* Store channel in data structures. */ | /* Store channel in data structures. */ | ||||
| ▲ Show 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | case NLASTRIP_MODE_MULTIPLY: | ||||
| * blended_value - (1 - inf) * lower_value = inf * (lower_value * strip_value) | * blended_value - (1 - inf) * lower_value = inf * (lower_value * strip_value) | ||||
| * (blended_value - (1 - inf) * lower_value) / (inf * lower_value) = strip_value | * (blended_value - (1 - inf) * lower_value) / (inf * lower_value) = strip_value | ||||
| * (blended_value - lower_value + inf * lower_value) / (inf * lower_value) = strip_value | * (blended_value - lower_value + inf * lower_value) / (inf * lower_value) = strip_value | ||||
| * ((blended_value - lower_value) / (inf * lower_value)) + 1 = strip_value | * ((blended_value - lower_value) / (inf * lower_value)) + 1 = strip_value | ||||
| * | * | ||||
| * strip_value = ((blended_value - lower_value) / (inf * lower_value)) + 1 | * strip_value = ((blended_value - lower_value) / (inf * lower_value)) + 1 | ||||
| */ | */ | ||||
| *r_strip_value = ((blended_value - lower_value) / (influence * lower_value)) + 1.0f; | *r_strip_value = ((blended_value - lower_value) / (influence * lower_value)) + 1.0f; | ||||
| return true; | return true; | ||||
| case NLASTRIP_MODE_COMBINE: | case NLASTRIP_MODE_COMBINE: | ||||
| BLI_assert(!"combine mode"); | BLI_assert(!"combine mode"); | ||||
| ATTR_FALLTHROUGH; | ATTR_FALLTHROUGH; | ||||
| default: | default: | ||||
| /** Math: | /** Math: | ||||
| * | * | ||||
| * blended_value = lower_value * (1.0f - inf) + (strip_value * inf) | * blended_value = lower_value * (1.0f - inf) + (strip_value * inf) | ||||
| * blended_value - lower_value * (1.0f - inf) = (strip_value * inf) | * blended_value - lower_value * (1.0f - inf) = (strip_value * inf) | ||||
| * (blended_value - lower_value * (1.0f - inf)) / inf = strip_value | * (blended_value - lower_value * (1.0f - inf)) / inf = strip_value | ||||
| * | * | ||||
| * strip_value = (blended_value - lower_value * (1.0f - inf)) / inf | * strip_value = (blended_value - lower_value * (1.0f - inf)) / inf | ||||
| */ | */ | ||||
| *r_strip_value = (blended_value - lower_value * (1.0f - influence)) / influence; | *r_strip_value = (blended_value - lower_value * (1.0f - influence)) / influence; | ||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| /** \returns true if solution exists and output is written to. */ | /** \returns true if solution exists and output is written to. */ | ||||
| static bool nla_combine_get_inverted_strip_value(const int mix_mode, | static bool nla_combine_get_inverted_strip_value(const int mix_mode, | ||||
| float base_value, | float base_value, | ||||
| const float lower_value, | const float lower_value, | ||||
| const float blended_value, | const float blended_value, | ||||
| const float influence, | const float influence, | ||||
| float *r_strip_value) | float *r_strip_value) | ||||
| { | { | ||||
| /* No solution if strip had no influence. */ | /* No solution if strip had no influence. */ | ||||
| if (IS_EQF(influence, 0.0f)) { | if (IS_EQF(influence, 0.0f)) { | ||||
| return false; | return false; | ||||
| ▲ Show 20 Lines • Show All 110 Lines • ▼ Show 20 Lines | static bool nlaeval_blend_value(NlaBlendData *blend, | ||||
| } | } | ||||
| if (!nlaevalchan_validate_index_ex(nec, array_index)) { | if (!nlaevalchan_validate_index_ex(nec, array_index)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (nec->mix_mode == NEC_MIX_QUATERNION) { | if (nec->mix_mode == NEC_MIX_QUATERNION) { | ||||
| /* For quaternion properties, always output all sub-channels. */ | /* For quaternion properties, always output all sub-channels. */ | ||||
| BLI_bitmap_set_all(nec->valid.ptr, true, 4); | BLI_bitmap_set_all(nec->domain.ptr, true, 4); | ||||
| } | } | ||||
| else { | else { | ||||
| BLI_BITMAP_ENABLE(nec->valid.ptr, array_index); | BLI_BITMAP_ENABLE(nec->domain.ptr, array_index); | ||||
| } | } | ||||
| NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_ensure_channel(blend->snapshot, nec); | NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_ensure_channel(blend->snapshot, nec); | ||||
| float *p_value = &nec_snapshot->values[array_index]; | float *p_value = &nec_snapshot->values[array_index]; | ||||
| if (blend->mode == NLASTRIP_MODE_COMBINE) { | if (blend->mode == NLASTRIP_MODE_COMBINE) { | ||||
| /* Quaternion blending is deferred until all sub-channel values are known. */ | /* Quaternion blending is deferred until all sub-channel values are known. */ | ||||
| if (nec->mix_mode == NEC_MIX_QUATERNION) { | if (nec->mix_mode == NEC_MIX_QUATERNION) { | ||||
| ▲ Show 20 Lines • Show All 395 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| /* sanity checks */ | /* sanity checks */ | ||||
| if (channels == NULL) { | if (channels == NULL) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* for each channel with accumulated values, write its value on the property it affects */ | /* for each channel with accumulated values, write its value on the property it affects */ | ||||
| LISTBASE_FOREACH (NlaEvalChannel *, nec, &channels->channels) { | LISTBASE_FOREACH (NlaEvalChannel *, nec, &channels->channels) { | ||||
| /** | |||||
| * The bitmask is set for all channels touched by NLA due to the domain() function. | |||||
| * Channels touched by current set of evaluated strips will have a snapshot channel directly | |||||
| * from the evaluation snapshot. | |||||
| * | |||||
| * This function falls back to the default value if the snapshot channel doesn't exist. | |||||
| * Thus channels, touched by NLA but not by the current set of evaluated strips, will be | |||||
| * reset to default. If channel not touched by NLA then it's value is unchanged. | |||||
| */ | |||||
| NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_find_channel(snapshot, nec); | NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_find_channel(snapshot, nec); | ||||
| PathResolvedRNA rna = {nec->key.ptr, nec->key.prop, -1}; | PathResolvedRNA rna = {nec->key.ptr, nec->key.prop, -1}; | ||||
| for (int i = 0; i < nec_snapshot->length; i++) { | for (int i = 0; i < nec_snapshot->length; i++) { | ||||
| if (BLI_BITMAP_TEST(nec->valid.ptr, i)) { | if (BLI_BITMAP_TEST(nec->domain.ptr, i)) { | ||||
| float value = nec_snapshot->values[i]; | float value = nec_snapshot->values[i]; | ||||
| if (nec->is_array) { | if (nec->is_array) { | ||||
| rna.prop_index = i; | rna.prop_index = i; | ||||
| } | } | ||||
| BKE_animsys_write_rna_setting(&rna, value); | BKE_animsys_write_rna_setting(&rna, value); | ||||
| if (flush_to_original) { | if (flush_to_original) { | ||||
| animsys_write_orig_anim_rna(ptr, nec->rna_path, rna.prop_index, value); | animsys_write_orig_anim_rna(ptr, nec->rna_path, rna.prop_index, value); | ||||
| } | } | ||||
| Show All 25 Lines | if (BKE_fcurve_is_empty(fcu)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| NlaEvalChannel *nec = nlaevalchan_verify(ptr, channels, fcu->rna_path); | NlaEvalChannel *nec = nlaevalchan_verify(ptr, channels, fcu->rna_path); | ||||
| if (nec != NULL) { | if (nec != NULL) { | ||||
| /* For quaternion properties, enable all sub-channels. */ | /* For quaternion properties, enable all sub-channels. */ | ||||
| if (nec->mix_mode == NEC_MIX_QUATERNION) { | if (nec->mix_mode == NEC_MIX_QUATERNION) { | ||||
| BLI_bitmap_set_all(nec->valid.ptr, true, 4); | BLI_bitmap_set_all(nec->domain.ptr, true, 4); | ||||
| continue; | continue; | ||||
| } | } | ||||
| int idx = nlaevalchan_validate_index(nec, fcu->array_index); | int idx = nlaevalchan_validate_index(nec, fcu->array_index); | ||||
| if (idx >= 0) { | if (idx >= 0) { | ||||
| BLI_BITMAP_ENABLE(nec->valid.ptr, idx); | BLI_BITMAP_ENABLE(nec->domain.ptr, idx); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void nla_eval_domain_strips(PointerRNA *ptr, | static void nla_eval_domain_strips(PointerRNA *ptr, | ||||
| NlaEvalData *channels, | NlaEvalData *channels, | ||||
| ListBase *strips, | ListBase *strips, | ||||
| ▲ Show 20 Lines • Show All 396 Lines • ▼ Show 20 Lines | if (lower_nec->mix_mode == NEC_MIX_QUATERNION) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| *r_force_all = true; | *r_force_all = true; | ||||
| if (!nla_combine_quaternion_get_inverted_strip_values( | if (!nla_combine_quaternion_get_inverted_strip_values( | ||||
| lower_values, values, influence, values)) { | lower_values, values, influence, values)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| float *base_values = lower_nec->base_snapshot.values; | float *base_values = lower_nec->base_snapshot.values; | ||||
| for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| if (ELEM(index, i, -1)) { | if (ELEM(index, i, -1)) { | ||||
| if (!nla_combine_get_inverted_strip_value(lower_nec->mix_mode, | if (!nla_combine_get_inverted_strip_value(lower_nec->mix_mode, | ||||
| base_values[i], | base_values[i], | ||||
| lower_values[i], | lower_values[i], | ||||
| values[i], | values[i], | ||||
| influence, | influence, | ||||
| &values[i])) { | &values[i])) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| ▲ Show 20 Lines • Show All 407 Lines • Show Last 20 Lines | |||||