Anim: Don't use keying sets when inserting keyframes during autokeying
Prior to this PR, the autokeying system used keying sets to insert keyframes where required. With the functions introduced in #113504 the code can be simplified and made to not rely on keying sets, allowing autokeying to also insert keys by rna path directly. This also removes all the code related to "Insert Needed" from autokeying. The insert key functions deal with that now, all that is needed is to pass in the flag. Part of #113278 Pull Request: https://projects.blender.org/blender/blender/pulls/115522
This commit is contained in:
committed by
Christoph Lendenfeld
parent
a8e13994b8
commit
92ad16ab90
@@ -142,13 +142,10 @@ bool is_autokey_flag(const Scene *scene, eKeyInsert_Flag flag);
|
||||
*/
|
||||
bool autokeyframe_cfra_can_key(const Scene *scene, ID *id);
|
||||
|
||||
void autokeyframe_object(
|
||||
bContext *C, Scene *scene, ViewLayer *view_layer, Object *ob, eTfmMode tmode);
|
||||
void autokeyframe_object(bContext *C, Scene *scene, Object *ob);
|
||||
/**
|
||||
* Auto-keyframing feature - for objects
|
||||
*
|
||||
* \param tmode: A transform mode.
|
||||
*
|
||||
* \note Context may not always be available,
|
||||
* so must check before using it as it's a luxury for a few cases.
|
||||
*/
|
||||
@@ -157,14 +154,12 @@ bool autokeyframe_pchan(bContext *C, Scene *scene, Object *ob, bPoseChannel *pch
|
||||
/**
|
||||
* Auto-keyframing feature - for poses/pose-channels
|
||||
*
|
||||
* \param tmode: A transform mode.
|
||||
*
|
||||
* targetless_ik: has targetless ik been done on any channels?
|
||||
*
|
||||
* \note Context may not always be available,
|
||||
* so must check before using it as it's a luxury for a few cases.
|
||||
*/
|
||||
void autokeyframe_pose(bContext *C, Scene *scene, Object *ob, int tmode, short targetless_ik);
|
||||
void autokeyframe_pose(bContext *C, Scene *scene, Object *ob, short targetless_ik);
|
||||
/**
|
||||
* Use for auto-key-framing.
|
||||
* \param only_if_property_keyed: if true, auto-key-framing only creates keyframes on already keyed
|
||||
|
||||
@@ -82,10 +82,20 @@ bool autokeyframe_cfra_can_key(const Scene *scene, ID *id)
|
||||
return true;
|
||||
}
|
||||
|
||||
void autokeyframe_object(
|
||||
bContext *C, Scene *scene, ViewLayer *view_layer, Object *ob, const eTfmMode tmode)
|
||||
static std::string get_rotation_mode_path(const eRotationModes rotmode)
|
||||
{
|
||||
switch (rotmode) {
|
||||
case ROT_MODE_QUAT:
|
||||
return "rotation_quaternion";
|
||||
case ROT_MODE_AXISANGLE:
|
||||
return "rotation_axis_angle";
|
||||
default:
|
||||
return "rotation_euler";
|
||||
}
|
||||
}
|
||||
|
||||
void autokeyframe_object(bContext *C, Scene *scene, Object *ob)
|
||||
{
|
||||
/* TODO: this should probably be done per channel instead. */
|
||||
ID *id = &ob->id;
|
||||
if (!autokeyframe_cfra_can_key(scene, id)) {
|
||||
return;
|
||||
@@ -96,10 +106,9 @@ void autokeyframe_object(
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
||||
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
|
||||
depsgraph, BKE_scene_frame_get(scene));
|
||||
eInsertKeyFlags flag = eInsertKeyFlags(0);
|
||||
|
||||
/* Get flags used for inserting keyframes. */
|
||||
flag = ANIM_get_keyframing_flags(scene, true);
|
||||
const eInsertKeyFlags flag = ANIM_get_keyframing_flags(scene, true);
|
||||
|
||||
/* Add data-source override for the object. */
|
||||
blender::Vector<PointerRNA> sources;
|
||||
@@ -112,9 +121,10 @@ void autokeyframe_object(
|
||||
*/
|
||||
ANIM_apply_keyingset(
|
||||
C, &sources, active_ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
|
||||
return;
|
||||
}
|
||||
|
||||
else if (is_autokey_flag(scene, AUTOKEY_FLAG_INSERTAVAILABLE)) {
|
||||
if (is_autokey_flag(scene, AUTOKEY_FLAG_INSERTAVAILABLE)) {
|
||||
/* Only key on available channels. */
|
||||
AnimData *adt = ob->adt;
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
@@ -134,64 +144,22 @@ void autokeyframe_object(
|
||||
flag);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
else if (is_autokey_flag(scene, AUTOKEY_FLAG_INSERTNEEDED)) {
|
||||
bool do_loc = false, do_rot = false, do_scale = false;
|
||||
const float scene_frame = BKE_scene_frame_get(scene);
|
||||
std::string rotation_rna_path = get_rotation_mode_path(eRotationModes(ob->rotmode));
|
||||
Vector<std::string> rna_paths = {"location", rotation_rna_path, "scale"};
|
||||
Main *bmain = CTX_data_main(C);
|
||||
|
||||
/* Filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D). */
|
||||
if (tmode == TFM_TRANSLATION) {
|
||||
do_loc = true;
|
||||
}
|
||||
else if (ELEM(tmode, TFM_ROTATION, TFM_TRACKBALL)) {
|
||||
if (scene->toolsettings->transform_pivot_point == V3D_AROUND_ACTIVE) {
|
||||
BKE_view_layer_synced_ensure(scene, view_layer);
|
||||
if (ob != BKE_view_layer_active_object_get(view_layer)) {
|
||||
do_loc = true;
|
||||
}
|
||||
}
|
||||
else if (scene->toolsettings->transform_pivot_point == V3D_AROUND_CURSOR) {
|
||||
do_loc = true;
|
||||
}
|
||||
|
||||
if ((scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) == 0) {
|
||||
do_rot = true;
|
||||
}
|
||||
}
|
||||
else if (tmode == TFM_RESIZE) {
|
||||
if (scene->toolsettings->transform_pivot_point == V3D_AROUND_ACTIVE) {
|
||||
BKE_view_layer_synced_ensure(scene, view_layer);
|
||||
if (ob != BKE_view_layer_active_object_get(view_layer)) {
|
||||
do_loc = true;
|
||||
}
|
||||
}
|
||||
else if (scene->toolsettings->transform_pivot_point == V3D_AROUND_CURSOR) {
|
||||
do_loc = true;
|
||||
}
|
||||
|
||||
if ((scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) == 0) {
|
||||
do_scale = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_loc) {
|
||||
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_LOCATION_ID);
|
||||
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
|
||||
}
|
||||
if (do_rot) {
|
||||
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_ROTATION_ID);
|
||||
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
|
||||
}
|
||||
if (do_scale) {
|
||||
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_SCALING_ID);
|
||||
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert keyframe in all (transform) channels. */
|
||||
else {
|
||||
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_LOC_ROT_SCALE_ID);
|
||||
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
|
||||
for (PointerRNA ptr : sources) {
|
||||
insert_key_rna(&ptr,
|
||||
rna_paths.as_span(),
|
||||
scene_frame,
|
||||
flag,
|
||||
eBezTriple_KeyframeType(scene->toolsettings->keyframe_type),
|
||||
bmain,
|
||||
reports);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +199,7 @@ bool autokeyframe_pchan(bContext *C, Scene *scene, Object *ob, bPoseChannel *pch
|
||||
return true;
|
||||
}
|
||||
|
||||
void autokeyframe_pose(bContext *C, Scene *scene, Object *ob, int tmode, short targetless_ik)
|
||||
void autokeyframe_pose(bContext *C, Scene *scene, Object *ob, short targetless_ik)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
ID *id = &ob->id;
|
||||
@@ -247,16 +215,16 @@ void autokeyframe_pose(bContext *C, Scene *scene, Object *ob, int tmode, short t
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene);
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
||||
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
|
||||
depsgraph, BKE_scene_frame_get(scene));
|
||||
eInsertKeyFlags flag = eInsertKeyFlags(0);
|
||||
const float scene_frame = BKE_scene_frame_get(scene);
|
||||
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
|
||||
scene_frame);
|
||||
|
||||
/* flag is initialized from UserPref keyframing settings
|
||||
* - special exception for targetless IK - INSERTKEY_MATRIX keyframes should get
|
||||
* visual keyframes even if flag not set, as it's not that useful otherwise
|
||||
* (for quick animation recording)
|
||||
*/
|
||||
flag = ANIM_get_keyframing_flags(scene, true);
|
||||
eInsertKeyFlags flag = ANIM_get_keyframing_flags(scene, true);
|
||||
|
||||
if (targetless_ik) {
|
||||
flag |= INSERTKEY_MATRIX;
|
||||
@@ -278,87 +246,51 @@ void autokeyframe_pose(bContext *C, Scene *scene, Object *ob, int tmode, short t
|
||||
/* Run the active Keying Set on the current data-source. */
|
||||
ANIM_apply_keyingset(
|
||||
C, &sources, active_ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* only insert into available channels? */
|
||||
else if (blender::animrig::is_autokey_flag(scene, AUTOKEY_FLAG_INSERTAVAILABLE)) {
|
||||
if (act) {
|
||||
LISTBASE_FOREACH (FCurve *, fcu, &act->curves) {
|
||||
/* only insert keyframes for this F-Curve if it affects the current bone */
|
||||
char pchan_name[sizeof(pchan->name)];
|
||||
if (!BLI_str_quoted_substr(fcu->rna_path, "bones[", pchan_name, sizeof(pchan_name))) {
|
||||
continue;
|
||||
}
|
||||
if (blender::animrig::is_autokey_flag(scene, AUTOKEY_FLAG_INSERTAVAILABLE)) {
|
||||
if (!act) {
|
||||
continue;
|
||||
}
|
||||
LISTBASE_FOREACH (FCurve *, fcu, &act->curves) {
|
||||
/* only insert keyframes for this F-Curve if it affects the current bone */
|
||||
char pchan_name[sizeof(pchan->name)];
|
||||
if (!BLI_str_quoted_substr(fcu->rna_path, "bones[", pchan_name, sizeof(pchan_name))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* only if bone name matches too...
|
||||
* NOTE: this will do constraints too, but those are ok to do here too?
|
||||
*/
|
||||
if (STREQ(pchan_name, pchan->name)) {
|
||||
blender::animrig::insert_keyframe(bmain,
|
||||
reports,
|
||||
id,
|
||||
act,
|
||||
((fcu->grp) ? (fcu->grp->name) : (nullptr)),
|
||||
fcu->rna_path,
|
||||
fcu->array_index,
|
||||
&anim_eval_context,
|
||||
eBezTriple_KeyframeType(ts->keyframe_type),
|
||||
flag);
|
||||
}
|
||||
/* only if bone name matches too...
|
||||
* NOTE: this will do constraints too, but those are ok to do here too?
|
||||
*/
|
||||
if (STREQ(pchan_name, pchan->name)) {
|
||||
blender::animrig::insert_keyframe(bmain,
|
||||
reports,
|
||||
id,
|
||||
act,
|
||||
((fcu->grp) ? (fcu->grp->name) : (nullptr)),
|
||||
fcu->rna_path,
|
||||
fcu->array_index,
|
||||
&anim_eval_context,
|
||||
eBezTriple_KeyframeType(ts->keyframe_type),
|
||||
flag);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* only insert keyframe if needed? */
|
||||
else if (blender::animrig::is_autokey_flag(scene, AUTOKEY_FLAG_INSERTNEEDED)) {
|
||||
bool do_loc = false, do_rot = false, do_scale = false;
|
||||
|
||||
/* Filter the conditions when this happens
|
||||
* (assume that 'curarea->spacetype == SPACE_VIEW3D'). */
|
||||
if (tmode == TFM_TRANSLATION) {
|
||||
if (targetless_ik) {
|
||||
do_rot = true;
|
||||
}
|
||||
else {
|
||||
do_loc = true;
|
||||
}
|
||||
}
|
||||
else if (ELEM(tmode, TFM_ROTATION, TFM_TRACKBALL)) {
|
||||
if (ELEM(scene->toolsettings->transform_pivot_point, V3D_AROUND_CURSOR, V3D_AROUND_ACTIVE))
|
||||
{
|
||||
do_loc = true;
|
||||
}
|
||||
|
||||
if ((scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) == 0) {
|
||||
do_rot = true;
|
||||
}
|
||||
}
|
||||
else if (tmode == TFM_RESIZE) {
|
||||
if (ELEM(scene->toolsettings->transform_pivot_point, V3D_AROUND_CURSOR, V3D_AROUND_ACTIVE))
|
||||
{
|
||||
do_loc = true;
|
||||
}
|
||||
|
||||
if ((scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) == 0) {
|
||||
do_scale = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_loc) {
|
||||
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_LOCATION_ID);
|
||||
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
|
||||
}
|
||||
if (do_rot) {
|
||||
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_ROTATION_ID);
|
||||
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
|
||||
}
|
||||
if (do_scale) {
|
||||
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_SCALING_ID);
|
||||
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
|
||||
}
|
||||
}
|
||||
/* insert keyframe in all (transform) channels */
|
||||
else {
|
||||
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_LOC_ROT_SCALE_ID);
|
||||
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
|
||||
Main *bmain = CTX_data_main(C);
|
||||
std::string rotation_rna_path = get_rotation_mode_path(eRotationModes(pchan->rotmode));
|
||||
Vector<std::string> rna_paths = {"location", rotation_rna_path, "scale"};
|
||||
for (PointerRNA &ptr : sources) {
|
||||
insert_key_rna(&ptr,
|
||||
rna_paths,
|
||||
scene_frame,
|
||||
flag,
|
||||
eBezTriple_KeyframeType(scene->toolsettings->keyframe_type),
|
||||
bmain,
|
||||
reports);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1326,7 +1326,7 @@ static void recalcData_pose(TransInfo *t)
|
||||
int targetless_ik = (t->flag & T_AUTOIK);
|
||||
|
||||
animrecord_check_state(t, &ob->id);
|
||||
blender::animrig::autokeyframe_pose(t->context, t->scene, ob, t->mode, targetless_ik);
|
||||
blender::animrig::autokeyframe_pose(t->context, t->scene, ob, targetless_ik);
|
||||
}
|
||||
|
||||
if (motionpath_need_update_pose(t->scene, ob)) {
|
||||
@@ -1589,7 +1589,7 @@ static void special_aftertrans_update__pose(bContext *C, TransInfo *t)
|
||||
/* automatic inserting of keys and unkeyed tagging -
|
||||
* only if transform wasn't canceled (or TFM_DUMMY) */
|
||||
if (!canceled && (t->mode != TFM_DUMMY)) {
|
||||
blender::animrig::autokeyframe_pose(C, t->scene, ob, t->mode, targetless_ik);
|
||||
blender::animrig::autokeyframe_pose(C, t->scene, ob, targetless_ik);
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -780,7 +780,7 @@ static void recalcData_objects(TransInfo *t)
|
||||
* (FPoints) instead of keyframes? */
|
||||
if ((t->animtimer) && blender::animrig::is_autokey_on(t->scene)) {
|
||||
animrecord_check_state(t, &ob->id);
|
||||
blender::animrig::autokeyframe_object(t->context, t->scene, t->view_layer, ob, t->mode);
|
||||
blender::animrig::autokeyframe_object(t->context, t->scene, ob);
|
||||
}
|
||||
|
||||
motionpath_update |= motionpath_need_update_object(t->scene, ob);
|
||||
@@ -855,7 +855,7 @@ static void special_aftertrans_update__object(bContext *C, TransInfo *t)
|
||||
|
||||
/* Set auto-key if necessary. */
|
||||
if (!canceled) {
|
||||
blender::animrig::autokeyframe_object(C, t->scene, t->view_layer, ob, t->mode);
|
||||
blender::animrig::autokeyframe_object(C, t->scene, ob);
|
||||
}
|
||||
|
||||
motionpath_update |= motionpath_need_update_object(t->scene, ob);
|
||||
|
||||
Reference in New Issue
Block a user