Fix #119946: NLA stack decomposition doesn't work with bones

The issue was that the `PointerRNA` passed to `BKE_animsys_get_nla_keyframing_context`
needs to point to an `ID` which wasn't the case when keying bones.
That is because internally the `FCurve` path is used to resolve the property.
This can only work from the `ID` because the `FCurve` path is always stored relative to that.
While the function doesn't fail when the property can't resolve the path, it won't actually do
the remapping when passing it to `BKE_animsys_nla_remap_keyframe_values` later.

Pull Request: https://projects.blender.org/blender/blender/pulls/120008
This commit is contained in:
Christoph Lendenfeld
2024-03-28 15:14:01 +01:00
committed by Thomas Dinges
parent e422383a12
commit 1e8890507e
3 changed files with 9 additions and 2 deletions
+3 -1
View File
@@ -949,9 +949,11 @@ void insert_key_rna(PointerRNA *rna_pointer,
/* Keyframing functions can deal with the nla_context being a nullptr. */ /* Keyframing functions can deal with the nla_context being a nullptr. */
ListBase nla_cache = {nullptr, nullptr}; ListBase nla_cache = {nullptr, nullptr};
NlaKeyframingContext *nla_context = nullptr; NlaKeyframingContext *nla_context = nullptr;
if (adt && adt->action == action) { if (adt && adt->action == action) {
PointerRNA id_pointer = RNA_id_pointer_create(id);
nla_context = BKE_animsys_get_nla_keyframing_context( nla_context = BKE_animsys_get_nla_keyframing_context(
&nla_cache, rna_pointer, adt, &anim_eval_context); &nla_cache, &id_pointer, adt, &anim_eval_context);
} }
const float nla_frame = BKE_nla_tweakedit_remap(adt, scene_frame, NLATIME_CONVERT_UNMAP); const float nla_frame = BKE_nla_tweakedit_remap(adt, scene_frame, NLATIME_CONVERT_UNMAP);
+1 -1
View File
@@ -238,7 +238,7 @@ typedef struct NlaKeyframingContext NlaKeyframingContext;
* *
* \param cache: List used to cache contexts for reuse when keying * \param cache: List used to cache contexts for reuse when keying
* multiple channels in one operation. * multiple channels in one operation.
* \param ptr: RNA pointer to the Object with the animation. * \param ptr: RNA pointer to the ID with the animation.
* \return Keyframing context, or NULL if not necessary. * \return Keyframing context, or NULL if not necessary.
*/ */
struct NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context( struct NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
@@ -3672,6 +3672,11 @@ void nlasnapshot_blend_get_inverted_lower_snapshot(NlaEvalData *eval_data,
NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context( NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
ListBase *cache, PointerRNA *ptr, AnimData *adt, const AnimationEvalContext *anim_eval_context) ListBase *cache, PointerRNA *ptr, AnimData *adt, const AnimationEvalContext *anim_eval_context)
{ {
/* The PointerRNA needs to point to an ID because animsys_evaluate_nla_for_keyframing uses
* F-Curve paths to resolve properties. Since F-Curve paths are always relative to the ID this
* would fail if the PointerRNA was e.g. a bone. */
BLI_assert(RNA_struct_is_ID(ptr->type));
/* No remapping needed if NLA is off or no action. */ /* No remapping needed if NLA is off or no action. */
if ((adt == nullptr) || (adt->action == nullptr) || (adt->nla_tracks.first == nullptr) || if ((adt == nullptr) || (adt->action == nullptr) || (adt->nla_tracks.first == nullptr) ||
(adt->flag & ADT_NLA_EVAL_OFF)) (adt->flag & ADT_NLA_EVAL_OFF))