This commit adds local target rotation support to the floor constraint,

making it much more useful. Requested and taunted for frequently by
Plumiferos folks. Click on "Use Rot" to take target object rotations
into account.

Good for using rotated empties, etc., as a sloped floor.
This commit is contained in:
Roland Hess
2006-09-22 15:57:58 +00:00
parent 3d3b64768d
commit 4725ca6c02
4 changed files with 51 additions and 26 deletions

View File

@@ -598,8 +598,7 @@ void *new_constraint_data (short type)
data->minmaxflag = TRACK_Z;
data->offset = 0.0f;
data->cache[0] = data->cache[1] = data->cache[2] = 0.0f;
data->sticky = 0;
data->stuck = 0;
data->flag = 0;
result = data;
@@ -1250,38 +1249,50 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype,
float val1, val2;
int index;
bMinMaxConstraint *data;
float obmat[4][4],imat[4][4],tarmat[4][4],tmat[4][4];
data = constraint->data;
Mat4CpyMat4(obmat,ob->obmat);
Mat4CpyMat4(tarmat,targetmat);
if (data->flag&MINMAX_USEROT) {
/* take rotation of target into account by doing the transaction in target's localspace */
Mat4Invert(imat,tarmat);
Mat4MulMat4(tmat,obmat,imat);
Mat4CpyMat4(obmat,tmat);
Mat4One(tarmat);
}
switch (data->minmaxflag){
case TRACK_Z:
val1 = targetmat[3][2];
val2 = ob->obmat[3][2]-data->offset;
val1 = tarmat[3][2];
val2 = obmat[3][2]-data->offset;
index = 2;
break;
case TRACK_Y:
val1 = targetmat[3][1];
val2 = ob->obmat[3][1]-data->offset;
val1 = tarmat[3][1];
val2 = obmat[3][1]-data->offset;
index = 1;
break;
case TRACK_X:
val1 = targetmat[3][0];
val2 = ob->obmat[3][0]-data->offset;
val1 = tarmat[3][0];
val2 = obmat[3][0]-data->offset;
index = 0;
break;
case TRACK_nZ:
val2 = targetmat[3][2];
val1 = ob->obmat[3][2]-data->offset;
val2 = tarmat[3][2];
val1 = obmat[3][2]-data->offset;
index = 2;
break;
case TRACK_nY:
val2 = targetmat[3][1];
val1 = ob->obmat[3][1]-data->offset;
val2 = tarmat[3][1];
val1 = obmat[3][1]-data->offset;
index = 1;
break;
case TRACK_nX:
val2 = targetmat[3][0];
val1 = ob->obmat[3][0]-data->offset;
val2 = tarmat[3][0];
val1 = obmat[3][0]-data->offset;
index = 0;
break;
default:
@@ -1289,18 +1300,27 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype,
}
if (val1 > val2) {
ob->obmat[3][index] = targetmat[3][index] + data->offset;
if (data->sticky==1) {
if (data->stuck==1) {
VECCOPY(ob->obmat[3], data->cache);
obmat[3][index] = tarmat[3][index] + data->offset;
if (data->flag&MINMAX_STICKY) {
if (data->flag&MINMAX_STUCK) {
VECCOPY(obmat[3], data->cache);
} else {
VECCOPY(data->cache, ob->obmat[3]);
data->stuck = 1;
VECCOPY(data->cache, obmat[3]);
data->flag|=MINMAX_STUCK;
}
}
if (data->flag&MINMAX_USEROT) {
/* get out of localspace */
Mat4MulMat4(tmat,obmat,targetmat);
Mat4CpyMat4(ob->obmat,tmat);
} else {
VECCOPY(ob->obmat[3],obmat[3]);
}
} else {
data->stuck=0;
data->flag&=~MINMAX_STUCK;
}
}
break;
case CONSTRAINT_TYPE_TRACKTO:

View File

@@ -99,8 +99,7 @@ typedef struct bMinMaxConstraint{
Object *tar;
int minmaxflag;
float offset;
short sticky;
short stuck;
int flag;
float cache[3];
char subtarget[32];
} bMinMaxConstraint;
@@ -278,6 +277,11 @@ typedef struct bSizeLimitConstraint{
#define CONSTRAINT_IK_AUTO 4
#define CONSTRAINT_IK_TEMP 8
/* MinMax (floor) flags */
#define MINMAX_STICKY 0x01
#define MINMAX_STUCK 0x02
#define MINMAX_USEROT 0x04
/* transform limiting constraints -> flag */
#define LIMIT_XMIN 0x01
#define LIMIT_XMAX 0x02

View File

@@ -762,7 +762,7 @@ static PyObject *floor_getter( BPy_Constraint * self, int type )
case EXPP_CONSTR_OFFSET:
return PyFloat_FromDouble( (double)con->offset );
case EXPP_CONSTR_STICKY:
return PyBool_FromLong( (long)( con->sticky & SELECT ) ) ;
return PyBool_FromLong( (long)( con->flag & MINMAX_STICKY ) ) ;
default:
return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
}
@@ -797,7 +797,7 @@ static int floor_setter( BPy_Constraint *self, int type, PyObject *value )
case EXPP_CONSTR_OFFSET:
return EXPP_setFloatClamped( value, &con->offset, -100.0, 100.0 );
case EXPP_CONSTR_STICKY:
return EXPP_setBitfield( value, &con->sticky, SELECT, 'h' );
return EXPP_setBitfield( value, &con->flag, MINMAX_STICKY, 'h' );
default:
return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
}

View File

@@ -847,7 +847,8 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
strcpy (data->subtarget, "");
uiBlockEndAlign(block);
but=uiDefButBitS(block, TOG, 1, B_CONSTRAINT_TEST, "Sticky", *xco, *yco-24, 54, 18, &data->sticky, 0, 24, 0, 0, "Immobilize object while constrained");
but=uiDefButI(block, TOG|BIT|0, B_CONSTRAINT_TEST, "Sticky", *xco, *yco-24, 44, 18, &data->flag, 0, 24, 0, 0, "Immobilize object while constrained");
but=uiDefButI(block, TOG|BIT|2, B_CONSTRAINT_TEST, "Use Rot", *xco+44, *yco-24, 64, 18, &data->flag, 0, 24, 0, 0, "Use target object rotation");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Max/Min:", *xco-8, *yco-64, 54, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");