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:
@@ -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){
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user