== Auto-Keyframing ==

I've moved the Auto-Keyframing functionality out of the special_aftertrans_update function into two separate functions, which can be called independent of the Transform system. One is for Bones, while the other is for Objects.

This now means that the Shift-S Snapping Tools will now work with auto-keyframing.
This commit is contained in:
2007-06-23 06:56:16 +00:00
parent ca26aeb7b2
commit 1c41d19964
3 changed files with 191 additions and 144 deletions

View File

@@ -44,6 +44,7 @@ struct NumInput;
struct Object; struct Object;
struct View3D; struct View3D;
struct ScrArea; struct ScrArea;
struct bPose;
typedef struct NumInput { typedef struct NumInput {
@@ -344,6 +345,10 @@ void sort_trans_data_dist(TransInfo *t);
void add_tdi_poin(float *poin, float *old, float delta); void add_tdi_poin(float *poin, float *old, float delta);
void special_aftertrans_update(TransInfo *t); void special_aftertrans_update(TransInfo *t);
/* auto-keying stuff used by special_aftertrans_update */
void autokeyframe_ob_cb_func(struct Object *ob, int tmode);
void autokeyframe_pose_cb_func(struct Object *ob, int tmode, short targetless_ik);
/*********************** Constraints *****************************/ /*********************** Constraints *****************************/
void getConstraintMatrix(TransInfo *t); void getConstraintMatrix(TransInfo *t);

View File

@@ -120,6 +120,7 @@
/*#include "armature.h"*/ /*#include "armature.h"*/
/* #include "edit.h" */ /* #include "edit.h" */
#include "nla.h" #include "nla.h"
#include "transform.h"
#ifdef __NLA #ifdef __NLA
#include "BIF_editarmature.h" #include "BIF_editarmature.h"
@@ -1209,7 +1210,10 @@ void snap_sel_to_grid()
} }
} }
ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK); ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
ob->recalc |= OB_RECALC_DATA;
/* autokeyframing */
autokeyframe_pose_cb_func(ob, TFM_TRANSLATION, 0);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
} }
else { else {
ob->recalc |= OB_RECALC_OB; ob->recalc |= OB_RECALC_OB;
@@ -1235,6 +1239,9 @@ void snap_sel_to_grid()
#ifdef WITH_VERSE #ifdef WITH_VERSE
if(ob->vnode) b_verse_send_transformation(ob); if(ob->vnode) b_verse_send_transformation(ob);
#endif #endif
/* auto-keyframing */
autokeyframe_ob_cb_func(ob, TFM_TRANSLATION);
} }
} }
@@ -1318,7 +1325,10 @@ void snap_sel_to_curs()
} }
} }
ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK); ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
ob->recalc |= OB_RECALC_DATA;
/* autokeyframing */
autokeyframe_pose_cb_func(ob, TFM_TRANSLATION, 0);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
} }
else { else {
ob->recalc |= OB_RECALC_OB; ob->recalc |= OB_RECALC_OB;
@@ -1344,6 +1354,9 @@ void snap_sel_to_curs()
#ifdef WITH_VERSE #ifdef WITH_VERSE
if(ob->vnode) b_verse_send_transformation(ob); if(ob->vnode) b_verse_send_transformation(ob);
#endif #endif
/* auto-keyframing */
autokeyframe_ob_cb_func(ob, TFM_TRANSLATION);
} }
} }
@@ -1667,8 +1680,11 @@ void snap_to_center()
} }
} }
} }
ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
ob->recalc |= OB_RECALC_DATA; /* autokeyframing */
ob->pose->flag |= POSE_DO_UNLOCK;
autokeyframe_pose_cb_func(ob, TFM_TRANSLATION, 0);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
} }
else { else {
ob->recalc |= OB_RECALC_OB; ob->recalc |= OB_RECALC_OB;
@@ -1694,6 +1710,9 @@ void snap_to_center()
#ifdef WITH_VERSE #ifdef WITH_VERSE
if(ob->vnode) b_verse_send_transformation(ob); if(ob->vnode) b_verse_send_transformation(ob);
#endif #endif
/* auto-keyframing */
autokeyframe_ob_cb_func(ob, TFM_TRANSLATION);
} }
} }

View File

@@ -2177,55 +2177,100 @@ static void clear_trans_object_base_flags(void)
} }
} }
/* inserting keys, refresh ipo-keys, softbody, redraw events... (ton) */ /* auto-keyframing feature - for objects
/* note; transdata has been freed already! */ * tmode: should be a transform mode
void special_aftertrans_update(TransInfo *t) */
void autokeyframe_ob_cb_func(Object *ob, int tmode)
{ {
Object *ob;
Base *base;
IpoCurve *icu; IpoCurve *icu;
int redrawipo=0; char *actname="";
int cancelled= (t->state == TRANS_CANCEL);
if(G.obedit) { if (G.flags & G_RECORDKEYS) {
if(t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE) if(ob->ipoflag & OB_ACTION_OB)
allqueue(REDRAWBUTSEDIT, 0); actname= "Object";
/* table needs to be created for each edit command, since vertices can move etc */ if(U.uiflag & USER_KEYINSERTAVAI) {
mesh_octree_table(G.obedit, NULL, 'e'); if(ob->ipo || ob->action) {
ID *id= (ID *)(ob);
if (ob->ipo) {
icu= ob->ipo->curve.first;
} }
else if( (t->flag & T_POSE) && t->poseobj) { else {
bArmature *arm; bActionChannel *achan;
achan= get_action_channel(ob->action, actname);
if (achan && achan->ipo)
icu= achan->ipo->curve.first;
else
icu= NULL;
}
while(icu) {
icu->flag &= ~IPO_SELECT;
if (U.uiflag & USER_KEYINSERTNEED)
insertkey_smarter(id, ID_OB, actname, NULL, icu->adrcode);
else
insertkey(id, ID_OB, actname, NULL, icu->adrcode);
icu= icu->next;
}
}
}
else if (U.uiflag & USER_KEYINSERTNEED) {
if (tmode==TFM_RESIZE) {
insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_SIZE_X);
insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_SIZE_Y);
insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_SIZE_Z);
}
else if (tmode==TFM_ROTATION) {
insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_ROT_X);
insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_ROT_Y);
insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_ROT_Z);
}
else if (tmode==TFM_TRANSLATION) {
insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_LOC_X);
insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_LOC_Y);
insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_LOC_Z);
}
}
else {
insertkey(&ob->id, ID_OB, actname, NULL, OB_ROT_X);
insertkey(&ob->id, ID_OB, actname, NULL, OB_ROT_Y);
insertkey(&ob->id, ID_OB, actname, NULL, OB_ROT_Z);
insertkey(&ob->id, ID_OB, actname, NULL, OB_LOC_X);
insertkey(&ob->id, ID_OB, actname, NULL, OB_LOC_Y);
insertkey(&ob->id, ID_OB, actname, NULL, OB_LOC_Z);
insertkey(&ob->id, ID_OB, actname, NULL, OB_SIZE_X);
insertkey(&ob->id, ID_OB, actname, NULL, OB_SIZE_Y);
insertkey(&ob->id, ID_OB, actname, NULL, OB_SIZE_Z);
}
remake_object_ipos(ob);
allqueue(REDRAWIPO, 0);
allspace(REMAKEIPO, 0);
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWNLA, 0);
allqueue(REDRAWTIME, 0);
}
}
/* auto-keyframing feature - for poses/pose-channels
* tmode: should be a transform mode
* targetless_ik: has targetless ik been done on any channels?
*/
void autokeyframe_pose_cb_func(Object *ob, int tmode, short targetless_ik)
{
bAction *act; bAction *act;
bPose *pose; bPose *pose;
bPoseChannel *pchan; bPoseChannel *pchan;
short targetless_ik= 0; IpoCurve *icu;
ob= t->poseobj;
arm= ob->data;
pose= ob->pose; pose= ob->pose;
/* this signal does one recalc on pose, then unlocks, so ESC or edit will work */
pose->flag |= POSE_DO_UNLOCK;
/* if target-less IK grabbing, we calculate the pchan transforms and clear flag */
if(!cancelled && t->mode==TFM_TRANSLATION)
targetless_ik= apply_targetless_ik(ob);
else {
/* not forget to clear the auto flag */
for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
bKinematicConstraint *data= has_targetless_ik(pchan);
if(data) data->flag &= ~CONSTRAINT_IK_AUTO;
}
}
if(t->mode==TFM_TRANSLATION)
pose_grab_with_ik_clear(ob);
/* automatic inserting of keys */
if((G.flags & G_RECORDKEYS) && (!cancelled)) {
act= ob->action; act= ob->action;
if (G.flags & G_RECORDKEYS) {
if (!act) if (!act)
act= ob->action= add_empty_action("Action"); act= ob->action= add_empty_action("Action");
@@ -2236,7 +2281,6 @@ void special_aftertrans_update(TransInfo *t)
bActionChannel *achan; bActionChannel *achan;
for (achan = act->chanbase.first; achan; achan=achan->next){ for (achan = act->chanbase.first; achan; achan=achan->next){
if (achan->ipo && !strcmp (achan->name, pchan->name)){ if (achan->ipo && !strcmp (achan->name, pchan->name)){
for (icu = achan->ipo->curve.first; icu; icu=icu->next){ for (icu = achan->ipo->curve.first; icu; icu=icu->next){
if (U.uiflag & USER_KEYINSERTNEED) if (U.uiflag & USER_KEYINSERTNEED)
@@ -2244,24 +2288,23 @@ void special_aftertrans_update(TransInfo *t)
else else
insertkey(&ob->id, ID_PO, pchan->name, NULL, icu->adrcode); insertkey(&ob->id, ID_PO, pchan->name, NULL, icu->adrcode);
} }
break; break;
} }
} }
} }
else if (U.uiflag & USER_KEYINSERTNEED) { else if (U.uiflag & USER_KEYINSERTNEED) {
if ((t->mode==TFM_TRANSLATION) && (targetless_ik==0)) { if ((tmode==TFM_TRANSLATION) && (targetless_ik==0)) {
insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_X); insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_X);
insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Y); insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Y);
insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Z); insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Z);
} }
if ((t->mode==TFM_ROTATION) || ((t->mode==TFM_TRANSLATION) && targetless_ik)) { if ((tmode==TFM_ROTATION) || ((tmode==TFM_TRANSLATION) && targetless_ik)) {
insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_W); insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_W);
insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_X); insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_X);
insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Y); insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Z); insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
} }
if (t->mode==TFM_RESIZE) { if (tmode==TFM_RESIZE) {
insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_X); insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_X);
insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Y); insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Y);
insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Z); insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Z);
@@ -2290,7 +2333,55 @@ void special_aftertrans_update(TransInfo *t)
allqueue(REDRAWIPO, 0); allqueue(REDRAWIPO, 0);
allqueue(REDRAWNLA, 0); allqueue(REDRAWNLA, 0);
allqueue(REDRAWTIME, 0); allqueue(REDRAWTIME, 0);
}
}
/* inserting keys, refresh ipo-keys, softbody, redraw events... (ton) */
/* note; transdata has been freed already! */
void special_aftertrans_update(TransInfo *t)
{
Object *ob;
Base *base;
int redrawipo=0;
int cancelled= (t->state == TRANS_CANCEL);
if(G.obedit) {
if(t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE)
allqueue(REDRAWBUTSEDIT, 0);
/* table needs to be created for each edit command, since vertices can move etc */
mesh_octree_table(G.obedit, NULL, 'e');
}
else if( (t->flag & T_POSE) && t->poseobj) {
bArmature *arm;
bPose *pose;
bPoseChannel *pchan;
short targetless_ik= 0;
ob= t->poseobj;
arm= ob->data;
pose= ob->pose;
/* this signal does one recalc on pose, then unlocks, so ESC or edit will work */
pose->flag |= POSE_DO_UNLOCK;
/* if target-less IK grabbing, we calculate the pchan transforms and clear flag */
if(!cancelled && t->mode==TFM_TRANSLATION)
targetless_ik= apply_targetless_ik(ob);
else {
/* not forget to clear the auto flag */
for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
bKinematicConstraint *data= has_targetless_ik(pchan);
if(data) data->flag &= ~CONSTRAINT_IK_AUTO;
}
}
if(t->mode==TFM_TRANSLATION)
pose_grab_with_ik_clear(ob);
/* automatic inserting of keys */
if(!cancelled) {
autokeyframe_pose_cb_func(ob, t->mode, targetless_ik);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
} }
else if(arm->flag & ARM_DELAYDEFORM) { else if(arm->flag & ARM_DELAYDEFORM) {
@@ -2316,76 +2407,8 @@ void special_aftertrans_update(TransInfo *t)
if(modifiers_isSoftbodyEnabled(ob)) ob->softflag |= OB_SB_REDO; if(modifiers_isSoftbodyEnabled(ob)) ob->softflag |= OB_SB_REDO;
/* Set autokey if necessary */ /* Set autokey if necessary */
if ((G.flags & G_RECORDKEYS) && (!cancelled) && (base->flag & SELECT)){ if ((!cancelled) && (base->flag & SELECT)){
char *actname=""; autokeyframe_ob_cb_func(ob, t->mode);
if(ob->ipoflag & OB_ACTION_OB)
actname= "Object";
if(U.uiflag & USER_KEYINSERTAVAI) {
if(base->object->ipo || base->object->action) {
ID* id= (ID *)(base->object);
if (base->object->ipo) {
icu= base->object->ipo->curve.first;
}
else {
bActionChannel *achan;
achan= get_action_channel(base->object->action, actname);
if (achan && achan->ipo)
icu= achan->ipo->curve.first;
else
icu= NULL;
}
while(icu) {
icu->flag &= ~IPO_SELECT;
if (U.uiflag & USER_KEYINSERTNEED)
insertkey_smarter(id, ID_OB, actname, NULL, icu->adrcode);
else
insertkey(id, ID_OB, actname, NULL, icu->adrcode);
icu= icu->next;
}
}
}
else if (U.uiflag & USER_KEYINSERTNEED) {
if (t->mode==TFM_RESIZE) {
insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_SIZE_X);
insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Y);
insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Z);
}
else if (t->mode==TFM_ROTATION) {
insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_ROT_X);
insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_ROT_Y);
insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_ROT_Z);
}
else if (t->mode==TFM_TRANSLATION) {
insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_LOC_X);
insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_LOC_Y);
insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_LOC_Z);
}
}
else {
insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_X);
insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_Y);
insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_Z);
insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_X);
insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_Y);
insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_Z);
insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_X);
insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Y);
insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Z);
}
remake_object_ipos (ob);
allqueue(REDRAWIPO, 0);
allspace(REMAKEIPO, 0);
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWNLA, 0);
allqueue(REDRAWTIME, 0);
} }
base= base->next; base= base->next;