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