Anim: support layered Actions when symmetrizing Action Constraint
The Symmetrize Action operator also updates Action Constraints, and even alters its Action to have identical (but mirrored) F-Curves for the bones. This now uses the new API for layered Actions, (hopefully) correctly storing the F-Curves and Action Groups. I suspect there is still a bug in there, but that's now equally there for legacy & layered Actions. Pull Request: https://projects.blender.org/blender/blender/pulls/128039
This commit is contained in:
@@ -439,7 +439,6 @@ static void updateDuplicateActionConstraintSettings(
|
||||
EditBone *dup_bone, EditBone *orig_bone, Object *ob, bPoseChannel *pchan, bConstraint *curcon)
|
||||
{
|
||||
bActionConstraint *act_con = (bActionConstraint *)curcon->data;
|
||||
bAction *act = (bAction *)act_con->act;
|
||||
|
||||
float mat[4][4];
|
||||
|
||||
@@ -512,18 +511,22 @@ static void updateDuplicateActionConstraintSettings(
|
||||
/* See if there is any channels that uses this bone */
|
||||
bAction *act = (bAction *)act_con->act;
|
||||
if (act) {
|
||||
blender::animrig::Action &action = act->wrap();
|
||||
blender::animrig::ChannelBag *cbag = blender::animrig::channelbag_for_action_slot(
|
||||
action, act_con->action_slot_handle);
|
||||
|
||||
/* Create a copy and mirror the animation */
|
||||
Vector<FCurve *> fcurves = blender::animrig::fcurve_find_in_action_slot_filtered(
|
||||
act, act_con->action_slot_handle, "pose.bones[", orig_bone->name);
|
||||
for (const FCurve *old_curve : fcurves) {
|
||||
FCurve *new_curve = BKE_fcurve_copy(old_curve);
|
||||
bActionGroup *agrp;
|
||||
|
||||
char *old_path = new_curve->rna_path;
|
||||
|
||||
new_curve->rna_path = BLI_string_replaceN(old_path, orig_bone->name, dup_bone->name);
|
||||
MEM_freeN(old_path);
|
||||
|
||||
/* FIXME: deal with the case where this F-Curve already exists. */
|
||||
|
||||
/* Flip the animation */
|
||||
int i;
|
||||
BezTriple *bezt;
|
||||
@@ -558,14 +561,21 @@ static void updateDuplicateActionConstraintSettings(
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure that a action group name for the new bone exists */
|
||||
agrp = BKE_action_group_find_name(act, dup_bone->name);
|
||||
|
||||
if (agrp == nullptr) {
|
||||
agrp = action_groups_add_new(act, dup_bone->name);
|
||||
if (action.is_action_legacy()) {
|
||||
/* Make sure that a action group name for the new bone exists */
|
||||
bActionGroup *agrp = BKE_action_group_find_name(act, dup_bone->name);
|
||||
if (agrp == nullptr) {
|
||||
agrp = action_groups_add_new(act, dup_bone->name);
|
||||
}
|
||||
BLI_assert(agrp != nullptr);
|
||||
action_groups_add_channel(act, agrp, new_curve);
|
||||
continue;
|
||||
}
|
||||
BLI_assert(agrp != nullptr);
|
||||
action_groups_add_channel(act, agrp, new_curve);
|
||||
|
||||
BLI_assert_msg(cbag, "If there are F-Curves for this slot, there should be a channelbag");
|
||||
bActionGroup &agrp = cbag->channel_group_ensure(dup_bone->name);
|
||||
cbag->fcurve_append(*new_curve);
|
||||
cbag->fcurve_assign_to_channel_group(*new_curve, agrp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user