Couple of fixes combined;

- With Actions on a Pose, ESC in transform restored wrong.
  This is solved similar to ipos now, storing a 'last time evaluated'.
  Could be extended to ghosting... soon.
- Moving the little yellow 'key blocks' in Action window didn't update
  3d window. ALso the 'lock' option didn't work, and flashed header.
- Pose Transform: noticed there were still errors in cases, especially
  with actions. Painfully tried to build the desired matrix now.
- Removed obsolete Bone pointer from TransData
This commit is contained in:
Ton Roosendaal
2005-07-19 16:12:56 +00:00
parent b344db3670
commit 19abd72baa
8 changed files with 139 additions and 126 deletions

View File

@@ -446,7 +446,9 @@ void extract_pose_from_action(bPose *pose, bAction *act, float ctime)
return;
if (!pose)
return;
pose->ctime= ctime;
/* Copy the data from the action into the pose */
for (pchan= pose->chanbase.first; pchan; pchan=pchan->next) {
achan= get_named_actionchannel(act, pchan->name);
@@ -494,120 +496,122 @@ void do_all_actions(Object *ob)
{
bPose *tpose=NULL;
bActionStrip *strip;
int doit;
float striptime, frametime, length, actlength;
float ctime, striptime, frametime, length, actlength;
float blendfac, stripframe;
int doit;
// only to have safe calls from editor
if(ob==NULL) return;
if(ob->type!=OB_ARMATURE || ob->pose==NULL) return;
if(ob==NULL) return; // only to have safe calls from editor
/* Retrieve data from the NLA */
if(ob->type==OB_ARMATURE && ob->pose) {
bArmature *arm= ob->data;
ctime= bsystem_time(ob, 0, (float) G.scene->r.cfra, 0.0);
if(ob->pose->ctime==ctime) { // no actions to execute while transform
;
}
else if(ob->action) {
/* Do local action (always overrides the nla actions) */
extract_pose_from_action (ob->pose, ob->action, bsystem_time(ob, 0, (float) G.scene->r.cfra, 0.0));
}
else if(ob->nlastrips.first) {
doit=0;
if(arm->flag & ARM_NO_ACTION) { // no action set while transform
;
}
else if(ob->action) {
/* Do local action (always overrides the nla actions) */
extract_pose_from_action (ob->pose, ob->action, bsystem_time(ob, 0, (float) G.scene->r.cfra, 0.0));
}
else if(ob->nlastrips.first) {
doit=0;
copy_pose(&tpose, ob->pose, 1);
rest_pose(ob->pose, 1); // potentially destroying current not-keyed pose
copy_pose(&tpose, ob->pose, 1);
rest_pose(ob->pose, 1); // potentially destroying current not-keyed pose
for (strip=ob->nlastrips.first; strip; strip=strip->next){
doit = 0;
if (strip->act){
/* Determine if the current frame is within the strip's range */
length = strip->end-strip->start;
actlength = strip->actend-strip->actstart;
striptime = (G.scene->r.cfra-(strip->start)) / length;
stripframe = (G.scene->r.cfra-(strip->start)) ;
for (strip=ob->nlastrips.first; strip; strip=strip->next){
doit = 0;
if (strip->act){
/* Determine if the current frame is within the strip's range */
length = strip->end-strip->start;
actlength = strip->actend-strip->actstart;
striptime = (G.scene->r.cfra-(strip->start)) / length;
stripframe = (G.scene->r.cfra-(strip->start)) ;
if (striptime>=0.0){
rest_pose(tpose, 1);
if (striptime>=0.0){
rest_pose(tpose, 1);
/* Handle path */
if (strip->flag & ACTSTRIP_USESTRIDE){
if (ob->parent && ob->parent->type==OB_CURVE){
Curve *cu = ob->parent->data;
float ctime, pdist;
/* Handle path */
if (strip->flag & ACTSTRIP_USESTRIDE){
if (ob->parent && ob->parent->type==OB_CURVE){
Curve *cu = ob->parent->data;
float ctime, pdist;
if (cu->flag & CU_PATH){
/* Ensure we have a valid path */
if(cu->path==NULL || cu->path->data==NULL) printf("action path error in ob %s\n", ob->parent->id.name+2);
else {
if (cu->flag & CU_PATH){
/* Ensure we have a valid path */
if(cu->path==NULL || cu->path->data==NULL) printf("action path error in ob %s\n", ob->parent->id.name+2);
else {
/* Find the position on the path */
ctime= bsystem_time(ob, ob->parent, (float)G.scene->r.cfra, 0.0);
if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) {
ctime /= cu->pathlen;
CLAMP(ctime, 0.0, 1.0);
}
pdist = ctime*cu->path->totdist;
if (strip->stridelen)
striptime = pdist / strip->stridelen;
else
striptime = 0;
striptime = (float)fmod (striptime, 1.0);
frametime = (striptime * actlength) + strip->actstart;
extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
doit=1;
/* Find the position on the path */
ctime= bsystem_time(ob, ob->parent, (float)G.scene->r.cfra, 0.0);
if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) {
ctime /= cu->pathlen;
CLAMP(ctime, 0.0, 1.0);
}
pdist = ctime*cu->path->totdist;
if (strip->stridelen)
striptime = pdist / strip->stridelen;
else
striptime = 0;
striptime = (float)fmod (striptime, 1.0);
frametime = (striptime * actlength) + strip->actstart;
extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
doit=1;
}
}
}
}
/* Handle repeat */
else if (striptime < 1.0){
/* Mod to repeat */
striptime*=strip->repeat;
striptime = (float)fmod (striptime, 1.0);
/* Handle repeat */
else if (striptime < 1.0){
/* Mod to repeat */
striptime*=strip->repeat;
striptime = (float)fmod (striptime, 1.0);
frametime = (striptime * actlength) + strip->actstart;
extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
doit=1;
}
/* Handle extend */
else{
if (strip->flag & ACTSTRIP_HOLDLASTFRAME){
striptime = 1.0;
frametime = (striptime * actlength) + strip->actstart;
extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
doit=1;
}
/* Handle extend */
else{
if (strip->flag & ACTSTRIP_HOLDLASTFRAME){
striptime = 1.0;
frametime = (striptime * actlength) + strip->actstart;
extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
doit=1;
}
}
/* Handle blendin & blendout */
if (doit){
/* Handle blendin */
if (strip->blendin>0.0 && stripframe<=strip->blendin && G.scene->r.cfra>=strip->start){
blendfac = stripframe/strip->blendin;
}
/* Handle blendin & blendout */
if (doit){
/* Handle blendin */
if (strip->blendin>0.0 && stripframe<=strip->blendin && G.scene->r.cfra>=strip->start){
blendfac = stripframe/strip->blendin;
}
else if (strip->blendout>0.0 && stripframe>=(length-strip->blendout) && G.scene->r.cfra<=strip->end){
blendfac = (length-stripframe)/(strip->blendout);
}
else
blendfac = 1;
/* Blend this pose with the accumulated pose */
blend_poses (ob->pose, tpose, blendfac, strip->mode);
else if (strip->blendout>0.0 && stripframe>=(length-strip->blendout) && G.scene->r.cfra<=strip->end){
blendfac = (length-stripframe)/(strip->blendout);
}
}
}
else
blendfac = 1;
/* Blend this pose with the accumulated pose */
blend_poses (ob->pose, tpose, blendfac, strip->mode);
}
}
}
}
ob->pose->ctime= ctime;
}
if (tpose){

View File

@@ -487,7 +487,7 @@ void *new_constraint_data (short type)
data = MEM_callocN(sizeof(bKinematicConstraint), "kinematicConstraint");
data->tolerance = (float)0.001;
data->iterations = 50;
data->iterations = 500;
result = data;
}

View File

@@ -102,7 +102,6 @@ typedef struct TransDataExtension {
float *size; /* Size of the data to transform (Faculative) */
float isize[3]; /* Initial size */
float obmat[3][3]; /* Object matrix */
void *bone; /* ARGH! old transform demanded it, added for now (ton) */
} TransDataExtension;
typedef struct TransData {

View File

@@ -77,7 +77,8 @@ typedef struct bPoseChannel {
typedef struct bPose{
ListBase chanbase;
int flag, pad;
int flag;
float ctime; // last time actions were done, to allow keyframing
} bPose;
typedef struct bActionChannel {

View File

@@ -88,7 +88,6 @@ typedef struct bArmature {
#define ARM_EDITBIT 5
#define ARM_DELAYBIT 6
/* dont use bit 7, was saved in files to disable stuff */
#define ARM_NO_ACTIONBIT 8
/* armature->flag */
#define ARM_RESTPOS 0x0001
@@ -100,7 +99,7 @@ typedef struct bArmature {
#define ARM_EDITMODE 0x0020
#define ARM_DELAYDEFORM 0x0040
#define ARM_DONT_USE 0x0080
#define ARM_NO_ACTION 0x0100
/* bit 0x0100 is free now */
#define ARM_B_BONES 0x0200

View File

@@ -995,7 +995,8 @@ void paste_posebuf (int flip)
}
}
/* Update event for deformation children */
/* Update event for pose and deformation children */
ob->pose->ctime= -123456.0f;
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
if (G.flags & G_RECORDKEYS) {
@@ -1121,19 +1122,20 @@ void transform_actionchannel_keys(char mode)
{
bAction *act;
TransVert *tv;
int /*sel=0,*/ i;
Object *ob= OBACT;
bConstraintChannel *conchan;
bActionChannel *chan;
short mvals[2], mvalc[2], cent[2];
float deltax, startx;
float cenf[2];
float sval[2], cval[2], lastcval[2];
short cancel=0;
float fac=0.0F;
int loop=1;
int tvtot=0;
float deltax, startx;
float cenf[2];
int invert=0, firsttime=1;
int i;
short cancel=0;
short mvals[2], mvalc[2], cent[2];
char str[256];
bConstraintChannel *conchan;
act=G.saction->action;
@@ -1261,8 +1263,11 @@ void transform_actionchannel_keys(char mode)
}
if (G.saction->lock){
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
force_draw_all(0);
if(ob && ob->pose) {
ob->pose->ctime= -123456.0f;
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
}
force_draw_plus(SPACE_VIEW3D, 0);
}
else {
force_draw(0);
@@ -1277,7 +1282,10 @@ void transform_actionchannel_keys(char mode)
/* Update the curve */
/* Depending on the lock status, draw necessary views */
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
if(ob && ob->pose) {
ob->pose->ctime= -123456.0f;
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
}
remake_action_ipos(act);
if(cancel==0) BIF_undo_push("Transform Action");

View File

@@ -478,7 +478,11 @@ void editipo_changed(SpaceIpo *si, int doredraw)
}
else if(si->blocktype==ID_SEQ) clear_last_seq();
else if(si->blocktype==ID_AC) {
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
Object *ob= OBACT;
if(ob && ob->pose) {
ob->pose->ctime= -123456.0f;
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
}
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
@@ -4863,7 +4867,11 @@ void transform_ipo(int mode)
force_draw_plus(SPACE_VIEW3D, 0);
}
else if(G.sipo->blocktype==ID_AC) {
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
Object *ob= OBACT;
if(ob && ob->pose) {
ob->pose->ctime= -123456.0f;
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
}
force_draw_plus(SPACE_VIEW3D, 0);
}
else if(G.sipo->blocktype==ID_OB) {

View File

@@ -382,7 +382,7 @@ void count_bone_select(TransInfo *t, ListBase *lb, int do_it)
if(do_it) {
if (bone->flag & BONE_SELECTED) {
/* We don't let IK children get "grabbed" */
if ( (t->mode!=TFM_TRANSLATION) || bone->parent==NULL || (bone->flag & BONE_IK_TOPARENT)==0 ) {
if ( (t->mode!=TFM_TRANSLATION) || (bone->flag & BONE_IK_TOPARENT)==0 ) {
bone->flag |= BONE_TRANSFORM;
t->total++;
do_next= 0; // no transform on children if one parent bone is selected
@@ -396,7 +396,7 @@ void count_bone_select(TransInfo *t, ListBase *lb, int do_it)
static int add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, TransData *td)
{
Bone *bone= pchan->bone;
float parmat[4][4], tempmat[4][4];
float pmat[3][3], omat[3][3];
float vec[3];
if(bone) {
@@ -415,25 +415,25 @@ static int add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tra
td->ext->rot= NULL;
td->ext->quat= pchan->quat;
td->ext->size= pchan->size;
td->ext->bone= bone; // FIXME: Dangerous
QUATCOPY(td->ext->iquat, pchan->quat);
VECCOPY(td->ext->isize, pchan->size);
if (pchan->parent) { /* apply parent transformation if there is one */
Mat4MulMat4(tempmat, bone->arm_mat, pchan->parent->chan_mat);
/* proper way to get the parent transform + own transform */
Mat3CpyMat4(omat, ob->obmat);
if(pchan->parent) {
Mat3CpyMat4(pmat, pchan->parent->pose_mat);
Mat3MulSerie(td->mtx, pchan->bone->bone_mat, pmat, omat, 0,0,0,0,0); // dang mulserie swaps args
}
else {
Mat4CpyMat4(tempmat, bone->arm_mat);
Mat3MulMat3(td->mtx, omat, pchan->bone->bone_mat); // huh, transposed?
}
Mat4MulMat4 (parmat, tempmat, ob->obmat);
Mat3CpyMat4 (td->mtx, parmat);
Mat3Inv (td->smtx, td->mtx);
/* for axismat we use bone's own transform */
Mat4MulMat4 (parmat, ob->obmat, pchan->pose_mat);
Mat3CpyMat4(td->axismtx, parmat);
Mat3CpyMat4(pmat, pchan->pose_mat);
Mat3MulMat3(td->axismtx, omat, pmat);
Mat3Ortho(td->axismtx);
return 1;
@@ -470,9 +470,6 @@ static void createTransPose(TransInfo *t)
}
if(t->total==0) return;
/* since we need to be able to insert keys, no actions should be assigned */
arm->flag |= ARM_NO_ACTION;
/* init trans data */
td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransPoseBone");
tdx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "TransPoseBoneExt");
@@ -1351,13 +1348,10 @@ void special_aftertrans_update(short cancelled)
int redrawipo=0;
if (G.obpose){
bArmature *arm= G.obpose->data;
bAction *act;
bPose *pose;
bPoseChannel *pchan;
arm->flag &= ~ARM_NO_ACTION;
if(cancelled) /* if cancelled we do the update always */
DAG_object_flush_update(G.scene, G.obpose, OB_RECALC_DATA);
else if(G.flags & G_RECORDKEYS) {