== Bone Paths - Auto-Recalc Improvements ==
Added a new function which specially caters for auto-recalculation of paths after updates (such as keyframing). Currently, all that differs between this and pose_calculate_path, is that it only recalculates for bones with paths. Also, it only updates what it needs to (minimum frame range affected). Warning: WIP commit (hopefully it compiles ok)
This commit is contained in:
@@ -61,6 +61,7 @@ void paste_posebuf (int flip);
|
||||
void pose_adds_vgroups(struct Object *meshobj, int heatweights);
|
||||
|
||||
void pose_calculate_path(struct Object *ob);
|
||||
void pose_recalculate_paths(struct Object *ob);
|
||||
void pose_clear_paths(struct Object *ob);
|
||||
|
||||
void pose_flip_names(void);
|
||||
|
||||
@@ -3275,7 +3275,7 @@ void common_insertkey(void)
|
||||
/* recalculate bone-paths on adding new keyframe? */
|
||||
// TODO: currently, there is no setting to turn this on/off globally
|
||||
if (recalc_bonepaths)
|
||||
pose_calculate_path(ob);
|
||||
pose_recalculate_paths(ob);
|
||||
|
||||
|
||||
allqueue(REDRAWIPO, 0);
|
||||
|
||||
@@ -289,7 +289,7 @@ void pose_calculate_path(Object *ob)
|
||||
}
|
||||
|
||||
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
|
||||
if (pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
|
||||
if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
|
||||
if (arm->layer & pchan->bone->layer) {
|
||||
if (pchan->path) {
|
||||
fp= pchan->path+3*(CFRA-sfra);
|
||||
@@ -315,6 +315,90 @@ void pose_calculate_path(Object *ob)
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
}
|
||||
|
||||
/* For the object with pose/action: update paths for those that have got them
|
||||
* This should selectively update paths that exist...
|
||||
*/
|
||||
void pose_recalculate_paths(Object *ob)
|
||||
{
|
||||
bArmature *arm;
|
||||
bPoseChannel *pchan;
|
||||
Base *base;
|
||||
float *fp;
|
||||
int cfra;
|
||||
int sfra, efra;
|
||||
|
||||
if (ob==NULL || ob->pose==NULL)
|
||||
return;
|
||||
arm= ob->data;
|
||||
|
||||
/* set frame values */
|
||||
cfra = CFRA;
|
||||
sfra = efra = cfra;
|
||||
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
|
||||
if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
|
||||
if (pchan->path) {
|
||||
/* if the pathsf and pathef aren't initialised, abort! */
|
||||
if (ELEM(0, pchan->pathsf, pchan->pathef))
|
||||
return;
|
||||
|
||||
/* try to increase area to do (only as much as needed) */
|
||||
sfra= MIN2(sfra, pchan->pathsf);
|
||||
efra= MAX2(efra, pchan->pathef);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (efra <= sfra) return;
|
||||
|
||||
waitcursor(1);
|
||||
|
||||
/* hack: for unsaved files, set OB_RECALC so that paths can get calculated */
|
||||
if ((ob->recalc & OB_RECALC)==0) {
|
||||
ob->recalc |= OB_RECALC;
|
||||
DAG_object_update_flags(G.scene, ob, screen_view3d_layers());
|
||||
}
|
||||
else
|
||||
DAG_object_update_flags(G.scene, ob, screen_view3d_layers());
|
||||
|
||||
for (CFRA=sfra; CFRA<=efra; CFRA++) {
|
||||
/* do all updates */
|
||||
for (base= FIRSTBASE; base; base= base->next) {
|
||||
if (base->object->recalc) {
|
||||
int temp= base->object->recalc;
|
||||
object_handle_update(base->object);
|
||||
base->object->recalc= temp;
|
||||
}
|
||||
}
|
||||
|
||||
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
|
||||
if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
|
||||
if (pchan->path) {
|
||||
/* only update if:
|
||||
* - in range of this pchan's existing path
|
||||
* - ... insert evil filtering/optimising conditions here...
|
||||
*/
|
||||
if (IN_RANGE(CFRA, pchan->pathsf, pchan->pathef)) {
|
||||
fp= pchan->path+3*(CFRA-sfra);
|
||||
|
||||
if (arm->pathflag & ARM_PATH_HEADS) {
|
||||
VECCOPY(fp, pchan->pose_head);
|
||||
}
|
||||
else {
|
||||
VECCOPY(fp, pchan->pose_tail);
|
||||
}
|
||||
|
||||
Mat4MulVecfl(ob->obmat, fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
waitcursor(0);
|
||||
|
||||
CFRA= cfra;
|
||||
allqueue(REDRAWVIEW3D, 0); /* recalc tags are still there */
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
}
|
||||
|
||||
/* for the object with pose/action: clear path curves for selected bones only */
|
||||
void pose_clear_paths(Object *ob)
|
||||
|
||||
@@ -3075,7 +3075,7 @@ void autokeyframe_pose_cb_func(Object *ob, int tmode, short targetless_ik)
|
||||
/* do the bone paths */
|
||||
if (arm->pathflag & ARM_PATH_ACFRA) {
|
||||
//pose_clear_paths(ob);
|
||||
pose_calculate_path(ob);
|
||||
pose_recalculate_paths(ob);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user