+ Local axis constraint for multiple object selection works with resize and rotate (the easiest).

+ Refined the headerprint for Translation. Now prints only the needed info for constraint in the constraint's space (ie: if you're moving 1 unit along the local X axis, regardless of it's orientation, it will print "D: 1.000 along local X")
Still need to make numinput work like that (typing a number with a local axis constraint would move along that axis. There's some base code already though, just need a finishing touch, but it's late now)

+ Optimised PET calculations by using the TD_NOACTION flag (actually, that might have been in the last commit).

+ Added a float axismtx[3][3] member to TransData to store the orientation of the element (useful for local axis constrainst which, in edit could be moving along normals and the like).

- Fixed scaling in edit mode (was doing some matrix multiplications in the wrong order, only visible when using a constraint)

- Fixed the constraint projection matrix. It didn't work for planar constraint if the constraint space wasn't global (in a nutshell, it produced weird results for local space planes).

- Some potential bugs fixed (Note to Ton: added an ext pointer in TransInfo to point to the TransDataExtension block. With the sort done after allocation, the first td pointer doesn't necesarely point at the start of the ext block, so we needed another to free it correctly).

- Got rid of some remaining test with G.obedit.

- Moved constraint reset from init to post trans code (Ton, that means you can create constraints before calling transform, like for the menus for example).

NOTE:

I was getting some random segfault with the new headerprint code. Very random, couldn't reproduce with a debug version. I did some initialisation that might have been missing (though doubtful that's what caused the crashes). Was linked to using constraint though not caused by them. Probably due to some dumb late coding error.
This commit is contained in:
2005-03-08 03:51:45 +00:00
parent 03b70c9bf5
commit 81ea38cd10
5 changed files with 287 additions and 128 deletions

View File

@@ -205,7 +205,7 @@ void createTransTexspace(void)
ob= OBACT; ob= OBACT;
Trans.total = 1; Trans.total = 1;
td= Trans.data= MEM_callocN(sizeof(TransData), "TransTexspace"); td= Trans.data= MEM_callocN(sizeof(TransData), "TransTexspace");
td->ext= MEM_callocN(sizeof(TransDataExtension), "TransTexspace"); td->ext= Trans.ext= MEM_callocN(sizeof(TransDataExtension), "TransTexspace");
td->flag= TD_SELECTED; td->flag= TD_SELECTED;
VECCOPY(td->center, ob->obmat[3]); VECCOPY(td->center, ob->obmat[3]);
@@ -360,7 +360,7 @@ static void createTransPose(void)
/* init trans data */ /* init trans data */
td = Trans.data = MEM_mallocN(Trans.total*sizeof(TransData), "TransPoseBone"); td = Trans.data = MEM_mallocN(Trans.total*sizeof(TransData), "TransPoseBone");
tdx = MEM_mallocN(Trans.total*sizeof(TransDataExtension), "TransPoseBoneExt"); tdx = Trans.ext = MEM_mallocN(Trans.total*sizeof(TransDataExtension), "TransPoseBoneExt");
for(i=0; i<Trans.total; i++, td++, tdx++) { for(i=0; i<Trans.total; i++, td++, tdx++) {
td->ext= tdx; td->ext= tdx;
td->tdi = NULL; td->tdi = NULL;
@@ -447,7 +447,7 @@ static void createTransMBallVerts(void)
else Trans.total = countsel; else Trans.total = countsel;
Trans.data= MEM_mallocN(Trans.total*sizeof(TransData), "TransObData(MBall EditMode)"); Trans.data= MEM_mallocN(Trans.total*sizeof(TransData), "TransObData(MBall EditMode)");
tx = MEM_mallocN(Trans.total*sizeof(TransDataExtension), "MetaElement_TransExtension"); tx = Trans.ext = MEM_mallocN(Trans.total*sizeof(TransDataExtension), "MetaElement_TransExtension");
Mat3CpyMat4(mtx, G.obedit->obmat); Mat3CpyMat4(mtx, G.obedit->obmat);
Mat3Inv(smtx, mtx); Mat3Inv(smtx, mtx);
@@ -858,7 +858,7 @@ static void ObjectToTransData(TransData *td, Object *ob)
VECCOPY(td->center, ob->obmat[3]); VECCOPY(td->center, ob->obmat[3]);
Mat3CpyMat4(td->mtx, ob->obmat); Mat3CpyMat4(td->axismtx, ob->obmat);
if (ob->parent) if (ob->parent)
{ {
@@ -1078,7 +1078,7 @@ static void createTransObject(void)
} }
td = Trans.data = MEM_mallocN(Trans.total*sizeof(TransData), "TransOb"); td = Trans.data = MEM_mallocN(Trans.total*sizeof(TransData), "TransOb");
tx = MEM_mallocN(Trans.total*sizeof(TransDataExtension), "TransObExtension"); tx = Trans.ext = MEM_mallocN(Trans.total*sizeof(TransDataExtension), "TransObExtension");
for(base= FIRSTBASE; base; base= base->next) { for(base= FIRSTBASE; base; base= base->next) {
if TESTBASELIB(base) { if TESTBASELIB(base) {
@@ -1315,22 +1315,22 @@ void Transform(int mode)
break; break;
case XKEY: case XKEY:
if (cmode == 'X') { if (cmode == 'X') {
Trans.con.mode &= ~CON_APPLY; stopConstraint(&Trans);
cmode = '\0'; cmode = '\0';
} }
else if(cmode == 'x') { else if(cmode == 'x') {
if (G.qual == 0) if (G.qual == 0)
setLocalConstraint(&Trans, (CON_APPLY|CON_AXIS0), "along local X"); setLocalConstraint(&Trans, (CON_AXIS0), "along local X");
else if (G.qual == LR_CTRLKEY) else if (G.qual == LR_CTRLKEY)
setLocalConstraint(&Trans, (CON_APPLY|CON_AXIS1|CON_AXIS2), "locking local X"); setLocalConstraint(&Trans, (CON_AXIS1|CON_AXIS2), "locking local X");
cmode = 'X'; cmode = 'X';
} }
else { else {
if (G.qual == 0) if (G.qual == 0)
setConstraint(&Trans, mati, (CON_APPLY|CON_AXIS0), "along global X"); setConstraint(&Trans, mati, (CON_AXIS0), "along global X");
else if (G.qual == LR_CTRLKEY) else if (G.qual == LR_CTRLKEY)
setConstraint(&Trans, mati, (CON_APPLY|CON_AXIS1|CON_AXIS2), "locking global X"); setConstraint(&Trans, mati, (CON_AXIS1|CON_AXIS2), "locking global X");
cmode = 'x'; cmode = 'x';
} }
@@ -1338,22 +1338,22 @@ void Transform(int mode)
break; break;
case YKEY: case YKEY:
if (cmode == 'Y') { if (cmode == 'Y') {
Trans.con.mode &= ~CON_APPLY; stopConstraint(&Trans);
cmode = '\0'; cmode = '\0';
} }
else if(cmode == 'y') { else if(cmode == 'y') {
if (G.qual == 0) if (G.qual == 0)
setLocalConstraint(&Trans, (CON_APPLY|CON_AXIS1), "along global Y"); setLocalConstraint(&Trans, (CON_AXIS1), "along global Y");
else if (G.qual == LR_CTRLKEY) else if (G.qual == LR_CTRLKEY)
setLocalConstraint(&Trans, (CON_APPLY|CON_AXIS0|CON_AXIS2), "locking global Y"); setLocalConstraint(&Trans, (CON_AXIS0|CON_AXIS2), "locking global Y");
cmode = 'Y'; cmode = 'Y';
} }
else { else {
if (G.qual == 0) if (G.qual == 0)
setConstraint(&Trans, mati, (CON_APPLY|CON_AXIS1), "along local Y"); setConstraint(&Trans, mati, (CON_AXIS1), "along local Y");
else if (G.qual == LR_CTRLKEY) else if (G.qual == LR_CTRLKEY)
setConstraint(&Trans, mati, (CON_APPLY|CON_AXIS0|CON_AXIS2), "locking local Y"); setConstraint(&Trans, mati, (CON_AXIS0|CON_AXIS2), "locking local Y");
cmode = 'y'; cmode = 'y';
} }
@@ -1361,22 +1361,22 @@ void Transform(int mode)
break; break;
case ZKEY: case ZKEY:
if (cmode == 'Z') { if (cmode == 'Z') {
Trans.con.mode &= ~CON_APPLY; stopConstraint(&Trans);
cmode = '\0'; cmode = '\0';
} }
else if(cmode == 'z') { else if(cmode == 'z') {
if (G.qual == 0) if (G.qual == 0)
setLocalConstraint(&Trans, (CON_APPLY|CON_AXIS2), "along local Z"); setLocalConstraint(&Trans, (CON_AXIS2), "along local Z");
else if (G.qual == LR_CTRLKEY) else if (G.qual == LR_CTRLKEY)
setLocalConstraint(&Trans, (CON_APPLY|CON_AXIS0|CON_AXIS1), "locking local Z"); setLocalConstraint(&Trans, (CON_AXIS0|CON_AXIS1), "locking local Z");
cmode = 'Z'; cmode = 'Z';
} }
else { else {
if (G.qual == 0) if (G.qual == 0)
setConstraint(&Trans, mati, (CON_APPLY|CON_AXIS2), "along global Z"); setConstraint(&Trans, mati, (CON_AXIS2), "along global Z");
else if (G.qual == LR_CTRLKEY) else if (G.qual == LR_CTRLKEY)
setConstraint(&Trans, mati, (CON_APPLY|CON_AXIS0|CON_AXIS1), "locking global Z"); setConstraint(&Trans, mati, (CON_AXIS0|CON_AXIS1), "locking global Z");
cmode = 'z'; cmode = 'z';
} }
@@ -1434,8 +1434,10 @@ void Transform(int mode)
BIF_undo_push("Transform"); BIF_undo_push("Transform");
} }
printf("before postrans\n");
/* free data, reset vars */ /* free data, reset vars */
postTrans(&Trans); postTrans(&Trans);
printf("after postrans\n");
/* mess from old transform, just for now (ton) */ /* mess from old transform, just for now (ton) */
{ {
@@ -1641,8 +1643,8 @@ int Resize(TransInfo *t, short mval[2])
continue; continue;
if (!(td->flag & TD_OBJECT)) { if (!(td->flag & TD_OBJECT)) {
Mat3MulMat3(smat, mat, td->smtx); Mat3MulMat3(smat, mat, td->mtx);
Mat3MulMat3(tmat, td->mtx, smat); Mat3MulMat3(tmat, td->smtx, smat);
} }
else { else {
Mat3CpyMat3(tmat, mat); Mat3CpyMat3(tmat, mat);
@@ -1840,11 +1842,7 @@ int Rotation(TransInfo *t, short mval[2])
float dphi; float dphi;
float vec[3], axis[3]; float vec[3], axis[3];
float mat[3][3], totmat[3][3], omat[3][3], smat[3][3]; float mat[3][3], totmat[3][3], smat[3][3];
if (G.obedit) {
Mat3CpyMat4(omat, G.obedit->obmat);
}
VECCOPY(axis, G.vd->persinv[2]); VECCOPY(axis, G.vd->persinv[2]);
Normalise(axis); Normalise(axis);
@@ -1855,6 +1853,14 @@ int Rotation(TransInfo *t, short mval[2])
if(G.qual & LR_SHIFTKEY) t->fac += dphi/30.0f; if(G.qual & LR_SHIFTKEY) t->fac += dphi/30.0f;
else t->fac += dphi; else t->fac += dphi;
/*
clamping angle between -2 PI and 2 PI (not sure if useful so commented out - theeth)
if (t->fac >= 2 * M_PI)
t->fac -= 2 * M_PI;
else if (t->fac <= -2 * M_PI)
t->fac -= -2 * M_PI;
*/
final = t->fac; final = t->fac;
snapGrid(t, &final); snapGrid(t, &final);
@@ -1896,8 +1902,8 @@ int Rotation(TransInfo *t, short mval[2])
VecRotToMat3(axis, final * td->factor, mat); VecRotToMat3(axis, final * td->factor, mat);
} }
if (G.obedit) { if (!(td->flag & TD_OBJECT)) {
Mat3MulMat3(totmat, mat, omat); Mat3MulMat3(totmat, mat, td->mtx);
Mat3MulMat3(smat, td->smtx, totmat); Mat3MulMat3(smat, td->smtx, totmat);
VecSubf(vec, td->iloc, t->center); VecSubf(vec, td->iloc, t->center);
@@ -2010,6 +2016,34 @@ void initTranslation(TransInfo *t)
else initgrabz(t->center[0], t->center[1], t->center[2]); else initgrabz(t->center[0], t->center[1], t->center[2]);
} }
void headerTranslation(TransInfo *t, float vec[3], char *str) {
char tvec[60];
if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec);
}
else {
sprintf(&tvec[0], "%.4f", vec[0]);
sprintf(&tvec[20], "%.4f", vec[1]);
sprintf(&tvec[40], "%.4f", vec[2]);
}
if (t->con.mode & CON_APPLY) {
switch(t->num.idx_max) {
case 0:
sprintf(str, "D: %s%s %s", &tvec[0], t->con.text, t->proptext);
break;
case 1:
sprintf(str, "D: %s D: %s%s %s", &tvec[0], &tvec[20], t->con.text, t->proptext);
break;
case 2:
sprintf(str, "D: %s D: %s D: %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext);
}
}
else {
sprintf(str, "Dx: %s Dy: %s Dz: %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext);
}
}
int Translation(TransInfo *t, short mval[2]) int Translation(TransInfo *t, short mval[2])
{ {
float vec[3], tvec[3]; float vec[3], tvec[3];
@@ -2019,32 +2053,16 @@ int Translation(TransInfo *t, short mval[2])
window_to_3d(vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1])); window_to_3d(vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1]));
if (t->con.applyVec) { if (t->con.mode & CON_APPLY) {
t->con.applyVec(t, NULL, vec, tvec); float pvec[3] = {0.0f, 0.0f, 0.0f};
t->con.applyVec(t, NULL, vec, tvec, pvec);
VECCOPY(vec, tvec); VECCOPY(vec, tvec);
headerTranslation(t, pvec, str);
} }
else { else {
snapGrid(t, vec); snapGrid(t, vec);
applyNumInput(&t->num, vec); applyNumInput(&t->num, vec);
} headerTranslation(t, vec, str);
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[60];
outputNumInput(&(t->num), c);
if (t->con.mode & CON_APPLY)
sprintf(str, "Dx: %s Dy: %s Dz: %s %s %s", &c[0], &c[20], &c[40], t->con.text, t->proptext);
else
sprintf(str, "Dx: %s Dy: %s Dz: %s %s", &c[0], &c[20], &c[40], t->proptext);
}
else {
/* default header print */
if (t->con.mode & CON_APPLY)
sprintf(str, "Dx: %.4f Dy: %.4f Dz: %.4f %s %s", vec[0], vec[1], vec[2], t->con.text, t->proptext);
else
sprintf(str, "Dx: %.4f Dy: %.4f Dz: %.4f %s", vec[0], vec[1], vec[2], t->proptext);
} }
@@ -2053,7 +2071,8 @@ int Translation(TransInfo *t, short mval[2])
continue; continue;
if (t->con.applyVec) { if (t->con.applyVec) {
t->con.applyVec(t, td, vec, tvec); float pvec[3];
t->con.applyVec(t, td, vec, tvec, pvec);
} }
else { else {
VECCOPY(tvec, vec); VECCOPY(tvec, vec);

View File

@@ -49,9 +49,12 @@ typedef struct TransCon {
float center[3]; /* transformation centre to define where to draw the view widget float center[3]; /* transformation centre to define where to draw the view widget
ALWAYS in global space. Unlike the transformation center */ ALWAYS in global space. Unlike the transformation center */
int mode; /* Mode flags of the Constraint */ int mode; /* Mode flags of the Constraint */
void (*applyVec)(struct TransInfo *, struct TransData *, float *, float *); void (*drawExtra)(struct TransInfo *);
/* For constraints that needs to draw differently from the other
uses this instead of the generic draw function */
void (*applyVec)(struct TransInfo *, struct TransData *, float *, float *, float *);
/* Apply function pointer for linear vectorial transformation */ /* Apply function pointer for linear vectorial transformation */
/* The last two parameters are pointers to the in/out vectors */ /* The last three parameters are pointers to the in/out/printable vectors */
void (*applySize)(struct TransInfo *, struct TransData *, float [3][3]); void (*applySize)(struct TransInfo *, struct TransData *, float [3][3]);
/* Apply function pointer for rotation transformation (prototype will change */ /* Apply function pointer for rotation transformation (prototype will change */
void (*applyRot)(struct TransInfo *, struct TransData *, float [3]); void (*applyRot)(struct TransInfo *, struct TransData *, float [3]);
@@ -89,9 +92,10 @@ typedef struct TransData {
float factor; /* Factor of the transformation (for Proportionnal Editing) */ float factor; /* Factor of the transformation (for Proportionnal Editing) */
float *loc; /* Location of the data to transform */ float *loc; /* Location of the data to transform */
float iloc[3]; /* Initial location */ float iloc[3]; /* Initial location */
float center[3]; float center[3]; /* Individual data center */
float mtx[3][3]; /* Transformation matrix from data space to global space */ float mtx[3][3]; /* Transformation matrix from data space to global space */
float smtx[3][3]; /* Transformation matrix from global space to data space */ float smtx[3][3]; /* Transformation matrix from global space to data space */
float axismtx[3][3];/* Axis orientation matrix of the data */
struct Object *ob; struct Object *ob;
TransDataExtension *ext; /* for objects, poses. 1 single malloc per TransInfo! */ TransDataExtension *ext; /* for objects, poses. 1 single malloc per TransInfo! */
TransDataIpokey *tdi; /* for objects, ipo keys. per transdata a malloc */ TransDataIpokey *tdi; /* for objects, ipo keys. per transdata a malloc */
@@ -113,6 +117,7 @@ typedef struct TransInfo {
short idx_max; short idx_max;
float snap[3]; /* Snapping Gears */ float snap[3]; /* Snapping Gears */
TransData *data; /* transformed data (array) */ TransData *data; /* transformed data (array) */
TransDataExtension *ext; /* transformed data extension (array) */
TransCon con; /* transformed constraint */ TransCon con; /* transformed constraint */
NumInput num; /* numerical input */ NumInput num; /* numerical input */
float val; /* init value for some transformations */ float val; /* init value for some transformations */
@@ -143,6 +148,7 @@ typedef struct TransInfo {
#define CON_AXIS1 4 #define CON_AXIS1 4
#define CON_AXIS2 8 #define CON_AXIS2 8
#define CON_SELECT 16 #define CON_SELECT 16
#define CON_NOFLIP 32 /* does not reorient vector to face viewport when on */
#define PROP_SHARP 0 #define PROP_SHARP 0
#define PROP_SMOOTH 1 #define PROP_SMOOTH 1

View File

@@ -114,7 +114,8 @@ void recalcData();
/* ************************** CONSTRAINTS ************************* */ /* ************************** CONSTRAINTS ************************* */
void getConstraintMatrix(TransInfo *t); void getConstraintMatrix(TransInfo *t);
void postConstraintChecks(TransInfo *t, float vec[3]) { void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3]) {
int i = 0;
Mat3MulVecfl(t->con.imtx, vec); Mat3MulVecfl(t->con.imtx, vec);
snapGrid(t, vec); snapGrid(t, vec);
@@ -131,6 +132,16 @@ void postConstraintChecks(TransInfo *t, float vec[3]) {
} }
applyNumInput(&t->num, vec); applyNumInput(&t->num, vec);
if (t->con.mode & CON_AXIS0) {
pvec[i++] = vec[0];
}
if (t->con.mode & CON_AXIS1) {
pvec[i++] = vec[1];
}
if (t->con.mode & CON_AXIS2) {
pvec[i++] = vec[2];
}
Mat3MulVecfl(t->con.mtx, vec); Mat3MulVecfl(t->con.mtx, vec);
} }
@@ -213,7 +224,7 @@ void planeProjection(TransInfo *t, float in[3], float out[3]) {
* *
*/ */
void applyAxisConstraintVec(TransInfo *t, TransData *td, float in[3], float out[3]) void applyAxisConstraintVec(TransInfo *t, TransData *td, float in[3], float out[3], float pvec[3])
{ {
VECCOPY(out, in); VECCOPY(out, in);
if (!td && t->con.mode & CON_APPLY) { if (!td && t->con.mode & CON_APPLY) {
@@ -238,7 +249,7 @@ void applyAxisConstraintVec(TransInfo *t, TransData *td, float in[3], float out[
} }
} }
postConstraintChecks(t, out); postConstraintChecks(t, out, pvec);
} }
} }
@@ -268,6 +279,31 @@ void applyAxisConstraintSize(TransInfo *t, TransData *td, float smat[3][3])
} }
} }
/*
* Callback for object based spacial constraints applied to resize motion
*
*
*/
void applyObjectConstraintSize(TransInfo *t, TransData *td, float smat[3][3])
{
if (td && t->con.mode & CON_APPLY) {
float tmat[3][3];
if (!(t->con.mode & CON_AXIS0)) {
smat[0][0] = 1.0f;
}
if (!(t->con.mode & CON_AXIS1)) {
smat[1][1] = 1.0f;
}
if (!(t->con.mode & CON_AXIS2)) {
smat[2][2] = 1.0f;
}
Mat3MulMat3(tmat, smat, td->axismtx);
Mat3MulMat3(smat, td->axismtx, tmat);
}
}
/* /*
* Generic callback for constant spacial constraints applied to rotations * Generic callback for constant spacial constraints applied to rotations
* *
@@ -276,6 +312,7 @@ void applyAxisConstraintSize(TransInfo *t, TransData *td, float smat[3][3])
* In the case of single axis constraints, the rotation axis is directly the one constrained to. * In the case of single axis constraints, the rotation axis is directly the one constrained to.
* For planar constraints (2 axis), the rotation axis is the normal of the plane. * For planar constraints (2 axis), the rotation axis is the normal of the plane.
* *
* The following only applies when CON_NOFLIP is not set.
* The vector is then modified to always point away from the screen (in global space) * The vector is then modified to always point away from the screen (in global space)
* This insures that the rotation is always logically following the mouse. * This insures that the rotation is always logically following the mouse.
* (ie: not doing counterclockwise rotations when the mouse moves clockwise). * (ie: not doing counterclockwise rotations when the mouse moves clockwise).
@@ -300,8 +337,79 @@ void applyAxisConstraintRot(TransInfo *t, TransData *td, float vec[3])
VECCOPY(vec, t->con.mtx[2]); VECCOPY(vec, t->con.mtx[2]);
break; break;
} }
if (Inpf(vec, G.vd->viewinv[2]) > 0.0f) { if (!(mode & CON_NOFLIP)) {
VecMulf(vec, -1.0f); if (Inpf(vec, G.vd->viewinv[2]) > 0.0f) {
VecMulf(vec, -1.0f);
}
}
}
}
/*
* Callback for object based spacial constraints applied to rotations
*
* The rotation axis is copied into VEC.
*
* In the case of single axis constraints, the rotation axis is directly the one constrained to.
* For planar constraints (2 axis), the rotation axis is the normal of the plane.
*
* The following only applies when CON_NOFLIP is not set.
* The vector is then modified to always point away from the screen (in global space)
* This insures that the rotation is always logically following the mouse.
* (ie: not doing counterclockwise rotations when the mouse moves clockwise).
*/
void applyObjectConstraintRot(TransInfo *t, TransData *td, float vec[3])
{
if (td && t->con.mode & CON_APPLY) {
int mode = t->con.mode & (CON_AXIS0|CON_AXIS1|CON_AXIS2);
switch(mode) {
case CON_AXIS0:
case (CON_AXIS1|CON_AXIS2):
VECCOPY(vec, td->axismtx[0]);
break;
case CON_AXIS1:
case (CON_AXIS0|CON_AXIS2):
VECCOPY(vec, td->axismtx[1]);
break;
case CON_AXIS2:
case (CON_AXIS0|CON_AXIS1):
VECCOPY(vec, td->axismtx[2]);
break;
}
if (!(mode & CON_NOFLIP)) {
if (Inpf(vec, G.vd->viewinv[2]) > 0.0f) {
VecMulf(vec, -1.0f);
}
}
}
}
void drawObjectConstraint(TransInfo *t) {
int i;
TransData * td = t->data;
if (t->con.mode & CON_AXIS0) {
drawLine(t->con.center, td->axismtx[0], 255 - 'x');
}
if (t->con.mode & CON_AXIS1) {
drawLine(t->con.center, td->axismtx[1], 255 - 'y');
}
if (t->con.mode & CON_AXIS2) {
drawLine(t->con.center, td->axismtx[2], 255 - 'z');
}
td++;
for(i=1;i<t->total;i++,td++) {
if (t->con.mode & CON_AXIS0) {
drawLine(t->con.center, td->axismtx[0], 'x');
}
if (t->con.mode & CON_AXIS1) {
drawLine(t->con.center, td->axismtx[1], 'y');
}
if (t->con.mode & CON_AXIS2) {
drawLine(t->con.center, td->axismtx[2], 'z');
} }
} }
} }
@@ -338,7 +446,7 @@ int getConstraintSpaceDimension(TransInfo *t)
} }
void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[]) { void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[]) {
strcpy(t->con.text, text); strcpy(t->con.text + 1, text);
Mat3CpyMat3(t->con.mtx, space); Mat3CpyMat3(t->con.mtx, space);
t->con.mode = mode; t->con.mode = mode;
getConstraintMatrix(t); getConstraintMatrix(t);
@@ -348,6 +456,8 @@ void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[])
Mat4MulVecfl(G.obedit->obmat, t->con.center); Mat4MulVecfl(G.obedit->obmat, t->con.center);
} }
startConstraint(t);
t->con.applyVec = applyAxisConstraintVec; t->con.applyVec = applyAxisConstraintVec;
t->con.applySize = applyAxisConstraintSize; t->con.applySize = applyAxisConstraintSize;
t->con.applyRot = applyAxisConstraintRot; t->con.applyRot = applyAxisConstraintRot;
@@ -366,6 +476,26 @@ void setLocalConstraint(TransInfo *t, int mode, const char text[]) {
Mat3CpyMat4(obmat, t->data->ob->obmat); Mat3CpyMat4(obmat, t->data->ob->obmat);
setConstraint(t, obmat, mode, text); setConstraint(t, obmat, mode, text);
} }
else {
strcpy(t->con.text + 1, text);
Mat3One(t->con.mtx);
Mat3One(t->con.imtx);
t->con.mode = mode;
getConstraintMatrix(t);
VECCOPY(t->con.center, t->center);
if (G.obedit) {
Mat4MulVecfl(G.obedit->obmat, t->con.center);
}
startConstraint(t);
t->con.drawExtra = drawObjectConstraint;
t->con.applyVec = NULL;
t->con.applySize = applyObjectConstraintSize;
t->con.applyRot = applyObjectConstraintRot;
t->redraw = 1;
}
} }
} }
@@ -390,6 +520,7 @@ void BIF_setSingleAxisConstraint(float vec[3]) {
Mat4MulVecfl(G.obedit->obmat, t->con.center); Mat4MulVecfl(G.obedit->obmat, t->con.center);
} }
t->con.drawExtra = NULL;
t->con.applyVec = applyAxisConstraintVec; t->con.applyVec = applyAxisConstraintVec;
t->con.applySize = applyAxisConstraintSize; t->con.applySize = applyAxisConstraintSize;
t->con.applyRot = applyAxisConstraintRot; t->con.applyRot = applyAxisConstraintRot;
@@ -405,20 +536,25 @@ void BIF_drawConstraint()
if (!(tc->mode & CON_APPLY)) if (!(tc->mode & CON_APPLY))
return; return;
if (tc->mode & CON_SELECT) { if (tc->drawExtra) {
drawLine(tc->center, tc->mtx[0], 'x'); tc->drawExtra(t);
drawLine(tc->center, tc->mtx[1], 'y');
drawLine(tc->center, tc->mtx[2], 'z');
} }
else {
if (tc->mode & CON_SELECT) {
drawLine(tc->center, tc->mtx[0], 'x');
drawLine(tc->center, tc->mtx[1], 'y');
drawLine(tc->center, tc->mtx[2], 'z');
}
if (tc->mode & CON_AXIS0) { if (tc->mode & CON_AXIS0) {
drawLine(tc->center, tc->mtx[0], 255 - 'x'); drawLine(tc->center, tc->mtx[0], 255 - 'x');
} }
if (tc->mode & CON_AXIS1) { if (tc->mode & CON_AXIS1) {
drawLine(tc->center, tc->mtx[1], 255 - 'y'); drawLine(tc->center, tc->mtx[1], 255 - 'y');
} }
if (tc->mode & CON_AXIS2) { if (tc->mode & CON_AXIS2) {
drawLine(tc->center, tc->mtx[2], 255 - 'z'); drawLine(tc->center, tc->mtx[2], 255 - 'z');
}
} }
} }
@@ -447,18 +583,21 @@ void BIF_drawPropCircle()
void startConstraint(TransInfo *t) { void startConstraint(TransInfo *t) {
t->con.mode |= CON_APPLY; t->con.mode |= CON_APPLY;
*t->con.text = ' ';
t->num.idx_max = MIN2(getConstraintSpaceDimension(t) - 1, t->idx_max); t->num.idx_max = MIN2(getConstraintSpaceDimension(t) - 1, t->idx_max);
} }
void stopConstraint(TransInfo *t) { void stopConstraint(TransInfo *t) {
t->con.mode &= ~CON_APPLY; t->con.mode &= ~CON_APPLY;
*t->con.text = '\0';
t->num.idx_max = t->idx_max; t->num.idx_max = t->idx_max;
} }
void getConstraintMatrix(TransInfo *t) void getConstraintMatrix(TransInfo *t)
{ {
Mat3Inv(t->con.pmtx, t->con.mtx); float mat[3][3];
Mat3CpyMat3(t->con.imtx, t->con.pmtx); Mat3Inv(t->con.imtx, t->con.mtx);
Mat3One(t->con.pmtx);
if (!(t->con.mode & CON_AXIS0)) { if (!(t->con.mode & CON_AXIS0)) {
t->con.pmtx[0][0] = t->con.pmtx[0][0] =
@@ -477,6 +616,9 @@ void getConstraintMatrix(TransInfo *t)
t->con.pmtx[2][1] = t->con.pmtx[2][1] =
t->con.pmtx[2][2] = 0.0f; t->con.pmtx[2][2] = 0.0f;
} }
Mat3MulMat3(mat, t->con.pmtx, t->con.imtx);
Mat3MulMat3(t->con.pmtx, t->con.mtx, mat);
} }
void initSelectConstraint(TransInfo *t) void initSelectConstraint(TransInfo *t)
@@ -490,6 +632,7 @@ void initSelectConstraint(TransInfo *t)
Mat4MulVecfl(G.obedit->obmat, t->con.center); Mat4MulVecfl(G.obedit->obmat, t->con.center);
} }
setNearestAxis(t); setNearestAxis(t);
t->con.drawExtra = NULL;
t->con.applyVec = applyAxisConstraintVec; t->con.applyVec = applyAxisConstraintVec;
t->con.applySize = applyAxisConstraintSize; t->con.applySize = applyAxisConstraintSize;
t->con.applyRot = applyAxisConstraintRot; t->con.applyRot = applyAxisConstraintRot;
@@ -560,31 +703,31 @@ void setNearestAxis(TransInfo *t)
if (len[0] < len[1] && len[0] < len[2]) { if (len[0] < len[1] && len[0] < len[2]) {
if (G.qual == LR_CTRLKEY) { if (G.qual == LR_CTRLKEY) {
t->con.mode |= (CON_AXIS1|CON_AXIS2); t->con.mode |= (CON_AXIS1|CON_AXIS2);
strcpy(t->con.text, "locking global X"); strcpy(t->con.text, " locking global X");
} }
else { else {
t->con.mode |= CON_AXIS0; t->con.mode |= CON_AXIS0;
strcpy(t->con.text, "along global X"); strcpy(t->con.text, " along global X");
} }
} }
else if (len[1] < len[0] && len[1] < len[2]) { else if (len[1] < len[0] && len[1] < len[2]) {
if (G.qual == LR_CTRLKEY) { if (G.qual == LR_CTRLKEY) {
t->con.mode |= (CON_AXIS0|CON_AXIS2); t->con.mode |= (CON_AXIS0|CON_AXIS2);
strcpy(t->con.text, "locking global Y"); strcpy(t->con.text, " locking global Y");
} }
else { else {
t->con.mode |= CON_AXIS1; t->con.mode |= CON_AXIS1;
strcpy(t->con.text, "along global Y"); strcpy(t->con.text, " along global Y");
} }
} }
else if (len[2] < len[1] && len[2] < len[0]) { else if (len[2] < len[1] && len[2] < len[0]) {
if (G.qual == LR_CTRLKEY) { if (G.qual == LR_CTRLKEY) {
t->con.mode |= (CON_AXIS0|CON_AXIS1); t->con.mode |= (CON_AXIS0|CON_AXIS1);
strcpy(t->con.text, "locking global Z"); strcpy(t->con.text, " locking global Z");
} }
else { else {
t->con.mode |= CON_AXIS2; t->con.mode |= CON_AXIS2;
strcpy(t->con.text, "along global Z"); strcpy(t->con.text, " along global Z");
} }
} }
getConstraintMatrix(t); getConstraintMatrix(t);

View File

@@ -45,6 +45,9 @@ void drawConstraint();
//void drawPropCircle(TransInfo *t); //void drawPropCircle(TransInfo *t);
void drawPropCircle(); void drawPropCircle();
void stopConstraint(TransInfo *t);
void startConstraint(TransInfo *t);
void getConstraintMatrix(TransInfo *t); void getConstraintMatrix(TransInfo *t);
void initSelectConstraint(TransInfo *t); void initSelectConstraint(TransInfo *t);

View File

@@ -347,15 +347,46 @@ void drawLine(float *center, float *dir, char axis)
myloadmatrix(G.vd->viewmat); myloadmatrix(G.vd->viewmat);
} }
void initTrans (TransInfo *t)
{
G.moving = 1; // Set moving flag on (display object in white)
t->data = NULL;
t->ext = NULL;
getmouseco_areawin(t->imval);
t->transform = NULL;
t->total =
t->num.idx =
t->num.idx_max =
t->num.ctrl[0] =
t->num.ctrl[1] =
t->num.ctrl[2] = 0;
t->val = 0.0f;
t->num.val[0] =
t->num.val[1] =
t->num.val[2] = 0.0f;
}
/* Here I would suggest only TransInfo related issues, like free data & reset vars. Not redraws */ /* Here I would suggest only TransInfo related issues, like free data & reset vars. Not redraws */
void postTrans (TransInfo *t) void postTrans (TransInfo *t)
{ {
TransDataExtension *tx = t->data->ext;
TransData *td; TransData *td;
int a; int a;
G.moving = 0; // Set moving flag off (display as usual) G.moving = 0; // Set moving flag off (display as usual)
stopConstraint(t);
t->con.applyVec = NULL;
t->con.applySize= NULL;
t->con.applyRot = NULL;
t->con.mode = 0;
/* since ipokeys are optional on objects, we mallocced them per trans-data */ /* since ipokeys are optional on objects, we mallocced them per trans-data */
for(a=0, td= t->data; a<t->total; a++, td++) { for(a=0, td= t->data; a<t->total; a++, td++) {
if(td->tdi) MEM_freeN(td->tdi); if(td->tdi) MEM_freeN(td->tdi);
@@ -364,7 +395,7 @@ void postTrans (TransInfo *t)
MEM_freeN(t->data); MEM_freeN(t->data);
t->data = NULL; t->data = NULL;
if (tx) MEM_freeN(tx); if (t->ext) MEM_freeN(t->ext);
} }
@@ -407,26 +438,8 @@ void apply_grid3(float *val, int max_index, float fac1, float fac2, float fac3)
} }
} }
void apply_grid1(float *val, int max_index, float factor)
{
/* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */
float fac1 = 0.0;
float fac2 = G.vd->grid * factor;
float fac3 = 0.1f * fac2;
apply_grid3(val, max_index, fac1, fac2, fac3);
}
void apply_grid2(float *val, int max_index, float factor, float factor2)
{
/* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */
float fac1 = 0.0;
float fac2 = G.vd->grid * factor;
float fac3 = factor2 * fac2;
apply_grid3(val, max_index, fac1, fac2, fac3);
}
void snapGrid(TransInfo *t, float *val) { void snapGrid(TransInfo *t, float *val) {
apply_grid3(val, t->num.idx_max, t->snap[0], t->snap[1], t->snap[2]); apply_grid3(val, t->idx_max, t->snap[0], t->snap[1], t->snap[2]);
} }
void applyTransObjects(TransInfo *t) void applyTransObjects(TransInfo *t)
@@ -495,33 +508,6 @@ void restoreTransObjects(TransInfo *t)
recalcData(t); recalcData(t);
} }
void initTrans (TransInfo *t)
{
G.moving = 1; // Set moving flag on (display object in white)
t->data = NULL;
getmouseco_areawin(t->imval);
t->transform = NULL;
t->con.applyVec = NULL;
t->con.applyRot = NULL;
t->con.mode =
t->total =
t->num.idx =
t->num.idx_max =
t->num.ctrl[0] =
t->num.ctrl[1] =
t->num.ctrl[2] = 0;
t->val = 0.0f;
t->num.val[0] =
t->num.val[1] =
t->num.val[2] = 0.0f;
}
void calculateCenterCursor(TransInfo *t) void calculateCenterCursor(TransInfo *t)
{ {
float *cursor; float *cursor;
@@ -639,9 +625,11 @@ void calculatePropRatio(TransInfo *t)
td->factor = 1.0f; td->factor = 1.0f;
} }
else if (td->dist > t->propsize) { else if (td->dist > t->propsize) {
td->flag &= TD_NOACTION;
td->factor = 0.0f; td->factor = 0.0f;
} }
else { else {
td->flag &= ~TD_NOACTION;
dist= (t->propsize-td->dist)/t->propsize; dist= (t->propsize-td->dist)/t->propsize;
switch(prop_mode) { switch(prop_mode) {
case PROP_SHARP: case PROP_SHARP: