Two half working commits!

- Python Drivers
  In Ipo Window "transform properties" Panel, added the buttons, and the
  initial handling (now only printing text). Willian makes it work!

- Better Matrix to Eul, code submitted by Brecht. No time yet to do it
  really nice (like a Mat3ToEulCompat(mat, eul, eulc))
This commit is contained in:
2005-10-30 20:56:19 +00:00
parent 99753a423f
commit 41c5328dd4
5 changed files with 134 additions and 98 deletions

View File

@@ -709,6 +709,7 @@ void berekeny(float f1, float f2, float f3, float f4, float *o, int b)
o[a]= c0+t*c1+t*t*c2+t*t*t*c3; o[a]= c0+t*c1+t*t*c2+t*t*t*c3;
} }
} }
void berekenx(float *f, float *o, int b) void berekenx(float *f, float *o, int b)
{ {
float t, c0, c1, c2, c3; float t, c0, c1, c2, c3;
@@ -724,83 +725,89 @@ void berekenx(float *f, float *o, int b)
} }
} }
/* has to return a float value */
static float eval_driver(IpoDriver *driver) static float eval_driver(IpoDriver *driver)
{ {
Object *ob= driver->ob;
if(ob==NULL) return 0.0f; if(driver->flag & IPO_DRIVER_PYTHON) {
printf("Execute %s\n", driver->name);
if(driver->blocktype==ID_OB) {
switch(driver->adrcode) {
case OB_LOC_X:
return ob->loc[0];
case OB_LOC_Y:
return ob->loc[1];
case OB_LOC_Z:
return ob->loc[2];
case OB_ROT_X:
return ob->rot[0]/(M_PI_2/9.0);
case OB_ROT_Y:
return ob->rot[1]/(M_PI_2/9.0);
case OB_ROT_Z:
return ob->rot[2]/(M_PI_2/9.0);
case OB_SIZE_X:
return ob->size[0];
case OB_SIZE_Y:
return ob->size[1];
case OB_SIZE_Z:
return ob->size[2];
}
} }
else { /* ID_AR */ else {
bPoseChannel *pchan= get_pose_channel(ob->pose, driver->name); Object *ob= driver->ob;
if(pchan && pchan->bone) {
float pose_mat[3][3]; if(ob==NULL) return 0.0f;
float diff_mat[3][3], par_mat[3][3], ipar_mat[3][3];
float eul[3], size[3]; if(driver->blocktype==ID_OB) {
/* we need the local transform = current transform - (parent transform + bone transform) */
Mat3CpyMat4(pose_mat, pchan->pose_mat);
if (pchan->parent) {
Mat3CpyMat4(par_mat, pchan->parent->pose_mat);
Mat3MulMat3(diff_mat, par_mat, pchan->bone->bone_mat);
Mat3Inv(ipar_mat, diff_mat);
}
else {
Mat3Inv(ipar_mat, pchan->bone->bone_mat);
}
Mat3MulMat3(diff_mat, ipar_mat, pose_mat);
Mat3ToEul(diff_mat, eul);
Mat3ToSize(diff_mat, size);
switch(driver->adrcode) { switch(driver->adrcode) {
case OB_LOC_X: case OB_LOC_X:
return pchan->loc[0]; return ob->loc[0];
case OB_LOC_Y: case OB_LOC_Y:
return pchan->loc[1]; return ob->loc[1];
case OB_LOC_Z: case OB_LOC_Z:
return pchan->loc[2]; return ob->loc[2];
case OB_ROT_X: case OB_ROT_X:
return eul[0]/(M_PI_2/9.0); return ob->rot[0]/(M_PI_2/9.0);
case OB_ROT_Y: case OB_ROT_Y:
return eul[1]/(M_PI_2/9.0); return ob->rot[1]/(M_PI_2/9.0);
case OB_ROT_Z: case OB_ROT_Z:
return eul[2]/(M_PI_2/9.0); return ob->rot[2]/(M_PI_2/9.0);
case OB_SIZE_X: case OB_SIZE_X:
return size[0]; return ob->size[0];
case OB_SIZE_Y: case OB_SIZE_Y:
return size[1]; return ob->size[1];
case OB_SIZE_Z: case OB_SIZE_Z:
return size[2]; return ob->size[2];
} }
} }
} else { /* ID_AR */
bPoseChannel *pchan= get_pose_channel(ob->pose, driver->name);
if(pchan && pchan->bone) {
float pose_mat[3][3];
float diff_mat[3][3], par_mat[3][3], ipar_mat[3][3];
float eul[3], size[3];
/* we need the local transform = current transform - (parent transform + bone transform) */
Mat3CpyMat4(pose_mat, pchan->pose_mat);
if (pchan->parent) {
Mat3CpyMat4(par_mat, pchan->parent->pose_mat);
Mat3MulMat3(diff_mat, par_mat, pchan->bone->bone_mat);
Mat3Inv(ipar_mat, diff_mat);
}
else {
Mat3Inv(ipar_mat, pchan->bone->bone_mat);
}
Mat3MulMat3(diff_mat, ipar_mat, pose_mat);
Mat3ToEul(diff_mat, eul);
Mat3ToSize(diff_mat, size);
switch(driver->adrcode) {
case OB_LOC_X:
return pchan->loc[0];
case OB_LOC_Y:
return pchan->loc[1];
case OB_LOC_Z:
return pchan->loc[2];
case OB_ROT_X:
return eul[0]/(M_PI_2/9.0);
case OB_ROT_Y:
return eul[1]/(M_PI_2/9.0);
case OB_ROT_Z:
return eul[2]/(M_PI_2/9.0);
case OB_SIZE_X:
return size[0];
case OB_SIZE_Y:
return size[1];
case OB_SIZE_Z:
return size[2];
}
}
}
}
return 0.0f; return 0.0f;
} }

View File

@@ -2170,9 +2170,24 @@ void Mat3ToEul(float tmat[][3], float *eul)
cy = (float)sqrt(mat[0][0]*mat[0][0] + mat[0][1]*mat[0][1]); cy = (float)sqrt(mat[0][0]*mat[0][0] + mat[0][1]*mat[0][1]);
if (cy > 16.0*FLT_EPSILON) { if (cy > 16.0*FLT_EPSILON) {
eul[0] = (float)atan2(mat[1][2], mat[2][2]); float eul1[3], eul2[3];
eul[1] = (float)atan2(-mat[0][2], cy);
eul[2] = (float)atan2(mat[0][1], mat[0][0]); eul1[0] = (float)atan2(mat[1][2], mat[2][2]);
eul1[1] = (float)atan2(-mat[0][2], cy);
eul1[2] = (float)atan2(mat[0][1], mat[0][0]);
eul2[0] = (float)atan2(-mat[1][2], -mat[2][2]);
eul2[1] = (float)atan2(-mat[0][2], -cy);
eul2[2] = (float)atan2(-mat[0][1], -mat[0][0]);
/* return best, which is just the one with lowest values it in */
if( fabs(eul1[0])+fabs(eul1[1])+fabs(eul1[2]) > fabs(eul2[0])+fabs(eul2[1])+fabs(eul2[2])) {
VecCopyf(eul, eul2);
}
else {
VecCopyf(eul, eul1);
}
} else { } else {
eul[0] = (float)atan2(-mat[2][1], mat[1][1]); eul[0] = (float)atan2(-mat[2][1], mat[1][1]);
eul[1] = (float)atan2(-mat[0][2], cy); eul[1] = (float)atan2(-mat[0][2], cy);

View File

@@ -174,7 +174,7 @@ typedef struct Curve {
typedef struct IpoDriver { typedef struct IpoDriver {
struct Object *ob; struct Object *ob;
short blocktype, adrcode, type, flag; short blocktype, adrcode, type, flag;
char name[32]; /* bone or constraint(?) name, later we can add python expression here */ char name[128]; /* bone or constraint(?), or python expression here */
} IpoDriver; } IpoDriver;
typedef struct IpoCurve { typedef struct IpoCurve {
@@ -252,6 +252,10 @@ typedef struct IpoCurve {
#define CU_UNDERLINE 4 #define CU_UNDERLINE 4
#define CU_WRAP 8 /* wordwrap occured here */ #define CU_WRAP 8 /* wordwrap occured here */
/* *************** driver ****************** */
/* driver->flag */
#define IPO_DRIVER_PYTHON 1
#endif #endif

View File

@@ -1783,17 +1783,22 @@ void do_ipobuts(unsigned short event)
if(ei->icu->driver) { if(ei->icu->driver) {
IpoDriver *driver= ei->icu->driver; IpoDriver *driver= ei->icu->driver;
if(driver->ob) { if(driver->flag & IPO_DRIVER_PYTHON) {
if(ob==driver->ob) { driver->ob= NULL;
error("Cannot assign a Driver to own Object"); }
driver->ob= NULL; else {
if(driver->ob) {
if(ob==driver->ob) {
error("Cannot assign a Driver to own Object");
driver->ob= NULL;
}
else {
/* check if type is still OK */
if(driver->ob->type==OB_ARMATURE && driver->blocktype==ID_AR);
else driver->blocktype= ID_OB;
}
} }
else { }
/* check if type is still OK */
if(driver->ob->type==OB_ARMATURE && driver->blocktype==ID_AR);
else driver->blocktype= ID_OB;
}
}
DAG_scene_sort(G.scene); DAG_scene_sort(G.scene);
if(G.sipo->blocktype==ID_KE || G.sipo->blocktype==ID_AC) if(G.sipo->blocktype==ID_KE || G.sipo->blocktype==ID_AC)
@@ -1877,27 +1882,35 @@ static void ipo_panel_properties(short cntrl) // IPO_HANDLER_PROPERTIES
if(ei->icu && ei->icu->driver) { if(ei->icu && ei->icu->driver) {
IpoDriver *driver= ei->icu->driver; IpoDriver *driver= ei->icu->driver;
uiDefBut(block, BUT, B_IPO_DRIVER, "Remove", 210,265,100,19, NULL, 0.0f, 0.0f, 0, 0, "Remove Driver for this Ipo Channel"); uiDefBut(block, BUT, B_IPO_DRIVER, "Remove", 210,265,100,20, NULL, 0.0f, 0.0f, 0, 0, "Remove Driver for this Ipo Channel");
uiBlockBeginAlign(block); uiBlockBeginAlign(block);
uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_IPO_DEPCHANGE, "OB:", 10, 240, 150, 20, &(driver->ob), "Driver Object"); uiDefIconButBitS(block, TOG, IPO_DRIVER_PYTHON, B_IPO_DEPCHANGE, ICON_PYTHON, 10,240,25,20, &driver->flag, 0, 0, 0, 0, "Use a one-line Python Expression as Driver");
if(driver->ob) {
int icon=ICON_OBJECT; if(driver->flag & IPO_DRIVER_PYTHON) {
uiDefBut(block, TEX, B_IPO_REDR, "", 35,240,275,20, driver->name, 0, 127, 0, 0, "Python Expression");
if(driver->ob->type==OB_ARMATURE && driver->blocktype==ID_AR) { uiBlockEndAlign(block);
icon = ICON_POSE_DEHLT; }
uiDefBut(block, TEX, B_IPO_REDR, "BO:", 10,220,150,20, driver->name, 0, 31, 0, 0, "Bone name"); else {
} uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_IPO_DEPCHANGE, "OB:", 35, 240, 125, 20, &(driver->ob), "Driver Object");
else driver->blocktype= ID_OB; /* safety when switching object button */ if(driver->ob) {
int icon=ICON_OBJECT;
uiBlockBeginAlign(block);
uiDefIconTextButS(block, MENU, B_IPO_DEPCHANGE, icon, if(driver->ob->type==OB_ARMATURE && driver->blocktype==ID_AR) {
ipodriver_modeselect_pup(driver->ob), 165,240,145,20, &(driver->blocktype), 0, 0, 0, 0, "Driver type"); icon = ICON_POSE_DEHLT;
uiDefBut(block, TEX, B_IPO_REDR, "BO:", 10,220,150,20, driver->name, 0, 31, 0, 0, "Bone name");
uiDefButS(block, MENU, B_IPO_REDR, }
ipodriver_channelselect_pup(), 165,220,145,20, &(driver->adrcode), 0, 0, 0, 0, "Driver channel"); else driver->blocktype= ID_OB; /* safety when switching object button */
uiBlockBeginAlign(block);
uiDefIconTextButS(block, MENU, B_IPO_DEPCHANGE, icon,
ipodriver_modeselect_pup(driver->ob), 165,240,145,20, &(driver->blocktype), 0, 0, 0, 0, "Driver type");
uiDefButS(block, MENU, B_IPO_REDR,
ipodriver_channelselect_pup(), 165,220,145,20, &(driver->adrcode), 0, 0, 0, 0, "Driver channel");
}
uiBlockEndAlign(block);
} }
uiBlockEndAlign(block);
} }
else { else {
uiDefBut(block, BUT, B_IPO_DRIVER, "Add Driver", 210,265,100,19, NULL, 0.0f, 0.0f, 0, 0, "Create a Driver for this Ipo Channel"); uiDefBut(block, BUT, B_IPO_DRIVER, "Add Driver", 210,265,100,19, NULL, 0.0f, 0.0f, 0, 0, "Create a Driver for this Ipo Channel");

View File

@@ -3332,12 +3332,9 @@ void compatible_eul(float *eul, float *oldrot)
if(dz > 0.0) eul[2] -= 2.0*M_PI; else eul[2]+= 2.0*M_PI; if(dz > 0.0) eul[2] -= 2.0*M_PI; else eul[2]+= 2.0*M_PI;
} }
/* this return was there from ancient days... i remove it now, /* this return was there from ancient days... but why! probably because the code sucks :)
because axis-only rotations then work much nicer (try Y axis rotate
and check Y euler values).
Needed for new locking of transform values. (ton)
*/ */
/*return;*/ return;
/* calc again */ /* calc again */
dx= eul[0] - oldrot[0]; dx= eul[0] - oldrot[0];