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:
authorMartin Poirier <theeth@yahoo.com>2006-12-03 21:38:51 +0300
committerMartin Poirier <theeth@yahoo.com>2006-12-03 21:38:51 +0300
commit4a2eceff20c0dc3d77de2a20a5fc0c15296ef453 (patch)
tree1ddce4ca9c08adaf20a7696ef242ee9b84dafbd2
parent953cd28b677590f30f1ae42e7210639f2cd4b6bc (diff)
=== [ #5094 ] TrackTo Constraint with an animatable "up" direction ===
Patch by Matthew Plough: This adds an option to the Track To constraint to use the target's Z axis for Up axis reference instead of the global Z axis. Off by default for backward compat.
-rw-r--r--source/blender/blenkernel/intern/constraint.c92
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h5
-rw-r--r--source/blender/src/buttons_object.c6
3 files changed, 101 insertions, 2 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index d471e9c7539..5d65585f40e 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -886,6 +886,93 @@ static void constraint_target_to_mat4 (Object *ob, const char *substring, float
}
}
+
+/* stupid little cross product function, 0:x, 1:y, 2:z axes */
+static int basis_cross(int n, int m)
+{
+ if(n-m == 1) return 1;
+ if(n-m == -1) return -1;
+ if(n-m == 2) return -1;
+ if(n-m == -2) return 1;
+ else return 0;
+}
+
+static void vectomat(float *vec, float *target_up, short axis, short upflag, short flags, float m[][3])
+{
+ float n[3];
+ float u[3]; /* vector specifying the up axis */
+ float proj[3];
+ float right[3];
+ float sign = 1;
+ float neg = -1;
+ int back_index, up_index, right_index;
+
+ VecCopyf(n, vec);
+ if(Normalise(n) == 0.0) {
+ n[0] = 0.0;
+ n[1] = 0.0;
+ n[2] = 1.0;
+ }
+ if(axis > 2) axis -= 3;
+ else VecMulf(n,-1);
+
+ /* n specifies the transformation of the track axis */
+
+ if(flags & TARGET_Z_UP) {
+ /* target Z axis is the global up axis */
+ u[0] = target_up[0];
+ u[1] = target_up[1];
+ u[2] = target_up[2];
+ }
+ else {
+ /* world Z axis is the global up axis */
+ u[0] = 0;
+ u[1] = 0;
+ u[2] = 1;
+ }
+
+ /* project the up vector onto the plane specified by n */
+ Projf(proj, u, n); /* first u onto n... */
+ VecSubf(proj, u, proj); /* then onto the plane */
+ /* proj specifies the transformation of the up axis */
+
+ if(Normalise(proj) == 0.0) { /* degenerate projection */
+ proj[0] = 0.0;
+ proj[1] = 1.0;
+ proj[2] = 0.0;
+ }
+
+ /* normalised cross product of n and proj specifies transformation of the right axis */
+ Crossf(right, proj, n);
+ Normalise(right);
+
+ if(axis != upflag) {
+ right_index = 3 - axis - upflag;
+ neg = (float) basis_cross(axis, upflag);
+
+ /* account for up direction, track direction */
+ m[right_index][0] = neg * right[0];
+ m[right_index][1] = neg * right[1];
+ m[right_index][2] = neg * right[2];
+
+ m[upflag][0] = proj[0];
+ m[upflag][1] = proj[1];
+ m[upflag][2] = proj[2];
+
+ m[axis][0] = n[0];
+ m[axis][1] = n[1];
+ m[axis][2] = n[2];
+ }
+
+ else {
+ m[0][0]= m[1][1]= m[2][2]= 1.0;
+ m[0][1]= m[0][2]= m[0][3]= 0.0;
+ m[1][0]= m[1][2]= m[1][3]= 0.0;
+ m[2][0]= m[2][1]= m[2][3]= 0.0;
+ }
+}
+
+
/* called during solve_constraints */
/* also for make_parent, to find correct inverse of "follow path" */
/* warning, ownerdata is void... is not Bone anymore, but PoseChannel or Object */
@@ -1371,8 +1458,9 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype,
VecSubf(vec, ob->obmat[3], targetmat[3]);
- quat= vectoquat(vec, (short)data->reserved1, (short)data->reserved2);
- QuatToMat3(quat, totmat);
+ vectomat(vec, targetmat[2],
+ (short)data->reserved1, (short)data->reserved2,
+ data->flags, totmat);
Mat4CpyMat4(tmat, ob->obmat);
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index ccc5f0c48e4..37aa3938ab2 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -77,6 +77,8 @@ typedef struct bTrackToConstraint{
Object *tar;
int reserved1; /* I'll be using reserved1 and reserved2 as Track and Up flags, not sure if that's what they were intented for anyway. Not sure either if it would create backward incompatibility if I were to rename them. - theeth*/
int reserved2;
+ int flags;
+ int pad;
char subtarget[32];
} bTrackToConstraint;
@@ -282,6 +284,9 @@ typedef struct bRigidBodyJointConstraint{
#define TRACK_nY 0x04
#define TRACK_nZ 0x05
+/* bTrackToConstraint->flags */
+#define TARGET_Z_UP 0x01
+
#define VOLUME_XZ 0x00
#define VOLUME_X 0x01
#define VOLUME_Z 0x02
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index 5f974b2d400..b963d440596 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -817,6 +817,12 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Align:", *xco+5, *yco-42, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ uiDefButBitI(block, TOG, 1, B_CONSTRAINT_TEST, "TargetZ", *xco+60, *yco-42, 50, 18, &data->flags, 0, 1, 0, 0, "Target Z axis, not world Z axis, will constrain up direction");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "To:", *xco+12, *yco-64, 25, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X", *xco+39, *yco-64,17,18, &data->reserved1, 12.0, 0.0, 0, 0, "The axis that points to the target object");