diff options
author | Joshua Leung <aligorith@gmail.com> | 2009-09-02 14:45:11 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2009-09-02 14:45:11 +0400 |
commit | 01b4caa701c21b88b4447d7d4fd5570b05fa5979 (patch) | |
tree | 390563ce8d6c55d105a603bd1d9341e8eaf033b6 /source/blender/blenkernel | |
parent | 0763627e394bf4b634584a11f1b15dca33d94258 (diff) |
2.5 - Rotation order is now taken into account for constraints
* Added a 'rotOrder' parameter for constraint evaluation objects and constraint targets, which describes the rotation mode used for the matrices there.
Todos:
* Constraint targets default to using XYZ only for now. This will need be be addressed eventually.
* Copy Rotation constraint currently cannot use the new rotation order code for the target matrix. What's surprising is that even though it's just using XYZ as the old code did, it doesn't work, and yet everything else works nicely. Silly constraint! (it is almost impossible to improve this constraint further without breaking a rig out there)
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_constraint.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 43 |
2 files changed, 29 insertions, 15 deletions
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h index 6e69906b71d..a0061173438 100644 --- a/source/blender/blenkernel/BKE_constraint.h +++ b/source/blender/blenkernel/BKE_constraint.h @@ -49,6 +49,7 @@ typedef struct bConstraintOb { float startmat[4][4]; /* original matrix (before constraint solving) */ short type; /* type of owner */ + short rotOrder; /* rotation order for constraint owner (as defined in eEulerRotationOrders in BLI_arithb.h) */ } bConstraintOb; /* ---------------------------------------------------------------------------- */ diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 88e73a00ba7..e6e65ebd614 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -121,6 +121,7 @@ bConstraintOb *constraints_make_evalob (Scene *scene, Object *ob, void *subdata, if (ob) { cob->ob = ob; cob->type = datatype; + cob->rotOrder = EULER_ORDER_DEFAULT; // TODO: when objects have rotation order too, use that Mat4CpyMat4(cob->matrix, ob->obmat); } else @@ -137,6 +138,15 @@ bConstraintOb *constraints_make_evalob (Scene *scene, Object *ob, void *subdata, cob->pchan = (bPoseChannel *)subdata; cob->type = datatype; + if (cob->pchan->rotmode > 0) { + /* should be some type of Euler order */ + cob->rotOrder= cob->pchan->rotmode; + } + else { + /* Quats, so eulers should just use default order */ + cob->rotOrder= EULER_ORDER_DEFAULT; + } + /* matrix in world-space */ Mat4MulMat4(cob->matrix, cob->pchan->pose_mat, ob->obmat); } @@ -664,6 +674,7 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain * (Hopefully all compilers will be happy with the lines with just a space on them. Those are * really just to help this code easier to read) */ +// TODO: cope with getting rotation order... #define SINGLETARGET_GET_TARS(con, datatar, datasubtarget, ct, list) \ { \ ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \ @@ -687,6 +698,7 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain * (Hopefully all compilers will be happy with the lines with just a space on them. Those are * really just to help this code easier to read) */ +// TODO: cope with getting rotation order... #define SINGLETARGETNS_GET_TARS(con, datatar, ct, list) \ { \ ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \ @@ -795,11 +807,11 @@ static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta /* extract components of both matrices */ VECCOPY(loc, ct->matrix[3]); - Mat4ToEul(ct->matrix, eul); + Mat4ToEulO(ct->matrix, eul, ct->rotOrder); Mat4ToSize(ct->matrix, size); VECCOPY(loco, invmat[3]); - Mat4ToEul(invmat, eulo); + Mat4ToEulO(invmat, eulo, cob->rotOrder); Mat4ToSize(invmat, sizo); /* disable channels not enabled */ @@ -814,8 +826,8 @@ static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta if (!(data->flag & CHILDOF_SIZEZ)) size[2]= sizo[2]= 1.0f; /* make new target mat and offset mat */ - LocEulSizeToMat4(ct->matrix, loc, eul, size); - LocEulSizeToMat4(invmat, loco, eulo, sizo); + LocEulOSizeToMat4(ct->matrix, loc, eul, size, ct->rotOrder); + LocEulOSizeToMat4(invmat, loco, eulo, sizo, cob->rotOrder); /* multiply target (parent matrix) by offset (parent inverse) to get * the effect of the parent that will be exherted on the owner @@ -1304,7 +1316,7 @@ static void rotlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *t VECCOPY(loc, cob->matrix[3]); Mat4ToSize(cob->matrix, size); - Mat4ToEul(cob->matrix, eul); + Mat4ToEulO(cob->matrix, eul, cob->rotOrder); /* eulers: radians to degrees! */ eul[0] = (float)(eul[0] / M_PI * 180); @@ -1339,7 +1351,7 @@ static void rotlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *t eul[1] = (float)(eul[1] / 180 * M_PI); eul[2] = (float)(eul[2] / 180 * M_PI); - LocEulSizeToMat4(cob->matrix, loc, eul, size); + LocEulOSizeToMat4(cob->matrix, loc, eul, size, cob->rotOrder); } static bConstraintTypeInfo CTI_ROTLIMIT = { @@ -1546,14 +1558,15 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta VECCOPY(loc, cob->matrix[3]); Mat4ToSize(cob->matrix, size); - Mat4ToEul(ct->matrix, eul); - Mat4ToEul(cob->matrix, obeul); + //Mat4ToEulO(ct->matrix, eul, ct->rotOrder); + Mat4ToEul(ct->matrix, eul); // the version we should be using causes errors... + Mat4ToEulO(cob->matrix, obeul, cob->rotOrder); if ((data->flag & ROTLIKE_X)==0) eul[0] = obeul[0]; else { if (data->flag & ROTLIKE_OFFSET) - euler_rot(eul, obeul[0], 'x'); + eulerO_rot(eul, obeul[0], 'x', cob->rotOrder); if (data->flag & ROTLIKE_X_INVERT) eul[0] *= -1; @@ -1563,7 +1576,7 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta eul[1] = obeul[1]; else { if (data->flag & ROTLIKE_OFFSET) - euler_rot(eul, obeul[1], 'y'); + eulerO_rot(eul, obeul[1], 'y', cob->rotOrder); if (data->flag & ROTLIKE_Y_INVERT) eul[1] *= -1; @@ -1573,14 +1586,14 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta eul[2] = obeul[2]; else { if (data->flag & ROTLIKE_OFFSET) - euler_rot(eul, obeul[2], 'z'); + eulerO_rot(eul, obeul[2], 'z', cob->rotOrder); if (data->flag & ROTLIKE_Z_INVERT) eul[2] *= -1; } compatible_eul(eul, obeul); - LocEulSizeToMat4(cob->matrix, loc, eul, size); + LocEulOSizeToMat4(cob->matrix, loc, eul, size, cob->rotOrder); } } @@ -3036,7 +3049,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase * Mat4ToSize(ct->matrix, dvec); break; case 1: /* rotation (convert to degrees first) */ - Mat4ToEul(ct->matrix, dvec); + Mat4ToEulO(ct->matrix, dvec, cob->rotOrder); for (i=0; i<3; i++) dvec[i] = (float)(dvec[i] / M_PI * 180); break; @@ -3047,7 +3060,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase * /* extract components of owner's matrix */ VECCOPY(loc, cob->matrix[3]); - Mat4ToEul(cob->matrix, eul); + Mat4ToEulO(cob->matrix, eul, cob->rotOrder); Mat4ToSize(cob->matrix, size); /* determine where in range current transforms lie */ @@ -3102,7 +3115,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase * } /* apply to matrix */ - LocEulSizeToMat4(cob->matrix, loc, eul, size); + LocEulOSizeToMat4(cob->matrix, loc, eul, size, cob->rotOrder); } } |