Anim: when creating action slot by keying, name it after last-used slot
When a new Action slot is created by keying a property, it is now named after the last-assigned slot. This is in support of the following scenario: - Action `A` is assigned, with slot `Legacy Slot`. - The slot is renamed to `Main Light`, because that's what being animated by it. - Animator wants to try an alternative animation, and unassigns the Action. - Animator starts keying the light, which creates Action `B` and a slot. - This slot is now also named `Main Light`, independently of the actual name of the light being animated. - Animator can switch between actions `A` and `B`, and because the slots have the same name, the auto-assignment Just Works™. Pull Request: https://projects.blender.org/blender/blender/pulls/131600
This commit is contained in:
@@ -210,7 +210,11 @@ class Action : public ::bAction {
|
||||
Slot &slot_add_for_id_type(ID_Type idtype);
|
||||
|
||||
/**
|
||||
* Create a new slot, named after the given ID, and limited to the ID's type.
|
||||
* Create a new slot suitable for the ID's type.
|
||||
*
|
||||
* The slot will be named after `animated_id.adt.last_slot_identifier`, defaulting to the ID's
|
||||
* name when that is not set. This is done so that toggling Actions works transparently, when
|
||||
* toggling between `this` and the Action last assigned to the ID.
|
||||
*
|
||||
* Note that this assigns neither this Action nor the new Slot to the ID. This function
|
||||
* merely initializes the Slot itself to suitable values to start animating this ID.
|
||||
|
||||
@@ -529,13 +529,28 @@ Slot &Action::slot_add_for_id_type(const ID_Type idtype)
|
||||
Slot &Action::slot_add_for_id(const ID &animated_id)
|
||||
{
|
||||
Slot &slot = this->slot_add();
|
||||
|
||||
slot.idtype = GS(animated_id.name);
|
||||
this->slot_identifier_define(slot, animated_id.name);
|
||||
|
||||
/* Determine the identifier for this slot, prioritising transparent
|
||||
* auto-selection when toggling between Actions. That's why the last-used slot
|
||||
* identifier is used here, and the ID name only as fallback. */
|
||||
const AnimData *adt = BKE_animdata_from_id(&animated_id);
|
||||
const StringRefNull last_slot_identifier = adt ? adt->last_slot_identifier : "";
|
||||
|
||||
StringRefNull slot_identifier = last_slot_identifier;
|
||||
if (slot_identifier.is_empty()) {
|
||||
slot_identifier = animated_id.name;
|
||||
}
|
||||
|
||||
this->slot_identifier_define(slot, slot_identifier);
|
||||
/* No need to call anim.slot_identifier_propagate() as nothing will be using
|
||||
* this brand new Slot yet. */
|
||||
|
||||
/* The last-used slot might have had a different ID type through some quirk (changes to linked
|
||||
* data, for example). So better ensure that the identifier prefix is correct on this new slot,
|
||||
* instead of relying for 100% on the old one. */
|
||||
slot.identifier_ensure_prefix();
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
|
||||
@@ -302,6 +302,22 @@ TEST_F(ActionLayersTest, add_slot)
|
||||
EXPECT_STREQ(cube->id.name, slot.identifier);
|
||||
EXPECT_EQ(ID_OB, slot.idtype);
|
||||
}
|
||||
|
||||
{ /* Creating a Slot for a specific ID that already had a slot assigned before should name it
|
||||
* after that previous slot. This should also ensure that the first two characters are actually
|
||||
* correct for the ID type. */
|
||||
AnimData *adt = BKE_animdata_ensure_id(&cube->id);
|
||||
STRNCPY_UTF8(adt->last_slot_identifier, "$$Kübuš 😹");
|
||||
Slot &slot = action->slot_add_for_id(cube->id);
|
||||
EXPECT_EQ(DNA_DEFAULT_ACTION_LAST_SLOT_HANDLE + 3, action->last_slot_handle);
|
||||
EXPECT_EQ(DNA_DEFAULT_ACTION_LAST_SLOT_HANDLE + 3, slot.handle);
|
||||
|
||||
EXPECT_STREQ("Kübuš 😹", slot.identifier + 2)
|
||||
<< "The last-assigned slot name should be reused";
|
||||
EXPECT_STREQ("OBKübuš 😹", slot.identifier)
|
||||
<< "The ID type encoded in the slot identifier should be correct";
|
||||
EXPECT_EQ(ID_OB, slot.idtype);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ActionLayersTest, add_slot__reset_idroot)
|
||||
|
||||
Reference in New Issue
Block a user