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:
authorJoshua Leung <aligorith@gmail.com>2011-06-13 17:54:21 +0400
committerJoshua Leung <aligorith@gmail.com>2011-06-13 17:54:21 +0400
commita4216cb1d4336bd2244f4519398db0b9f19833ad (patch)
tree29a031f5980afc355b0372b8c875fa216159bd28 /source/blender/blenkernel/intern/fcurve.c
parent8e85491ab7f4d2e156910eceb87ca4023d42c95a (diff)
Transformation Channel Driver Variables - "Proper Localspace"
By popular demand, the "Transformation Channel" driver variable type now has a "local space" transform space option which uses the same magic that constraints use for defining local-space. This is what many bug reporters and feature requesters have moaned about for a while now, so after reviewing several of the bug reports which lead to the current situation, here is what has been much-wanted for so long! In order to implement this, I've: - renamed the old "Local Space" option here to "Transformation Space", in order to prevent old rigs breaking. This has also been kept, as it is useful for #21384 (though perhaps with this new option it isn't needed anymore) - reviewed my fix for #20870 (IIRC, a Durian-era bug), which related to the non-uniqueness of matrix->euler decomposition
Diffstat (limited to 'source/blender/blenkernel/intern/fcurve.c')
-rw-r--r--source/blender/blenkernel/intern/fcurve.c70
1 files changed, 55 insertions, 15 deletions
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index d6a9d950015..be2a6a762ee 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -42,6 +42,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
+#include "DNA_constraint_types.h"
#include "DNA_object_types.h"
#include "BLI_blenlib.h"
@@ -52,6 +53,7 @@
#include "BKE_animsys.h"
#include "BKE_action.h"
#include "BKE_armature.h"
+#include "BKE_constraint.h"
#include "BKE_curve.h"
#include "BKE_global.h"
#include "BKE_object.h"
@@ -1197,7 +1199,7 @@ static float dvar_eval_transChan (ChannelDriver *driver, DriverVar *dvar)
Object *ob= (Object *)dtar_id_ensure_proxy_from(dtar->id);
bPoseChannel *pchan;
float mat[4][4];
- float eul[3] = {0.0f,0.0f,0.0f};
+ float oldEul[3] = {0.0f,0.0f,0.0f};
short useEulers=0, rotOrder=ROT_MODE_EUL;
/* check if this target has valid data */
@@ -1210,36 +1212,62 @@ static float dvar_eval_transChan (ChannelDriver *driver, DriverVar *dvar)
/* try to get posechannel */
pchan= get_pose_channel(ob->pose, dtar->pchan_name);
- /* check if object or bone, and get transform matrix accordingly */
+ /* check if object or bone, and get transform matrix accordingly
+ * - "useEulers" code is used to prevent the problems associated with non-uniqueness
+ * of euler decomposition from matrices [#20870]
+ * - localspace is for [#21384], where parent results are not wanted
+ * but local-consts is for all the common "corrective-shapes-for-limbs" situations
+ */
if (pchan) {
/* bone */
if (pchan->rotmode > 0) {
- VECCOPY(eul, pchan->eul);
+ VECCOPY(oldEul, pchan->eul);
rotOrder= pchan->rotmode;
useEulers = 1;
}
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
- /* specially calculate local matrix, since chan_mat is not valid
- * since it stores delta transform of pose_mat so that deforms work
- */
- pchan_to_mat4(pchan, mat);
+ if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
+ /* just like how the constraints do it! */
+ copy_m4_m4(mat, pchan->pose_mat);
+ constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
+ }
+ else {
+ /* specially calculate local matrix, since chan_mat is not valid
+ * since it stores delta transform of pose_mat so that deforms work
+ * so it cannot be used here for "transform" space
+ */
+ pchan_to_mat4(pchan, mat);
+ }
}
- else
+ else {
+ /* worldspace matrix */
mul_m4_m4m4(mat, pchan->pose_mat, ob->obmat);
+ }
}
else {
/* object */
if (ob->rotmode > 0) {
- VECCOPY(eul, ob->rot);
+ VECCOPY(oldEul, ob->rot);
rotOrder= ob->rotmode;
useEulers = 1;
}
- if (dtar->flag & DTAR_FLAG_LOCALSPACE)
- object_to_mat4(ob, mat);
- else
+ if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
+ if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
+ /* just like how the constraints do it! */
+ copy_m4_m4(mat, ob->obmat);
+ constraint_mat_convertspace(ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL);
+ }
+ else {
+ /* transforms to matrix */
+ object_to_mat4(ob, mat);
+ }
+ }
+ else {
+ /* worldspace matrix - just the good-old one */
copy_m4_m4(mat, ob->obmat);
+ }
}
/* check which transform */
@@ -1255,9 +1283,21 @@ static float dvar_eval_transChan (ChannelDriver *driver, DriverVar *dvar)
return scale[dtar->transChan - DTAR_TRANSCHAN_SCALEX];
}
else if (dtar->transChan >= DTAR_TRANSCHAN_ROTX) {
- /* extract euler rotation (if needed), and choose the right axis */
- if ((dtar->flag & DTAR_FLAG_LOCALSPACE)==0 || (useEulers == 0))
- mat4_to_eulO(eul, rotOrder, mat);
+ /* extract rotation as eulers (if needed)
+ * - definitely if rotation order isn't eulers already
+ * - if eulers, then we have 2 options:
+ * a) decompose transform matrix as required, then try to make eulers from
+ * there compatible with original values
+ * b) [NOT USED] directly use the original values (no decomposition)
+ * - only an option for "transform space", if quality is really bad with a)
+ */
+ float eul[3];
+
+ mat4_to_eulO(eul, rotOrder, mat);
+
+ if (useEulers) {
+ compatible_eul(eul, oldEul);
+ }
return eul[dtar->transChan - DTAR_TRANSCHAN_ROTX];
}