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:
authorTon Roosendaal <ton@blender.org>2007-12-01 13:48:33 +0300
committerTon Roosendaal <ton@blender.org>2007-12-01 13:48:33 +0300
commit45c41ffb693f96856d5969a2427e504472026162 (patch)
tree1fd55c14fc2740380fea43d0f2ffa01a5d18b399 /source/blender/blenkernel
parent587b2d0d3a171f8ea11919ebea0e2a5af77508d1 (diff)
Two fixes:
- new option for Local Constraint Ipos did not set user counter in Ipo at file reading, causing data to get lost (not saved). - Driver feature: the channels "Loc X Y Z" now also use the result of constraints, but transformed back into local space, as if it was action X Y Z. Nice stuff for those who understand this... it means you can drive something with a bone that has constraints.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/intern/ipo.c71
1 files changed, 36 insertions, 35 deletions
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 03a34df090a..6f6711a2a18 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -758,44 +758,47 @@ void berekenx(float *f, float *o, int b)
}
}
-#define TFM_WITHOUT_BONE 1
-
-static void posechannel_get_local_transform(bPoseChannel *pchan, float *quat, float *eul, float *size, int flag)
+/* we need the local transform = current transform - (parent transform + bone transform) */
+/* (local transform is on action channel level) */
+static void posechannel_get_local_transform(bPoseChannel *pchan, float *loc, float *eul, float *size)
{
- float pose_mat[3][3];
- float diff_mat[3][3], ipar_mat[3][3];
-
- /* we need the local transform = current transform - (parent transform + bone transform) */
-
- Mat3CpyMat4(pose_mat, pchan->pose_mat);
+ float diff_mat[4][4];
+ float parmat[4][4], offs_bone[4][4], imat[4][4];
if (pchan->parent) {
+ /* get first the parent + bone transform in parmat */
- if(flag & TFM_WITHOUT_BONE) {
- float par_mat[3][3];
- Mat3CpyMat4(par_mat, pchan->parent->pose_mat);
- Mat3MulMat3(diff_mat, par_mat, pchan->bone->bone_mat);
- }
- else
- Mat3CpyMat4(diff_mat, pchan->parent->pose_mat);
-
- Mat3Inv(ipar_mat, diff_mat);
+ /* bone transform itself */
+ Mat4CpyMat3(offs_bone, pchan->bone->bone_mat);
+ /* The bone's root offset (is in the parent's coordinate system) */
+ VECCOPY(offs_bone[3], pchan->bone->head);
+ /* Get the length translation of parent (length along y axis) */
+ offs_bone[3][1]+= pchan->parent->bone->length;
+
+ Mat4MulSerie(parmat, pchan->parent->pose_mat, offs_bone, NULL, NULL, NULL, NULL, NULL, NULL);
+
+ /* invert it */
+ Mat4Invert(imat, parmat);
}
else {
- if(flag & TFM_WITHOUT_BONE)
- Mat3Inv(ipar_mat, pchan->bone->bone_mat);
- else
- Mat3One(ipar_mat);
+ Mat4CpyMat3(offs_bone, pchan->bone->bone_mat);
+ VECCOPY(offs_bone[3], pchan->bone->head);
+
+ /* invert it */
+ Mat4Invert(imat, offs_bone);
+
}
- Mat3MulMat3(diff_mat, ipar_mat, pose_mat);
-
- if(quat)
- Mat3ToQuat(diff_mat, quat);
+ /* difference: current transform - (parent transform + bone transform) */
+ Mat4MulMat4(diff_mat, pchan->pose_mat, imat);
+
+ if(loc)
+ VECCOPY(loc, diff_mat[3]);
if(eul)
- Mat3ToEul(diff_mat, eul);
+ Mat4ToEul(diff_mat, eul);
if(size)
- Mat3ToSize(diff_mat, size);
+ Mat4ToSize(diff_mat, size);
+
}
/* has to return a float value */
@@ -858,8 +861,6 @@ static float eval_driver(IpoDriver *driver, float ipotime)
Mat4ToQuat(pchan->pose_mat, q1);
Mat4ToQuat(pchan2->pose_mat, q2);
- // posechannel_get_local_transform(pchan , q1, NULL, NULL, 0);
- // posechannel_get_local_transform(pchan2, q2, NULL, NULL, 0);
QuatInv(q1);
QuatMul(quat, q1, q2);
@@ -870,17 +871,17 @@ static float eval_driver(IpoDriver *driver, float ipotime)
}
}
else {
- float eul[3], size[3];
+ float loc[3], eul[3], size[3];
- posechannel_get_local_transform(pchan, NULL, eul, size, TFM_WITHOUT_BONE);
+ posechannel_get_local_transform(pchan, loc, eul, size);
switch(driver->adrcode) {
case OB_LOC_X:
- return pchan->loc[0];
+ return loc[0];
case OB_LOC_Y:
- return pchan->loc[1];
+ return loc[1];
case OB_LOC_Z:
- return pchan->loc[2];
+ return loc[2];
case OB_ROT_X:
return eul[0]/(M_PI_2/9.0);
case OB_ROT_Y: