Fix problem with limit rotation constraints during transform. This code

would convert from quat to matrix and back if the bone had any constraint,
but did not normalize the quat first as done in other places, giving a
sudden jump when starting transform on some bones with constraints. Two
changes:

* Normalize quaternion first.
* Only do this conversion on bones with limit rotation constraints,
  instead of all bones with any constraint.
This commit is contained in:
Brecht Van Lommel 2010-04-19 09:38:36 +00:00
parent 3b502ca727
commit 1dce678c2b

@ -1921,39 +1921,50 @@ static void constraintTransLim(TransInfo *t, TransData *td)
} }
} }
static void constraintRotLim(TransInfo *t, TransData *td) static void constraintob_from_transdata(bConstraintOb *cob, TransData *td)
{ {
if (td->con) { /* Make a temporary bConstraintOb for use by limit constraints
bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_ROTLIMIT);
bConstraintOb cob;
bConstraint *con;
/* Make a temporary bConstraintOb for using these limit constraints
* - they only care that cob->matrix is correctly set ;-) * - they only care that cob->matrix is correctly set ;-)
* - current space should be local * - current space should be local
*/ */
memset(&cob, 0, sizeof(bConstraintOb)); memset(cob, 0, sizeof(bConstraintOb));
if (td->rotOrder == ROT_MODE_QUAT) { if (td->rotOrder == ROT_MODE_QUAT) {
/* quats */ /* quats */
if (td->ext) if (td->ext) {
quat_to_mat4( cob.matrix,td->ext->quat); /* objects and bones do normalization first too, otherwise
we don't necessarily end up with a rotation matrix, and
then conversion back to quat gives a different result */
float quat[4];
copy_qt_qt(quat, td->ext->quat);
normalize_qt(quat);
quat_to_mat4(cob->matrix, quat);
}
else else
return; return;
} }
else if (td->rotOrder == ROT_MODE_AXISANGLE) { else if (td->rotOrder == ROT_MODE_AXISANGLE) {
/* axis angle */ /* axis angle */
if (td->ext) if (td->ext)
axis_angle_to_mat4( cob.matrix,&td->ext->quat[1], td->ext->quat[0]); axis_angle_to_mat4(cob->matrix, &td->ext->quat[1], td->ext->quat[0]);
else else
return; return;
} }
else { else {
/* eulers */ /* eulers */
if (td->ext) if (td->ext)
eulO_to_mat4( cob.matrix,td->ext->rot, td->rotOrder); eulO_to_mat4(cob->matrix, td->ext->rot, td->rotOrder);
else else
return; return;
} }
}
static void constraintRotLim(TransInfo *t, TransData *td)
{
if (td->con) {
bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_ROTLIMIT);
bConstraintOb cob;
bConstraint *con;
int dolimit = 0;
/* Evaluate valid constraints */ /* Evaluate valid constraints */
for (con= td->con; con; con= con->next) { for (con= td->con; con; con= con->next) {
@ -1970,16 +1981,22 @@ static void constraintRotLim(TransInfo *t, TransData *td)
if ((data->flag2 & LIMIT_TRANSFORM)==0) if ((data->flag2 & LIMIT_TRANSFORM)==0)
continue; continue;
/* skip incompatable spacetypes */
if (!ELEM(con->ownspace, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL))
continue;
/* only do conversion if necessary, to preserve quats and eulers */
if(!dolimit) {
constraintob_from_transdata(&cob, td);
dolimit= 1;
}
/* do space conversions */ /* do space conversions */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) { if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */ /* just multiply by td->mtx (this should be ok) */
copy_m4_m4(tmat, cob.matrix); copy_m4_m4(tmat, cob.matrix);
mul_m4_m3m4(cob.matrix, td->mtx, tmat); mul_m4_m3m4(cob.matrix, td->mtx, tmat);
} }
else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
/* skip... incompatable spacetype */
continue;
}
/* do constraint */ /* do constraint */
cti->evaluate_constraint(con, &cob, NULL); cti->evaluate_constraint(con, &cob, NULL);
@ -1993,6 +2010,7 @@ static void constraintRotLim(TransInfo *t, TransData *td)
} }
} }
if(dolimit) {
/* copy results from cob->matrix */ /* copy results from cob->matrix */
if (td->rotOrder == ROT_MODE_QUAT) { if (td->rotOrder == ROT_MODE_QUAT) {
/* quats */ /* quats */
@ -2007,6 +2025,7 @@ static void constraintRotLim(TransInfo *t, TransData *td)
mat4_to_eulO( td->ext->rot, td->rotOrder,cob.matrix); mat4_to_eulO( td->ext->rot, td->rotOrder,cob.matrix);
} }
} }
}
} }
static void constraintSizeLim(TransInfo *t, TransData *td) static void constraintSizeLim(TransInfo *t, TransData *td)