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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2010-04-19 13:38:36 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2010-04-19 13:38:36 +0400
commit1dce678c2b411e0d2802ce1ff94438ac513e5064 (patch)
treeca3ef7f7d5a739a7199ec7000e062870b6b1629c /source/blender/editors/transform
parent3b502ca727563e2c58fa8396ea510d191a912518 (diff)
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.
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r--source/blender/editors/transform/transform.c105
1 files changed, 62 insertions, 43 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 809ea0e96c5..3539cf9562e 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -1921,39 +1921,50 @@ static void constraintTransLim(TransInfo *t, TransData *td)
}
}
+static void constraintob_from_transdata(bConstraintOb *cob, TransData *td)
+{
+ /* Make a temporary bConstraintOb for use by limit constraints
+ * - they only care that cob->matrix is correctly set ;-)
+ * - current space should be local
+ */
+ memset(cob, 0, sizeof(bConstraintOb));
+ if (td->rotOrder == ROT_MODE_QUAT) {
+ /* quats */
+ if (td->ext) {
+ /* 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
+ return;
+ }
+ else if (td->rotOrder == ROT_MODE_AXISANGLE) {
+ /* axis angle */
+ if (td->ext)
+ axis_angle_to_mat4(cob->matrix, &td->ext->quat[1], td->ext->quat[0]);
+ else
+ return;
+ }
+ else {
+ /* eulers */
+ if (td->ext)
+ eulO_to_mat4(cob->matrix, td->ext->rot, td->rotOrder);
+ else
+ return;
+ }
+}
+
static void constraintRotLim(TransInfo *t, TransData *td)
{
if (td->con) {
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 ;-)
- * - current space should be local
- */
- memset(&cob, 0, sizeof(bConstraintOb));
- if (td->rotOrder == ROT_MODE_QUAT) {
- /* quats */
- if (td->ext)
- quat_to_mat4( cob.matrix,td->ext->quat);
- else
- return;
- }
- else if (td->rotOrder == ROT_MODE_AXISANGLE) {
- /* axis angle */
- if (td->ext)
- axis_angle_to_mat4( cob.matrix,&td->ext->quat[1], td->ext->quat[0]);
- else
- return;
- }
- else {
- /* eulers */
- if (td->ext)
- eulO_to_mat4( cob.matrix,td->ext->rot, td->rotOrder);
- else
- return;
- }
+ int dolimit = 0;
/* Evaluate valid constraints */
for (con= td->con; con; con= con->next) {
@@ -1969,6 +1980,16 @@ static void constraintRotLim(TransInfo *t, TransData *td)
/* only use it if it's tagged for this purpose */
if ((data->flag2 & LIMIT_TRANSFORM)==0)
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 */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
@@ -1976,10 +1997,6 @@ static void constraintRotLim(TransInfo *t, TransData *td)
copy_m4_m4(tmat, cob.matrix);
mul_m4_m3m4(cob.matrix, td->mtx, tmat);
}
- else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
- /* skip... incompatable spacetype */
- continue;
- }
/* do constraint */
cti->evaluate_constraint(con, &cob, NULL);
@@ -1993,18 +2010,20 @@ static void constraintRotLim(TransInfo *t, TransData *td)
}
}
- /* copy results from cob->matrix */
- if (td->rotOrder == ROT_MODE_QUAT) {
- /* quats */
- mat4_to_quat( td->ext->quat,cob.matrix);
- }
- else if (td->rotOrder == ROT_MODE_AXISANGLE) {
- /* axis angle */
- mat4_to_axis_angle( &td->ext->quat[1], &td->ext->quat[0],cob.matrix);
- }
- else {
- /* eulers */
- mat4_to_eulO( td->ext->rot, td->rotOrder,cob.matrix);
+ if(dolimit) {
+ /* copy results from cob->matrix */
+ if (td->rotOrder == ROT_MODE_QUAT) {
+ /* quats */
+ mat4_to_quat( td->ext->quat,cob.matrix);
+ }
+ else if (td->rotOrder == ROT_MODE_AXISANGLE) {
+ /* axis angle */
+ mat4_to_axis_angle( &td->ext->quat[1], &td->ext->quat[0],cob.matrix);
+ }
+ else {
+ /* eulers */
+ mat4_to_eulO( td->ext->rot, td->rotOrder,cob.matrix);
+ }
}
}
}