Motion Paths: only update once when transforming multiple bones or objects.
This commit is contained in:
parent
a415d521db
commit
fe6a6dee0b
|
@ -730,12 +730,16 @@ bool transdata_check_local_islands(TransInfo *t, short around);
|
|||
|
||||
int count_set_pose_transflags(struct Object *ob, const int mode, const short around, bool has_translate_rotate[2]);
|
||||
|
||||
/* auto-keying stuff used by special_aftertrans_update */
|
||||
void autokeyframe_ob_cb_func(
|
||||
/* Auto-keyframe applied after transform, returns true if motion paths need to be updated. */
|
||||
void autokeyframe_object(
|
||||
struct bContext *C, struct Scene *scene, struct ViewLayer *view_layer, struct Object *ob, int tmode);
|
||||
void autokeyframe_pose_cb_func(
|
||||
void autokeyframe_pose(
|
||||
struct bContext *C, struct Scene *scene, struct Object *ob, int tmode, short targetless_ik);
|
||||
|
||||
/* Test if we need to update motion paths for a given object. */
|
||||
bool motionpath_need_update_object(struct Scene *scene, struct Object *ob);
|
||||
bool motionpath_need_update_pose(struct Scene *scene, struct Object *ob);
|
||||
|
||||
/*********************** Constraints *****************************/
|
||||
|
||||
void drawConstraint(TransInfo *t);
|
||||
|
|
|
@ -5916,7 +5916,7 @@ static void clear_trans_object_base_flags(TransInfo *t)
|
|||
* tmode: should be 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
|
||||
void autokeyframe_ob_cb_func(bContext *C, Scene *scene, ViewLayer *view_layer, Object *ob, int tmode)
|
||||
void autokeyframe_object(bContext *C, Scene *scene, ViewLayer *view_layer, Object *ob, int tmode)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
ID *id = &ob->id;
|
||||
|
@ -6012,33 +6012,33 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, ViewLayer *view_layer, O
|
|||
ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
|
||||
}
|
||||
|
||||
/* only calculate paths if there are paths to be recalculated,
|
||||
* assuming that since we've autokeyed the transforms this is
|
||||
* now safe to apply...
|
||||
*
|
||||
* NOTE: only do this when there's context info
|
||||
*/
|
||||
if (C && (ob->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) {
|
||||
//ED_objects_clear_paths(C); // XXX for now, don't need to clear
|
||||
ED_objects_recalculate_paths(C, scene);
|
||||
|
||||
/* XXX: there's potential here for problems with unkeyed rotations/scale,
|
||||
* but for now (until proper data-locality for baking operations),
|
||||
* this should be a better fix for T24451 and T37755
|
||||
*/
|
||||
}
|
||||
|
||||
/* free temp info */
|
||||
BLI_freelistN(&dsources);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return if we need to update motion paths, only if they already exist,
|
||||
* and we will insert a keyframe at the end of transform. */
|
||||
bool motionpath_need_update_object(Scene *scene, Object *ob)
|
||||
{
|
||||
/* XXX: there's potential here for problems with unkeyed rotations/scale,
|
||||
* but for now (until proper data-locality for baking operations),
|
||||
* this should be a better fix for T24451 and T37755
|
||||
*/
|
||||
|
||||
if (autokeyframe_cfra_can_key(scene, &ob->id)) {
|
||||
return (ob->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) != 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* auto-keyframing feature - for poses/pose-channels
|
||||
* tmode: should be 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_cb_func(bContext *C, Scene *scene, Object *ob, int tmode, short targetless_ik)
|
||||
void autokeyframe_pose(bContext *C, Scene *scene, Object *ob, int tmode, short targetless_ik)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
ID *id = &ob->id;
|
||||
|
@ -6158,16 +6158,6 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, Object *ob, int tmode,
|
|||
BLI_freelistN(&dsources);
|
||||
}
|
||||
}
|
||||
|
||||
/* do the bone paths
|
||||
* - only do this when there is context info, since we need that to resolve
|
||||
* how to do the updates and so on...
|
||||
* - do not calculate unless there are paths already to update...
|
||||
*/
|
||||
if (C && (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) {
|
||||
//ED_pose_clear_paths(C, ob); // XXX for now, don't need to clear
|
||||
ED_pose_recalculate_paths(C, scene, ob);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* tag channels that should have unkeyed data */
|
||||
|
@ -6180,6 +6170,17 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, Object *ob, int tmode,
|
|||
}
|
||||
}
|
||||
|
||||
/* Return if we need to update motion paths, only if they already exist,
|
||||
* and we will insert a keyframe at the end of transform. */
|
||||
bool motionpath_need_update_pose(Scene *scene, Object *ob)
|
||||
{
|
||||
if (autokeyframe_cfra_can_key(scene, &ob->id)) {
|
||||
return (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) != 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void special_aftertrans_update__movieclip(bContext *C, TransInfo *t)
|
||||
{
|
||||
SpaceClip *sc = t->sa->spacedata.first;
|
||||
|
@ -6665,6 +6666,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
|
|||
}
|
||||
}
|
||||
else if (t->flag & T_POSE) {
|
||||
GSet *motionpath_updates = BLI_gset_ptr_new("motionpath updates");
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
|
||||
|
@ -6704,7 +6706,10 @@ void special_aftertrans_update(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)) {
|
||||
autokeyframe_pose_cb_func(C, t->scene, ob, t->mode, targetless_ik);
|
||||
autokeyframe_pose(C, t->scene, ob, t->mode, targetless_ik);
|
||||
if (motionpath_need_update_pose(t->scene, ob)) {
|
||||
BLI_gset_insert(motionpath_updates, ob);
|
||||
}
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
else if (arm->flag & ARM_DELAYDEFORM) {
|
||||
|
@ -6719,6 +6724,13 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
|
|||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update motion paths once for all transformed bones in an object. */
|
||||
GSetIterator gs_iter;
|
||||
GSET_ITER (gs_iter, motionpath_updates) {
|
||||
ob = BLI_gsetIterator_getKey(&gs_iter);
|
||||
ED_pose_recalculate_paths(C, t->scene, ob);
|
||||
}
|
||||
}
|
||||
else if (t->options & CTX_PAINT_CURVE) {
|
||||
/* pass */
|
||||
|
@ -6734,13 +6746,12 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
|
|||
/* do nothing */
|
||||
}
|
||||
else { /* Objects */
|
||||
int i;
|
||||
|
||||
BLI_assert(t->flag & (T_OBJECT | T_TEXTURE));
|
||||
|
||||
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
|
||||
bool motionpath_update = false;
|
||||
|
||||
for (i = 0; i < tc->data_len; i++) {
|
||||
for (int i = 0; i < tc->data_len; i++) {
|
||||
TransData *td = tc->data + i;
|
||||
ListBase pidlist;
|
||||
PTCacheID *pid;
|
||||
|
@ -6772,7 +6783,8 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
|
|||
|
||||
/* Set autokey if necessary */
|
||||
if (!canceled) {
|
||||
autokeyframe_ob_cb_func(C, t->scene, t->view_layer, ob, t->mode);
|
||||
autokeyframe_object(C, t->scene, t->view_layer, ob, t->mode);
|
||||
motionpath_update |= motionpath_need_update_object(t->scene, ob);
|
||||
}
|
||||
|
||||
/* restore rigid body transform */
|
||||
|
@ -6782,6 +6794,11 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
|
|||
BKE_rigidbody_aftertrans_update(ob, td->ext->oloc, td->ext->orot, td->ext->oquat, td->ext->orotAxis, td->ext->orotAngle);
|
||||
}
|
||||
}
|
||||
|
||||
if (motionpath_update) {
|
||||
/* Update motion paths once for all transformed objects. */
|
||||
ED_objects_recalculate_paths(C, t->scene);
|
||||
}
|
||||
}
|
||||
|
||||
clear_trans_object_base_flags(t);
|
||||
|
|
|
@ -937,6 +937,8 @@ static void recalcData_objects(TransInfo *t)
|
|||
|
||||
}
|
||||
else if (t->flag & T_POSE) {
|
||||
GSet *motionpath_updates = BLI_gset_ptr_new("motionpath updates");
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
Object *ob = tc->poseobj;
|
||||
bArmature *arm = ob->data;
|
||||
|
@ -952,7 +954,10 @@ static void recalcData_objects(TransInfo *t)
|
|||
int targetless_ik = (t->flag & T_AUTOIK); // XXX this currently doesn't work, since flags aren't set yet!
|
||||
|
||||
animrecord_check_state(t->scene, &ob->id, t->animtimer);
|
||||
autokeyframe_pose_cb_func(t->context, t->scene, ob, t->mode, targetless_ik);
|
||||
autokeyframe_pose(t->context, t->scene, ob, t->mode, targetless_ik);
|
||||
if (motionpath_need_update_pose(t->scene, ob)) {
|
||||
BLI_gset_insert(motionpath_updates, ob);
|
||||
}
|
||||
}
|
||||
|
||||
/* old optimize trick... this enforces to bypass the depgraph */
|
||||
|
@ -965,6 +970,13 @@ static void recalcData_objects(TransInfo *t)
|
|||
BKE_pose_where_is(t->depsgraph, t->scene, ob);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update motion paths once for all transformed bones in an object. */
|
||||
GSetIterator gs_iter;
|
||||
GSET_ITER (gs_iter, motionpath_updates) {
|
||||
Object *ob = BLI_gsetIterator_getKey(&gs_iter);
|
||||
ED_pose_recalculate_paths(t->context, t->scene, ob);
|
||||
}
|
||||
}
|
||||
else if (base && (base->object->mode & OB_MODE_PARTICLE_EDIT) &&
|
||||
PE_get_current(t->scene, base->object))
|
||||
|
@ -975,7 +987,7 @@ static void recalcData_objects(TransInfo *t)
|
|||
flushTransParticles(t);
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
bool motionpath_update = false;
|
||||
|
||||
if (t->state != TRANS_CANCEL) {
|
||||
applyProject(t);
|
||||
|
@ -984,7 +996,7 @@ static void recalcData_objects(TransInfo *t)
|
|||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
for (int i = 0; i < tc->data_len; i++, td++) {
|
||||
Object *ob = td->ob;
|
||||
|
||||
if (td->flag & TD_NOACTION)
|
||||
|
@ -1000,7 +1012,8 @@ static void recalcData_objects(TransInfo *t)
|
|||
// TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes?
|
||||
if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
|
||||
animrecord_check_state(t->scene, &ob->id, t->animtimer);
|
||||
autokeyframe_ob_cb_func(t->context, t->scene, t->view_layer, ob, t->mode);
|
||||
autokeyframe_object(t->context, t->scene, t->view_layer, ob, t->mode);
|
||||
motionpath_update |= motionpath_need_update_object(t->scene, ob);
|
||||
}
|
||||
|
||||
/* sets recalc flags fully, instead of flushing existing ones
|
||||
|
@ -1012,6 +1025,11 @@ static void recalcData_objects(TransInfo *t)
|
|||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
if (motionpath_update) {
|
||||
/* Update motion paths once for all transformed objects. */
|
||||
ED_objects_recalculate_paths(t->context, t->scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue