Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Poirier <theeth@yahoo.com>2005-03-08 06:51:45 +0300
committerMartin Poirier <theeth@yahoo.com>2005-03-08 06:51:45 +0300
commit81ea38cd10d391eebce2f8629f9a93fd097e72b2 (patch)
tree2a6d7af1b67af26f55c56714cabc51023bb9708f
parent03b70c9bf54bf49ec612a484583b901b04e9b4bd (diff)
+ 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.
-rwxr-xr-xsource/blender/src/transform.c121
-rwxr-xr-xsource/blender/src/transform.h12
-rwxr-xr-xsource/blender/src/transform_constraints.c195
-rwxr-xr-xsource/blender/src/transform_constraints.h3
-rwxr-xr-xsource/blender/src/transform_generics.c84
5 files changed, 287 insertions, 128 deletions
diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c
index 745aff06279..df53adcaa96 100755
--- a/source/blender/src/transform.c
+++ b/source/blender/src/transform.c
@@ -205,7 +205,7 @@ void createTransTexspace(void)
ob= OBACT;
Trans.total = 1;
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;
VECCOPY(td->center, ob->obmat[3]);
@@ -360,7 +360,7 @@ static void createTransPose(void)
/* init trans data */
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++) {
td->ext= tdx;
td->tdi = NULL;
@@ -447,7 +447,7 @@ static void createTransMBallVerts(void)
else Trans.total = countsel;
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);
Mat3Inv(smtx, mtx);
@@ -858,7 +858,7 @@ static void ObjectToTransData(TransData *td, Object *ob)
VECCOPY(td->center, ob->obmat[3]);
- Mat3CpyMat4(td->mtx, ob->obmat);
+ Mat3CpyMat4(td->axismtx, ob->obmat);
if (ob->parent)
{
@@ -1078,7 +1078,7 @@ static void createTransObject(void)
}
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) {
if TESTBASELIB(base) {
@@ -1315,22 +1315,22 @@ void Transform(int mode)
break;
case XKEY:
if (cmode == 'X') {
- Trans.con.mode &= ~CON_APPLY;
+ stopConstraint(&Trans);
cmode = '\0';
}
else if(cmode == 'x') {
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)
- setLocalConstraint(&Trans, (CON_APPLY|CON_AXIS1|CON_AXIS2), "locking local X");
+ setLocalConstraint(&Trans, (CON_AXIS1|CON_AXIS2), "locking local X");
cmode = 'X';
}
else {
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)
- setConstraint(&Trans, mati, (CON_APPLY|CON_AXIS1|CON_AXIS2), "locking global X");
+ setConstraint(&Trans, mati, (CON_AXIS1|CON_AXIS2), "locking global X");
cmode = 'x';
}
@@ -1338,22 +1338,22 @@ void Transform(int mode)
break;
case YKEY:
if (cmode == 'Y') {
- Trans.con.mode &= ~CON_APPLY;
+ stopConstraint(&Trans);
cmode = '\0';
}
else if(cmode == 'y') {
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)
- setLocalConstraint(&Trans, (CON_APPLY|CON_AXIS0|CON_AXIS2), "locking global Y");
+ setLocalConstraint(&Trans, (CON_AXIS0|CON_AXIS2), "locking global Y");
cmode = 'Y';
}
else {
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)
- setConstraint(&Trans, mati, (CON_APPLY|CON_AXIS0|CON_AXIS2), "locking local Y");
+ setConstraint(&Trans, mati, (CON_AXIS0|CON_AXIS2), "locking local Y");
cmode = 'y';
}
@@ -1361,22 +1361,22 @@ void Transform(int mode)
break;
case ZKEY:
if (cmode == 'Z') {
- Trans.con.mode &= ~CON_APPLY;
+ stopConstraint(&Trans);
cmode = '\0';
}
else if(cmode == 'z') {
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)
- setLocalConstraint(&Trans, (CON_APPLY|CON_AXIS0|CON_AXIS1), "locking local Z");
+ setLocalConstraint(&Trans, (CON_AXIS0|CON_AXIS1), "locking local Z");
cmode = 'Z';
}
else {
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)
- setConstraint(&Trans, mati, (CON_APPLY|CON_AXIS0|CON_AXIS1), "locking global Z");
+ setConstraint(&Trans, mati, (CON_AXIS0|CON_AXIS1), "locking global Z");
cmode = 'z';
}
@@ -1434,8 +1434,10 @@ void Transform(int mode)
BIF_undo_push("Transform");
}
+ printf("before postrans\n");
/* free data, reset vars */
postTrans(&Trans);
+ printf("after postrans\n");
/* mess from old transform, just for now (ton) */
{
@@ -1641,8 +1643,8 @@ int Resize(TransInfo *t, short mval[2])
continue;
if (!(td->flag & TD_OBJECT)) {
- Mat3MulMat3(smat, mat, td->smtx);
- Mat3MulMat3(tmat, td->mtx, smat);
+ Mat3MulMat3(smat, mat, td->mtx);
+ Mat3MulMat3(tmat, td->smtx, smat);
}
else {
Mat3CpyMat3(tmat, mat);
@@ -1840,11 +1842,7 @@ int Rotation(TransInfo *t, short mval[2])
float dphi;
float vec[3], axis[3];
- float mat[3][3], totmat[3][3], omat[3][3], smat[3][3];
-
- if (G.obedit) {
- Mat3CpyMat4(omat, G.obedit->obmat);
- }
+ float mat[3][3], totmat[3][3], smat[3][3];
VECCOPY(axis, G.vd->persinv[2]);
Normalise(axis);
@@ -1855,6 +1853,14 @@ int Rotation(TransInfo *t, short mval[2])
if(G.qual & LR_SHIFTKEY) t->fac += dphi/30.0f;
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;
snapGrid(t, &final);
@@ -1896,8 +1902,8 @@ int Rotation(TransInfo *t, short mval[2])
VecRotToMat3(axis, final * td->factor, mat);
}
- if (G.obedit) {
- Mat3MulMat3(totmat, mat, omat);
+ if (!(td->flag & TD_OBJECT)) {
+ Mat3MulMat3(totmat, mat, td->mtx);
Mat3MulMat3(smat, td->smtx, totmat);
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]);
}
+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])
{
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]));
- if (t->con.applyVec) {
- t->con.applyVec(t, NULL, vec, tvec);
+ if (t->con.mode & CON_APPLY) {
+ float pvec[3] = {0.0f, 0.0f, 0.0f};
+ t->con.applyVec(t, NULL, vec, tvec, pvec);
VECCOPY(vec, tvec);
+ headerTranslation(t, pvec, str);
}
else {
snapGrid(t, vec);
applyNumInput(&t->num, vec);
- }
-
- /* 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);
+ headerTranslation(t, vec, str);
}
@@ -2053,7 +2071,8 @@ int Translation(TransInfo *t, short mval[2])
continue;
if (t->con.applyVec) {
- t->con.applyVec(t, td, vec, tvec);
+ float pvec[3];
+ t->con.applyVec(t, td, vec, tvec, pvec);
}
else {
VECCOPY(tvec, vec);
diff --git a/source/blender/src/transform.h b/source/blender/src/transform.h
index f830363eebc..6c380e343d5 100755
--- a/source/blender/src/transform.h
+++ b/source/blender/src/transform.h
@@ -49,9 +49,12 @@ typedef struct TransCon {
float center[3]; /* transformation centre to define where to draw the view widget
ALWAYS in global space. Unlike the transformation center */
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 */
- /* 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]);
/* Apply function pointer for rotation transformation (prototype will change */
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 *loc; /* Location of the data to transform */
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 smtx[3][3]; /* Transformation matrix from global space to data space */
+ float axismtx[3][3];/* Axis orientation matrix of the data */
struct Object *ob;
TransDataExtension *ext; /* for objects, poses. 1 single malloc per TransInfo! */
TransDataIpokey *tdi; /* for objects, ipo keys. per transdata a malloc */
@@ -113,6 +117,7 @@ typedef struct TransInfo {
short idx_max;
float snap[3]; /* Snapping Gears */
TransData *data; /* transformed data (array) */
+ TransDataExtension *ext; /* transformed data extension (array) */
TransCon con; /* transformed constraint */
NumInput num; /* numerical input */
float val; /* init value for some transformations */
@@ -143,6 +148,7 @@ typedef struct TransInfo {
#define CON_AXIS1 4
#define CON_AXIS2 8
#define CON_SELECT 16
+#define CON_NOFLIP 32 /* does not reorient vector to face viewport when on */
#define PROP_SHARP 0
#define PROP_SMOOTH 1
diff --git a/source/blender/src/transform_constraints.c b/source/blender/src/transform_constraints.c
index 5a48620d272..985bb431a13 100755
--- a/source/blender/src/transform_constraints.c
+++ b/source/blender/src/transform_constraints.c
@@ -114,7 +114,8 @@ void recalcData();
/* ************************** CONSTRAINTS ************************* */
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);
snapGrid(t, vec);
@@ -131,6 +132,16 @@ void postConstraintChecks(TransInfo *t, float vec[3]) {
}
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);
}
@@ -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);
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);
}
}
@@ -269,6 +280,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
*
* The rotation axis is copied into VEC.
@@ -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.
* 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).
@@ -300,8 +337,79 @@ void applyAxisConstraintRot(TransInfo *t, TransData *td, float vec[3])
VECCOPY(vec, t->con.mtx[2]);
break;
}
- if (Inpf(vec, G.vd->viewinv[2]) > 0.0f) {
- VecMulf(vec, -1.0f);
+ if (!(mode & CON_NOFLIP)) {
+ 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[]) {
- strcpy(t->con.text, text);
+ strcpy(t->con.text + 1, text);
Mat3CpyMat3(t->con.mtx, space);
t->con.mode = mode;
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);
}
+ startConstraint(t);
+
t->con.applyVec = applyAxisConstraintVec;
t->con.applySize = applyAxisConstraintSize;
t->con.applyRot = applyAxisConstraintRot;
@@ -366,6 +476,26 @@ void setLocalConstraint(TransInfo *t, int mode, const char text[]) {
Mat3CpyMat4(obmat, t->data->ob->obmat);
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);
}
+ t->con.drawExtra = NULL;
t->con.applyVec = applyAxisConstraintVec;
t->con.applySize = applyAxisConstraintSize;
t->con.applyRot = applyAxisConstraintRot;
@@ -405,20 +536,25 @@ void BIF_drawConstraint()
if (!(tc->mode & CON_APPLY))
return;
- 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->drawExtra) {
+ tc->drawExtra(t);
}
+ 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) {
- drawLine(tc->center, tc->mtx[0], 255 - 'x');
- }
- if (tc->mode & CON_AXIS1) {
- drawLine(tc->center, tc->mtx[1], 255 - 'y');
- }
- if (tc->mode & CON_AXIS2) {
- drawLine(tc->center, tc->mtx[2], 255 - 'z');
+ if (tc->mode & CON_AXIS0) {
+ drawLine(tc->center, tc->mtx[0], 255 - 'x');
+ }
+ if (tc->mode & CON_AXIS1) {
+ drawLine(tc->center, tc->mtx[1], 255 - 'y');
+ }
+ if (tc->mode & CON_AXIS2) {
+ drawLine(tc->center, tc->mtx[2], 255 - 'z');
+ }
}
}
@@ -447,18 +583,21 @@ void BIF_drawPropCircle()
void startConstraint(TransInfo *t) {
t->con.mode |= CON_APPLY;
+ *t->con.text = ' ';
t->num.idx_max = MIN2(getConstraintSpaceDimension(t) - 1, t->idx_max);
}
void stopConstraint(TransInfo *t) {
t->con.mode &= ~CON_APPLY;
+ *t->con.text = '\0';
t->num.idx_max = t->idx_max;
}
void getConstraintMatrix(TransInfo *t)
{
- Mat3Inv(t->con.pmtx, t->con.mtx);
- Mat3CpyMat3(t->con.imtx, t->con.pmtx);
+ float mat[3][3];
+ Mat3Inv(t->con.imtx, t->con.mtx);
+ Mat3One(t->con.pmtx);
if (!(t->con.mode & CON_AXIS0)) {
t->con.pmtx[0][0] =
@@ -477,6 +616,9 @@ void getConstraintMatrix(TransInfo *t)
t->con.pmtx[2][1] =
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)
@@ -490,6 +632,7 @@ void initSelectConstraint(TransInfo *t)
Mat4MulVecfl(G.obedit->obmat, t->con.center);
}
setNearestAxis(t);
+ t->con.drawExtra = NULL;
t->con.applyVec = applyAxisConstraintVec;
t->con.applySize = applyAxisConstraintSize;
t->con.applyRot = applyAxisConstraintRot;
@@ -560,31 +703,31 @@ void setNearestAxis(TransInfo *t)
if (len[0] < len[1] && len[0] < len[2]) {
if (G.qual == LR_CTRLKEY) {
t->con.mode |= (CON_AXIS1|CON_AXIS2);
- strcpy(t->con.text, "locking global X");
+ strcpy(t->con.text, " locking global X");
}
else {
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]) {
if (G.qual == LR_CTRLKEY) {
t->con.mode |= (CON_AXIS0|CON_AXIS2);
- strcpy(t->con.text, "locking global Y");
+ strcpy(t->con.text, " locking global Y");
}
else {
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]) {
if (G.qual == LR_CTRLKEY) {
t->con.mode |= (CON_AXIS0|CON_AXIS1);
- strcpy(t->con.text, "locking global Z");
+ strcpy(t->con.text, " locking global Z");
}
else {
t->con.mode |= CON_AXIS2;
- strcpy(t->con.text, "along global Z");
+ strcpy(t->con.text, " along global Z");
}
}
getConstraintMatrix(t);
diff --git a/source/blender/src/transform_constraints.h b/source/blender/src/transform_constraints.h
index 7ac5817e980..56552d610c6 100755
--- a/source/blender/src/transform_constraints.h
+++ b/source/blender/src/transform_constraints.h
@@ -45,6 +45,9 @@ void drawConstraint();
//void drawPropCircle(TransInfo *t);
void drawPropCircle();
+void stopConstraint(TransInfo *t);
+void startConstraint(TransInfo *t);
+
void getConstraintMatrix(TransInfo *t);
void initSelectConstraint(TransInfo *t);
diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c
index 966d44868a3..563ef654c58 100755
--- a/source/blender/src/transform_generics.c
+++ b/source/blender/src/transform_generics.c
@@ -347,15 +347,46 @@ void drawLine(float *center, float *dir, char axis)
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 */
void postTrans (TransInfo *t)
{
- TransDataExtension *tx = t->data->ext;
TransData *td;
int a;
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 */
for(a=0, td= t->data; a<t->total; a++, td++) {
if(td->tdi) MEM_freeN(td->tdi);
@@ -364,7 +395,7 @@ void postTrans (TransInfo *t)
MEM_freeN(t->data);
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) {
- 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)
@@ -495,33 +508,6 @@ void restoreTransObjects(TransInfo *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)
{
float *cursor;
@@ -639,9 +625,11 @@ void calculatePropRatio(TransInfo *t)
td->factor = 1.0f;
}
else if (td->dist > t->propsize) {
+ td->flag &= TD_NOACTION;
td->factor = 0.0f;
}
else {
+ td->flag &= ~TD_NOACTION;
dist= (t->propsize-td->dist)/t->propsize;
switch(prop_mode) {
case PROP_SHARP: