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
path: root/source
diff options
context:
space:
mode:
authorMartin Poirier <theeth@yahoo.com>2003-10-21 17:22:07 +0400
committerMartin Poirier <theeth@yahoo.com>2003-10-21 17:22:07 +0400
commit4efdabfbbc3f4f79328241e8b59002d869ae247a (patch)
tree5d3dae23f261a779e552520c4224a147090dabe4 /source
parent2da9cb5db284e16d95ff7e65dda9174c6b668950 (diff)
Constraint stuff from tuhopuu including (but probably not limited too):
Axis options for TrackTo LockTrack FollowPath Auto creation of TrackTo constraint from Ctrl-T (old track still an option) Auto creation of FollowPath when parenting to path (Normal parent still an option) Backward compatibility stuff to convert the per object axis settings to per constraint when a Track constraint is present. Function to convert old track to constraint (commented out) Revamped the constraints interface with Matt's work from tuhopuu and the stuff we were discussing earlier. -------------------- For coders: unique_constraint_name and *new_constraint_data moved to the kernel (constraint.c) new Projf function in arithb gives the projection of a vector on another vector add_new_constraint now takes a constraint type (int) parameter add_constraint_to_object(bConstraint *con, Object *ob) to link a constraint to an object add_constraint_to_client(bConstraint *con) to link constraint to current client (object or bone) add_influence_key_to_constraint (bConstraint *con) to (eventually) add a keyframe to the influence IPO of a constraint
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_constraint.h2
-rw-r--r--source/blender/blenkernel/intern/constraint.c558
-rw-r--r--source/blender/blenlib/BLI_arithb.h5
-rw-r--r--source/blender/blenlib/intern/arithb.c11
-rw-r--r--source/blender/blenloader/intern/readfile.c105
-rw-r--r--source/blender/blenloader/intern/writefile.c6
-rw-r--r--source/blender/include/BIF_editconstraint.h7
-rw-r--r--source/blender/include/butspace.h11
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h33
-rw-r--r--source/blender/src/buttons_object.c518
-rw-r--r--source/blender/src/editconstraint.c210
-rw-r--r--source/blender/src/editobject.c100
12 files changed, 1268 insertions, 298 deletions
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index 8da92f85c89..0a878d93ebe 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -41,6 +41,8 @@ struct bAction;
struct bArmature;
/* Function prototypes */
+void unique_constraint_name (struct bConstraint *con, struct ListBase *list);
+void *new_constraint_data (short type);
void evaluate_constraint (struct bConstraint *constraint, struct Object *ob, short ownertype, void *ownerdata, float targetmat[][4]);
void free_constraints (struct ListBase *conlist);
void copy_constraints (struct ListBase *dst, struct ListBase *src);
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index d4c535004b6..7d591ad234f 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -47,6 +47,7 @@
#include "BKE_utildefines.h"
#include "BKE_action.h"
+#include "BKE_anim.h" // for the curve calculation part
#include "BKE_armature.h"
#include "BKE_blender.h"
#include "BKE_constraint.h"
@@ -69,6 +70,141 @@ static void constraint_target_to_mat4 (Object *ob, const char *substring, float
/* Functions */
+void unique_constraint_name (bConstraint *con, ListBase *list){
+ char tempname[64];
+ int number;
+ char *dot;
+ int exists = 0;
+ bConstraint *curcon;
+
+ /* See if we even need to do this */
+ for (curcon = list->first; curcon; curcon=curcon->next){
+ if (curcon!=con){
+ if (!strcmp(curcon->name, con->name)){
+ exists = 1;
+ break;
+ }
+ }
+ }
+
+ if (!exists)
+ return;
+
+ /* Strip off the suffix */
+ dot=strchr(con->name, '.');
+ if (dot)
+ *dot=0;
+
+ for (number = 1; number <=999; number++){
+ sprintf (tempname, "%s.%03d", con->name, number);
+
+ exists = 0;
+ for (curcon=list->first; curcon; curcon=curcon->next){
+ if (con!=curcon){
+ if (!strcmp (curcon->name, tempname)){
+ exists = 1;
+ break;
+ }
+ }
+ }
+ if (!exists){
+ strcpy (con->name, tempname);
+ return;
+ }
+ }
+}
+
+void *new_constraint_data (short type)
+{
+ void *result;
+
+ switch (type){
+ case CONSTRAINT_TYPE_KINEMATIC:
+ {
+ bKinematicConstraint *data;
+ data = MEM_callocN(sizeof(bKinematicConstraint), "kinematicConstraint");
+
+ data->tolerance = (float)0.001;
+ data->iterations = 500;
+
+ result = data;
+ }
+ break;
+ case CONSTRAINT_TYPE_NULL:
+ {
+ result = NULL;
+ }
+ break;
+ case CONSTRAINT_TYPE_TRACKTO:
+ {
+ bTrackToConstraint *data;
+ data = MEM_callocN(sizeof(bTrackToConstraint), "tracktoConstraint");
+
+
+ data->reserved1 = TRACK_Y;
+ data->reserved2 = UP_Z;
+
+ result = data;
+
+ }
+ break;
+ case CONSTRAINT_TYPE_ROTLIKE:
+ {
+ bRotateLikeConstraint *data;
+ data = MEM_callocN(sizeof(bRotateLikeConstraint), "rotlikeConstraint");
+
+ result = data;
+ }
+ break;
+ case CONSTRAINT_TYPE_LOCLIKE:
+ {
+ bLocateLikeConstraint *data;
+ data = MEM_callocN(sizeof(bLocateLikeConstraint), "loclikeConstraint");
+
+ data->flag |= LOCLIKE_X|LOCLIKE_Y|LOCLIKE_Z;
+ result = data;
+ }
+ break;
+ case CONSTRAINT_TYPE_ACTION:
+ {
+ bActionConstraint *data;
+ data = MEM_callocN(sizeof(bActionConstraint), "actionConstraint");
+
+ result = data;
+ }
+ break;
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ {
+ bLockTrackConstraint *data;
+ data = MEM_callocN(sizeof(bLockTrackConstraint), "locktrackConstraint");
+
+ data->trackflag = TRACK_Y;
+ data->lockflag = LOCK_Z;
+
+ result = data;
+ }
+ break;
+ case CONSTRAINT_TYPE_FOLLOWPATH:
+ {
+ bFollowPathConstraint *data;
+ data = MEM_callocN(sizeof(bFollowPathConstraint), "followpathConstraint");
+
+ data->trackflag = TRACK_Y;
+ data->upflag = UP_Z;
+ data->offset = 0;
+ data->followflag = 0;
+
+ result = data;
+ }
+ break;
+ default:
+ result = NULL;
+ break;
+ }
+
+ return result;
+}
+
bConstraintChannel *find_constraint_channel (ListBase *list, const char *name){
bConstraintChannel *chan;
@@ -361,6 +497,77 @@ short get_constraint_target (bConstraint *con, short ownertype, void* ownerdata,
Mat4One (mat);
}
break;
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ {
+ bLockTrackConstraint *data;
+ data = (bLockTrackConstraint*)con->data;
+
+ if (data->tar){
+ constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime);
+ valid=1;
+ }
+ else
+ Mat4One (mat);
+ }
+ break;
+ case CONSTRAINT_TYPE_FOLLOWPATH:
+ {
+ bFollowPathConstraint *data;
+ data = (bFollowPathConstraint*)con->data;
+
+ if (data->tar){
+ Curve *cu;
+ float q[4], vec[4], dir[3], *quat, x1, totmat[4][4];
+ float curvetime;
+
+ Mat4One (totmat);
+
+ cu= data->tar->data;
+
+ if(data->followflag) {
+ if(!(cu->flag & CU_FOLLOW)) cu->flag += CU_FOLLOW;
+ }
+ else {
+ if(cu->flag & CU_FOLLOW) cu->flag -= CU_FOLLOW;
+ }
+
+ if(!(cu->flag & CU_PATH)) cu->flag += CU_PATH;
+
+ if(cu->path==0 || cu->path->data==0) calc_curvepath(data->tar);
+
+ curvetime = ctime - data->offset;
+
+ if(calc_ipo_spec(cu->ipo, CU_SPEED, &curvetime)==0) {
+ ctime /= cu->pathlen;
+ CLAMP(ctime, 0.0, 1.0);
+ }
+
+ if(where_on_path(data->tar, curvetime, vec, dir) ) {
+
+ if(data->followflag){
+ quat= vectoquat(dir, (short) data->trackflag, (short) data->upflag);
+
+ Normalise(dir);
+ q[0]= (float)cos(0.5*vec[3]);
+ x1= (float)sin(0.5*vec[3]);
+ q[1]= -x1*dir[0];
+ q[2]= -x1*dir[1];
+ q[3]= -x1*dir[2];
+ QuatMul(quat, q, quat);
+
+
+ QuatToMat4(quat, totmat);
+ }
+ VECCOPY(totmat[3], vec);
+
+ Mat4MulSerie(mat, data->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL);
+ }
+ valid=1;
+ }
+ else
+ Mat4One (mat);
+ }
+ break;
default:
Mat4One(mat);
break;
@@ -594,6 +801,10 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype,
{
bTrackToConstraint *data;
float size[3];
+ float *quat;
+ float vec[3];
+ float totmat[3][3];
+ float tmat[4][4];
data=(bTrackToConstraint*)constraint->data;
@@ -614,7 +825,16 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype,
ob->obmat[2][1]=0;
ob->obmat[2][2]=ob->size[2];
- solve_tracking(ob, targetmat);
+
+ VecSubf(vec, ob->obmat[3], targetmat[3]);
+ quat= vectoquat(vec, (short)data->reserved1, (short)data->reserved2);
+ QuatToMat3(quat, totmat);
+
+ Mat4CpyMat4(tmat, ob->obmat);
+
+ Mat4MulMat34(ob->obmat, totmat, tmat);
+
+
}
}
break;
@@ -685,7 +905,343 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype,
}
}
break;
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ {
+ bLockTrackConstraint *data;
+ float size[3];
+ float vec[3],vec2[3];
+ float totmat[3][3];
+ float tmpmat[3][3];
+ float invmat[3][3];
+ float tmat[4][4];
+ float mdet;
+
+
+ data=(bLockTrackConstraint*)constraint->data;
+
+
+ if (data->tar){
+
+ Mat4ToSize (ob->obmat, size);
+
+ Mat4CpyMat4 (M_oldmat, ob->obmat);
+
+ /* Vector object -> target */
+ VecSubf(vec, targetmat[3], ob->obmat[3]);
+ switch (data->lockflag){
+ case LOCK_X: /* LOCK X */
+ {
+ switch (data->trackflag){
+ case TRACK_Y: /* LOCK X TRACK Y */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, ob->obmat[0]);
+ VecSubf(totmat[1], vec, vec2);
+ Normalise(totmat[1]);
+
+ /* the x axis is fixed*/
+ totmat[0][0] = ob->obmat[0][0];
+ totmat[0][1] = ob->obmat[0][1];
+ totmat[0][2] = ob->obmat[0][2];
+ Normalise(totmat[0]);
+
+ /* the z axis gets mapped onto
+ a third orthogonal vector */
+ Crossf(totmat[2], totmat[0], totmat[1]);
+ }
+ break;
+ case TRACK_Z: /* LOCK X TRACK Z */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, ob->obmat[0]);
+ VecSubf(totmat[2], vec, vec2);
+ Normalise(totmat[2]);
+
+ /* the x axis is fixed*/
+ totmat[0][0] = ob->obmat[0][0];
+ totmat[0][1] = ob->obmat[0][1];
+ totmat[0][2] = ob->obmat[0][2];
+ Normalise(totmat[0]);
+
+ /* the z axis gets mapped onto
+ a third orthogonal vector */
+ Crossf(totmat[1], totmat[2], totmat[0]);
+ }
+ break;
+ case TRACK_nY: /* LOCK X TRACK -Y */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, ob->obmat[0]);
+ VecSubf(totmat[1], vec, vec2);
+ Normalise(totmat[1]);
+ VecMulf(totmat[1],-1);
+
+ /* the x axis is fixed*/
+ totmat[0][0] = ob->obmat[0][0];
+ totmat[0][1] = ob->obmat[0][1];
+ totmat[0][2] = ob->obmat[0][2];
+ Normalise(totmat[0]);
+
+ /* the z axis gets mapped onto
+ a third orthogonal vector */
+ Crossf(totmat[2], totmat[0], totmat[1]);
+ }
+ break;
+ case TRACK_nZ: /* LOCK X TRACK -Z */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, ob->obmat[0]);
+ VecSubf(totmat[2], vec, vec2);
+ Normalise(totmat[2]);
+ VecMulf(totmat[2],-1);
+
+ /* the x axis is fixed*/
+ totmat[0][0] = ob->obmat[0][0];
+ totmat[0][1] = ob->obmat[0][1];
+ totmat[0][2] = ob->obmat[0][2];
+ Normalise(totmat[0]);
+
+ /* the z axis gets mapped onto
+ a third orthogonal vector */
+ Crossf(totmat[1], totmat[2], totmat[0]);
+ }
+ break;
+ default:
+ {
+ totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
+ totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
+ totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
+ }
+ break;
+ }
+ }
+ break;
+ case LOCK_Y: /* LOCK Y */
+ {
+ switch (data->trackflag){
+ case TRACK_X: /* LOCK Y TRACK X */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, ob->obmat[1]);
+ VecSubf(totmat[0], vec, vec2);
+ Normalise(totmat[0]);
+
+ /* the y axis is fixed*/
+ totmat[1][0] = ob->obmat[1][0];
+ totmat[1][1] = ob->obmat[1][1];
+ totmat[1][2] = ob->obmat[1][2];
+ Normalise(totmat[1]);
+
+ /* the z axis gets mapped onto
+ a third orthogonal vector */
+ Crossf(totmat[2], totmat[0], totmat[1]);
+ }
+ break;
+ case TRACK_Y: /* LOCK Y TRACK Z */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, ob->obmat[1]);
+ VecSubf(totmat[2], vec, vec2);
+ Normalise(totmat[2]);
+
+ /* the y axis is fixed*/
+ totmat[1][0] = ob->obmat[1][0];
+ totmat[1][1] = ob->obmat[1][1];
+ totmat[1][2] = ob->obmat[1][2];
+ Normalise(totmat[1]);
+
+ /* the z axis gets mapped onto
+ a third orthogonal vector */
+ Crossf(totmat[0], totmat[1], totmat[2]);
+ }
+ break;
+ case TRACK_nX: /* LOCK Y TRACK -X */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, ob->obmat[1]);
+ VecSubf(totmat[0], vec, vec2);
+ Normalise(totmat[0]);
+ VecMulf(totmat[0],-1);
+
+ /* the y axis is fixed*/
+ totmat[1][0] = ob->obmat[1][0];
+ totmat[1][1] = ob->obmat[1][1];
+ totmat[1][2] = ob->obmat[1][2];
+ Normalise(totmat[1]);
+
+ /* the z axis gets mapped onto
+ a third orthogonal vector */
+ Crossf(totmat[2], totmat[0], totmat[1]);
+ }
+ break;
+ case TRACK_nZ: /* LOCK Y TRACK -Z */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, ob->obmat[1]);
+ VecSubf(totmat[2], vec, vec2);
+ Normalise(totmat[2]);
+ VecMulf(totmat[2],-1);
+
+ /* the y axis is fixed*/
+ totmat[1][0] = ob->obmat[1][0];
+ totmat[1][1] = ob->obmat[1][1];
+ totmat[1][2] = ob->obmat[1][2];
+ Normalise(totmat[1]);
+
+ /* the z axis gets mapped onto
+ a third orthogonal vector */
+ Crossf(totmat[0], totmat[1], totmat[2]);
+ }
+ break;
+ default:
+ {
+ totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
+ totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
+ totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
+ }
+ break;
+ }
+ }
+ break;
+ case LOCK_Z: /* LOCK Z */
+ {
+ switch (data->trackflag){
+ case TRACK_X: /* LOCK Z TRACK X */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, ob->obmat[2]);
+ VecSubf(totmat[0], vec, vec2);
+ Normalise(totmat[0]);
+
+ /* the z axis is fixed*/
+ totmat[2][0] = ob->obmat[2][0];
+ totmat[2][1] = ob->obmat[2][1];
+ totmat[2][2] = ob->obmat[2][2];
+ Normalise(totmat[2]);
+
+ /* the x axis gets mapped onto
+ a third orthogonal vector */
+ Crossf(totmat[1], totmat[2], totmat[0]);
+ }
+ break;
+ case TRACK_Y: /* LOCK Z TRACK Y */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, ob->obmat[2]);
+ VecSubf(totmat[1], vec, vec2);
+ Normalise(totmat[1]);
+
+ /* the z axis is fixed*/
+ totmat[2][0] = ob->obmat[2][0];
+ totmat[2][1] = ob->obmat[2][1];
+ totmat[2][2] = ob->obmat[2][2];
+ Normalise(totmat[2]);
+
+ /* the x axis gets mapped onto
+ a third orthogonal vector */
+ Crossf(totmat[0], totmat[1], totmat[2]);
+ }
+ break;
+ case TRACK_nX: /* LOCK Z TRACK -X */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, ob->obmat[2]);
+ VecSubf(totmat[0], vec, vec2);
+ Normalise(totmat[0]);
+ VecMulf(totmat[0],-1);
+
+ /* the z axis is fixed*/
+ totmat[2][0] = ob->obmat[2][0];
+ totmat[2][1] = ob->obmat[2][1];
+ totmat[2][2] = ob->obmat[2][2];
+ Normalise(totmat[2]);
+
+ /* the x axis gets mapped onto
+ a third orthogonal vector */
+ Crossf(totmat[1], totmat[2], totmat[0]);
+ }
+ break;
+ case TRACK_nY: /* LOCK Z TRACK -Y */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, ob->obmat[2]);
+ VecSubf(totmat[1], vec, vec2);
+ Normalise(totmat[1]);
+ VecMulf(totmat[1],-1);
+
+ /* the z axis is fixed*/
+ totmat[2][0] = ob->obmat[2][0];
+ totmat[2][1] = ob->obmat[2][1];
+ totmat[2][2] = ob->obmat[2][2];
+ Normalise(totmat[2]);
+
+ /* the x axis gets mapped onto
+ a third orthogonal vector */
+ Crossf(totmat[0], totmat[1], totmat[2]);
+ }
+ break;
+ default:
+ {
+ totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
+ totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
+ totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
+ }
+ break;
+ }
+ }
+ break;
+ default:
+ {
+ totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
+ totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
+ totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
+ }
+ break;
+ }
+ /* Block to keep matrix heading */
+ tmpmat[0][0] = ob->obmat[0][0];tmpmat[0][1] = ob->obmat[0][1];tmpmat[0][2] = ob->obmat[0][2];
+ tmpmat[1][0] = ob->obmat[1][0];tmpmat[1][1] = ob->obmat[1][1];tmpmat[1][2] = ob->obmat[1][2];
+ tmpmat[2][0] = ob->obmat[2][0];tmpmat[2][1] = ob->obmat[2][1];tmpmat[2][2] = ob->obmat[2][2];
+ Normalise(tmpmat[0]);
+ Normalise(tmpmat[1]);
+ Normalise(tmpmat[2]);
+ Mat3Inv(invmat,tmpmat);
+ Mat3MulMat3(tmpmat,totmat,invmat);
+ totmat[0][0] = tmpmat[0][0];totmat[0][1] = tmpmat[0][1];totmat[0][2] = tmpmat[0][2];
+ totmat[1][0] = tmpmat[1][0];totmat[1][1] = tmpmat[1][1];totmat[1][2] = tmpmat[1][2];
+ totmat[2][0] = tmpmat[2][0];totmat[2][1] = tmpmat[2][1];totmat[2][2] = tmpmat[2][2];
+
+ Mat4CpyMat4(tmat, ob->obmat);
+
+ mdet = Det3x3( totmat[0][0],totmat[0][1],totmat[0][2],
+ totmat[1][0],totmat[1][1],totmat[1][2],
+ totmat[2][0],totmat[2][1],totmat[2][2]);
+ if (mdet==0)
+ {
+ totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
+ totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
+ totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
+ }
+
+ /* apply out transformaton to the object */
+ Mat4MulMat34(ob->obmat, totmat, tmat);
+ }
+ }
+ break;
case CONSTRAINT_TYPE_FOLLOWPATH:
+ {
+ bFollowPathConstraint *data;
+ float obmat[4][4];
+
+ data=(bFollowPathConstraint*)constraint->data;
+
+ if (data->tar) {
+
+ object_to_mat4(ob, obmat);
+
+ Mat4MulSerie(ob->obmat, targetmat, obmat, NULL, NULL, NULL, NULL, NULL, NULL);
+ }
+ }
break;
default:
printf ("Error: Unknown constraint type\n");
diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h
index 497ff98b53a..eeb64d789ca 100644
--- a/source/blender/blenlib/BLI_arithb.h
+++ b/source/blender/blenlib/BLI_arithb.h
@@ -116,6 +116,11 @@ Crossf(
float *c, float *a, float *b
);
+ void
+Projf(
+ float *c, const float *v1, const float *v2
+);
+
/**
* Euler conversion routines
*/
diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c
index fa13f8223a8..715917d047f 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -119,6 +119,17 @@ float Inpf( float *v1, float *v2)
return v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2];
}
+/* Project v1 on v2 */
+void Projf(float *c, const float *v1, const float *v2)
+{
+ float mul;
+ mul = Inpf(v1, v2) / Inpf(v2, v2);
+
+ c[0] = mul * v2[0];
+ c[1] = mul * v2[1];
+ c[2] = mul * v2[2];
+}
+
void Mat3Transp(float mat[][3])
{
float t;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 358c99df3de..a7acb42fdef 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1227,8 +1227,6 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
data->tar = newlibadr(fd, id->lib, data->tar);
}
break;
- case CONSTRAINT_TYPE_NULL:
- break;
case CONSTRAINT_TYPE_TRACKTO:
{
bTrackToConstraint *data;
@@ -1236,7 +1234,22 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
data->tar = newlibadr(fd, id->lib, data->tar);
}
break;
-
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ {
+ bLockTrackConstraint *data;
+ data= ((bLockTrackConstraint*)con->data);
+ data->tar = newlibadr(fd, id->lib, data->tar);
+ };
+ break;
+ case CONSTRAINT_TYPE_FOLLOWPATH:
+ {
+ bFollowPathConstraint *data;
+ data= ((bFollowPathConstraint*)con->data);
+ data->tar = newlibadr(fd, id->lib, data->tar);
+ };
+ break;
+ case CONSTRAINT_TYPE_NULL:
+ break;
}
}
}
@@ -3746,6 +3759,80 @@ static void do_versions(Main *main)
if(main->versionfile <= 228) {
Scene *sce;
bScreen *sc;
+ Object *ob;
+
+
+ /* As of now, this insures that the transition from the old Track system
+ to the new full constraint Track is painless for everyone.*/
+ ob = main->object.first;
+
+ while (ob) {
+ ListBase *list;
+ list = &ob->constraints;
+
+ /* check for already existing TrackTo constraint
+ set their track and up flag correctly */
+
+ if (list){
+ bConstraint *curcon;
+ for (curcon = list->first; curcon; curcon=curcon->next){
+ if (curcon->type == CONSTRAINT_TYPE_TRACKTO){
+ bTrackToConstraint *data = curcon->data;
+ data->reserved1 = ob->trackflag;
+ data->reserved2 = ob->upflag;
+ }
+ }
+ }
+
+ if (ob->type == OB_ARMATURE) {
+ if (ob->pose){
+ bConstraint *curcon;
+ bPoseChannel *pchan;
+ for (pchan = ob->pose->chanbase.first;
+ pchan; pchan=pchan->next){
+ for (curcon = pchan->constraints.first;
+ curcon; curcon=curcon->next){
+ if (curcon->type == CONSTRAINT_TYPE_TRACKTO){
+ bTrackToConstraint *data = curcon->data;
+ data->reserved1 = ob->trackflag;
+ data->reserved2 = ob->upflag;
+ }
+ }
+ }
+ }
+ }
+
+ /* Change Ob->Track in real TrackTo constraint
+
+ NOT SURE IF PEOPLE WANT THIS SO I DISABLED IT
+
+ if (ob->track){
+ bConstraint *con;
+ bTrackToConstraint *data;
+
+ list = &ob->constraints;
+ if (list)
+ {
+ con = MEM_callocN(sizeof(bConstraint), "constraint");
+ strcpy (con->name, "AutoTrack");
+ unique_constraint_name(con, list);
+ con->flag |= CONSTRAINT_EXPAND;
+ con->enforce=1.0F;
+ con->type = CONSTRAINT_TYPE_TRACKTO;
+ data = (bTrackToConstraint *)
+ new_constraint_data(CONSTRAINT_TYPE_TRACKTO);
+
+ data->tar = ob->track;
+ data->reserved1 = ob->trackflag;
+ data->reserved2 = ob->upflag;
+ con->data= (void*) data;
+ BLI_addtail(list, con);
+ }
+ ob->track = 0;
+ }*/
+
+ ob = ob->id.next;
+ }
for (sce= main->scene.first; sce; sce= sce->id.next) {
sce->r.mode |= R_ENVMAP;
@@ -4189,6 +4276,18 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
expand_doit(fd, mainvar, data->tar);
break;
}
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ {
+ bLockTrackConstraint *data = (bLockTrackConstraint*)curcon->data;
+ expand_doit(fd, mainvar, data->tar);
+ break;
+ }
+ case CONSTRAINT_TYPE_FOLLOWPATH:
+ {
+ bFollowPathConstraint *data = (bFollowPathConstraint*)curcon->data;
+ expand_doit(fd, mainvar, data->tar);
+ break;
+ }
case CONSTRAINT_TYPE_NULL:
break;
default:
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 546ff3b60e6..4d11e6d7041 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -691,6 +691,12 @@ static void write_constraints(WriteData *wd, ListBase *conlist)
case CONSTRAINT_TYPE_ACTION:
writestruct(wd, DATA, "bActionConstraint", 1, con->data);
break;
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ writestruct(wd, DATA, "bLockTrackConstraint", 1, con->data);
+ break;
+ case CONSTRAINT_TYPE_FOLLOWPATH:
+ writestruct(wd, DATA, "bFollowPathConstraint", 1, con->data);
+ break;
default:
break;
}
diff --git a/source/blender/include/BIF_editconstraint.h b/source/blender/include/BIF_editconstraint.h
index 5d6d38fd529..f28b07797f0 100644
--- a/source/blender/include/BIF_editconstraint.h
+++ b/source/blender/include/BIF_editconstraint.h
@@ -48,13 +48,14 @@ typedef struct ConstraintElement{
} ConstraintElement;
struct bConstraintChannel *add_new_constraint_channel(const char *name);
-struct bConstraint * add_new_constraint(void);
+struct bConstraint * add_new_constraint(int type);
+void add_influence_key_to_constraint (struct bConstraint *con);
+void add_constraint_to_object(struct bConstraint *con, struct Object *ob);
+void add_constraint_to_client(struct bConstraint *con);
struct ListBase *get_constraint_client_channels (int forcevalid);
struct ListBase *get_constraint_client(char *name, short *clienttype, void** clientdata);
int test_constraints (struct Object *owner, const char *substring, int disable);
void test_scene_constraints (void);
-void unique_constraint_name (struct bConstraint *con, struct ListBase *list);
-void *new_constraint_data (short type);
/* void unique_constraint_name (struct bConstraint *con, struct ListBase *list); */
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index 7d708b36279..4b41667bc43 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -485,12 +485,19 @@ enum B_SOUND_BUTTONS {
#define B_CONSTRAINTBUTS 3300
enum {
B_CONSTRAINT_REDRAW = 3201,
- B_CONSTRAINT_ADD,
B_CONSTRAINT_DEL,
B_CONSTRAINT_TEST,
B_CONSTRAINT_CHANGETYPE,
B_CONSTRAINT_CHANGENAME,
- B_CONSTRAINT_CHANGETARGET
+ B_CONSTRAINT_CHANGETARGET,
+ B_CONSTRAINT_ADD_NULL,
+ B_CONSTRAINT_ADD_KINEMATIC,
+ B_CONSTRAINT_ADD_TRACKTO,
+ B_CONSTRAINT_ADD_ROTLIKE,
+ B_CONSTRAINT_ADD_LOCLIKE,
+ B_CONSTRAINT_ADD_ACTION,
+ B_CONSTRAINT_ADD_LOCKTRACK,
+ B_CONSTRAINT_ADD_FOLLOWPATH
};
/* *********************** */
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 02199b9aa01..7cd0272a8cb 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -109,9 +109,21 @@ typedef struct bActionConstraint{
char subtarget[32];
} bActionConstraint;
-/* Single-target object constraints */
+/* Locked Axis Tracking constraint */
+typedef struct bLockTrackConstraint{
+ Object *tar;
+ int trackflag;
+ int lockflag;
+ char subtarget[32];
+} bLockTrackConstraint;
+
+/* Follow Path constraints */
typedef struct bFollowPathConstraint{
Object *tar; /* Must be path object */
+ float offset; /* Offset in time on the path (in frame) */
+ int followflag;
+ int trackflag;
+ int upflag;
} bFollowPathConstraint;
/* Zero-target constraints */
@@ -126,7 +138,7 @@ typedef struct bRotationConstraint{
#define CONSTRAINT_TYPE_CHILDOF 1 /* Unimplemented */
#define CONSTRAINT_TYPE_TRACKTO 2
#define CONSTRAINT_TYPE_KINEMATIC 3
-#define CONSTRAINT_TYPE_FOLLOWPATH 4 /* Unimplemented */
+#define CONSTRAINT_TYPE_FOLLOWPATH 4
#define CONSTRAINT_TYPE_ROTLIMIT 5 /* Unimplemented */
#define CONSTRAINT_TYPE_LOCLIMIT 6 /* Unimplemented */
#define CONSTRAINT_TYPE_SIZELIMIT 7 /* Unimplemented */
@@ -135,6 +147,7 @@ typedef struct bRotationConstraint{
#define CONSTRAINT_TYPE_SIZELIKE 10 /* Unimplemented */
#define CONSTRAINT_TYPE_PYTHON 11 /* Unimplemented */
#define CONSTRAINT_TYPE_ACTION 12
+#define CONSTRAINT_TYPE_LOCKTRACK 13 /* New Tracking constraint that locks an axis in place - theeth */
/* bConstraint.flag */
#define CONSTRAINT_EXPAND 0x00000001
@@ -154,5 +167,21 @@ typedef struct bRotationConstraint{
#define LOCLIKE_Y 0x00000002
#define LOCLIKE_Z 0x00000004
+/* Tracking flags */
+#define LOCK_X 0x00000000
+#define LOCK_Y 0x00000001
+#define LOCK_Z 0x00000002
+
+#define UP_X 0x00000000
+#define UP_Y 0x00000001
+#define UP_Z 0x00000002
+
+#define TRACK_X 0x00000000
+#define TRACK_Y 0x00000001
+#define TRACK_Z 0x00000002
+#define TRACK_nX 0x00000003
+#define TRACK_nY 0x00000004
+#define TRACK_nZ 0x00000005
+
#endif
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index 637220c27e6..b88995ec8de 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -278,6 +278,12 @@ static void get_constraint_typestring (char *str, bConstraint *con)
case CONSTRAINT_TYPE_ACTION:
strcpy (str, "Action");
return;
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ strcpy (str, "Locked Track");
+ return;
+ case CONSTRAINT_TYPE_FOLLOWPATH:
+ strcpy (str, "Follow Path");
+ return;
default:
strcpy (str, "Unknown");
return;
@@ -299,6 +305,10 @@ static int get_constraint_col(bConstraint *con)
return TH_BUT_POPUP;
case CONSTRAINT_TYPE_ACTION:
return TH_BUT_ACTION;
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ return TH_BUT_SETTING;
+ case CONSTRAINT_TYPE_FOLLOWPATH:
+ return TH_BUT_SETTING2;
default:
return TH_REDALERT;
}
@@ -326,14 +336,22 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
if (con->flag & CONSTRAINT_EXPAND) {
- if (con->flag & CONSTRAINT_DISABLE)
+ if (con->flag & CONSTRAINT_DISABLE) {
+ BIF_ThemeColor(TH_REDALERT);
uiBlockSetCol(block, TH_REDALERT);
-
- if (type==TARGET_BONE)
+ }
+ else
+ BIF_ThemeColor(curCol);
+
+ /*if (type==TARGET_BONE)
but = uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Bone Constraint%t|Track To%x2|IK Solver%x3|Copy Rotation%x8|Copy Location%x9|Action%x12|Null%x0", *xco+20, *yco, 100, 20, &con->type, 0.0, 0.0, 0.0, 0.0, "Constraint type");
else
but = uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Object Constraint%t|Track To%x2|Copy Rotation%x8|Copy Location%x9|Null%x0", *xco+20, *yco, 100, 20, &con->type, 0.0, 0.0, 0.0, 0.0, "Constraint type");
+ */
+ glRects(*xco+34, *yco-12, *xco+138, *yco+5);
+ but = uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, *xco+20, *yco, 100, 20, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
uiButSetFunc(but, constraint_changed_func, con, NULL);
con->otype = con->type;
@@ -364,168 +382,276 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
uiDefIconButS(block, ICONTOG|BIT|CONSTRAINT_EXPAND_BIT, B_CONSTRAINT_REDRAW, ICON_RIGHTARROW, *xco+248, *yco, 20, 20, &con->flag, 0.0, 0.0, 0.0, 0.0, "Collapse");
- if (!(con->flag & CONSTRAINT_EXPAND)) {
- (*yco)-=21;
- return;
- }
- if (con->type!=CONSTRAINT_TYPE_NULL) {
- uiDefBut(block, NUMSLI|FLO, B_CONSTRAINT_REDRAW, "Influence:", *xco, *yco-20, 196, 20, &con->enforce, 0.0, 1.0, 0.0, 0.0, "Amount of influence this constraint will have on the final solution");
- but = uiDefBut(block, BUT, B_CONSTRAINT_REDRAW, "Edit Ipo", *xco+200, *yco-20, 64, 20, 0, 0.0, 1.0, 0.0, 0.0, "Show this constraint's ipo in the object's Ipo window");
- /* If this is on an object, add the constraint to the object */
- uiButSetFunc (but, activate_constraint_ipo_func, con, NULL);
- /* If this is on a bone, add the constraint to the action (if any) */
+ /* Draw constraint data*/
+ if (!(con->flag & CONSTRAINT_EXPAND)) {
(*yco)-=21;
}
+ else {
+ switch (con->type){
+ case CONSTRAINT_TYPE_ACTION:
+ {
+ bActionConstraint *data = con->data;
+ bArmature *arm;
+
+ height = 86;
+ BIF_ThemeColor(curCol);
+ glRects(*xco+40, *yco-height-16, *xco+width+50, *yco-14);
+ uiEmboss((float)*xco+40, (float)*yco-height-16, (float)*xco+width+50, (float)*yco-14, 1);
+
+ /* Draw target parameters */
+ uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object");
+
+ arm = get_armature(data->tar);
+ if (arm){
+ but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-40,96,18, &data->subtarget, 0, 24, 0, 0, "Bone");
+ }
+ else
+ strcpy (data->subtarget, "");
- /* Draw constraint data*/
-
- switch (con->type){
- case CONSTRAINT_TYPE_ACTION:
- {
- bActionConstraint *data = con->data;
- bArmature *arm;
-
- height = 86;
- BIF_ThemeColor(curCol);
- glRects(*xco+34, *yco-height-16, *xco+width+24, *yco-14);
- uiEmboss((float)*xco+34, (float)*yco-height-16, (float)*xco+width+24, (float)*yco-14, 1);
-
- /* Draw target parameters */
- uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object");
+ /* Draw action button */
+ uiDefIDPoinBut(block, test_actionpoin_but, B_CONSTRAINT_CHANGETARGET, "AC:", *xco+((width/2)-90), *yco-60, 75, 18, &data->act, "Action containing the keyed motion for this bone");
+ uiDefButI(block, MENU, B_CONSTRAINT_REDRAW, "Key on%t|X Rot%x0|Y Rot%x1|Z Rot%x2", *xco+((width/2)-90), *yco-80, 75, 18, &data->type, 0, 24, 0, 0, "Specify which transformation channel from the target is used to key the action");
- arm = get_armature(data->tar);
- if (arm){
- but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-40,96,18, &data->subtarget, 0, 24, 0, 0, "Bone");
+ uiDefButS(block, NUM, B_CONSTRAINT_CHANGETARGET, "Start:", *xco+((width/2)-15), *yco-60, 70, 18, &data->start, 1, 18000, 0.0, 0.0, "Starting frame of the keyed motion");
+ uiDefButS(block, NUM, B_CONSTRAINT_CHANGETARGET, "End:", *xco+((width/2)-15), *yco-80, 70, 18, &data->end, 1, 18000, 0.0, 0.0, "Ending frame of the keyed motion");
+
+ uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Min:", *xco+((width/2)+55), *yco-60, 80, 18, &data->min, -180, 180, 0, 0, "Minimum value for target channel range");
+ uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Max:", *xco+((width/2)+55), *yco-80, 80, 18, &data->max, -180, 180, 0, 0, "Maximum value for target channel range");
+
}
- else
- strcpy (data->subtarget, "");
-
- /* Draw action button */
- uiDefIDPoinBut(block, test_actionpoin_but, B_CONSTRAINT_CHANGETARGET, "AC:", *xco+((width/2)-120), *yco-60, 80, 18, &data->act, "Action containing the keyed motion for this bone");
-
- uiDefButS(block, NUM, B_CONSTRAINT_CHANGETARGET, "Start:", *xco+((width/2)-40), *yco-60, 80, 18, &data->start, 1, 18000, 0.0, 0.0, "Starting frame of the keyed motion");
- uiDefButS(block, NUM, B_CONSTRAINT_CHANGETARGET, "End:", *xco+((width/2)+40), *yco-60, 80, 18, &data->end, 1, 18000, 0.0, 0.0, "Ending frame of the keyed motion");
-
- /* Draw XYZ toggles */
- uiDefButI(block, MENU, B_CONSTRAINT_REDRAW, "Key on%t|X Rot%x0|Y Rot%x1|Z Rot%x2", *xco+((width/2)-120), *yco-80, 80, 18, &data->type, 0, 24, 0, 0, "Specify which transformation channel from the target is used to key the action");
- uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Min:", *xco+((width/2)-40), *yco-80, 80, 18, &data->min, -180, 180, 0, 0, "Minimum value for target channel range");
- uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Max:", *xco+((width/2)+40), *yco-80, 80, 18, &data->max, -180, 180, 0, 0, "Maximum value for target channel range");
-
- }
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- {
- bLocateLikeConstraint *data = con->data;
- bArmature *arm;
- height = 66;
- BIF_ThemeColor(curCol);
- glRects(*xco+34, *yco-height-16, *xco+width+24, *yco-14);
- uiEmboss((float)*xco+34, (float)*yco-height-16, (float)*xco+width+24, (float)*yco-14, 1);
+ break;
+ case CONSTRAINT_TYPE_LOCLIKE:
+ {
+ bLocateLikeConstraint *data = con->data;
+ bArmature *arm;
+ height = 66;
+ BIF_ThemeColor(curCol);
+ glRects(*xco+40, *yco-height-16, *xco+width+50, *yco-14);
+ uiEmboss((float)*xco+40, (float)*yco-height-16, (float)*xco+width+50, (float)*yco-14, 1);
+
+ /* Draw target parameters */
+ uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object");
+
+ arm = get_armature(data->tar);
+ if (arm){
+ but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-40,96,18, &data->subtarget, 0, 24, 0, 0, "Bone");
+ }
+ else
+ strcpy (data->subtarget, "");
- /* Draw target parameters */
- uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object");
+ /* Draw XYZ toggles */
+ but=uiDefButI(block, TOG|BIT|0, B_CONSTRAINT_TEST, "X", *xco+((width/2)-48), *yco-60, 32, 18, &data->flag, 0, 24, 0, 0, "Copy X component");
+ but=uiDefButI(block, TOG|BIT|1, B_CONSTRAINT_TEST, "Y", *xco+((width/2)-16), *yco-60, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Y component");
+ but=uiDefButI(block, TOG|BIT|2, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+16), *yco-60, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component");
+ }
+ break;
+ case CONSTRAINT_TYPE_ROTLIKE:
+ {
+ bRotateLikeConstraint *data = con->data;
+ bArmature *arm;
+ height = 46;
+ BIF_ThemeColor(curCol);
+ glRects(*xco+40, *yco-height-16, *xco+width+50, *yco-14);
+ uiEmboss((float)*xco+40, (float)*yco-height-16, (float)*xco+width+50, (float)*yco-14, 1);
+
+ uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object");
+
+ arm = get_armature(data->tar);
+ if (arm){
+ but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-40,96,18, &data->subtarget, 0, 24, 0, 0, "Bone");
+ }
+ else
+ strcpy (data->subtarget, "");
- arm = get_armature(data->tar);
- if (arm){
- but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-40,96,18, &data->subtarget, 0, 24, 0, 0, "Bone");
}
- else
- strcpy (data->subtarget, "");
+ break;
+ case CONSTRAINT_TYPE_KINEMATIC:
+ {
+ bKinematicConstraint *data = con->data;
+ bArmature *arm;
+
+ height = 66;
+ BIF_ThemeColor(curCol);
+ glRects(*xco+40, *yco-height-16, *xco+width+50, *yco-14);
+ uiEmboss((float)*xco+40, (float)*yco-height-16, (float)*xco+width+50, (float)*yco-14, 1);
+
+ uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Tolerance:", *xco+((width/2)-96), *yco-20, 96, 18, &data->tolerance, 0.0001, 1.0, 0.0, 0.0, "Maximum distance to target after solving");
+ uiDefButI(block, NUM, B_CONSTRAINT_REDRAW, "Iterations:", *xco+((width/2)), *yco-20, 96, 18, &data->iterations, 1, 10000, 0.0, 0.0, "Maximum number of solving iterations");
- /* Draw XYZ toggles */
- but=uiDefButI(block, TOG|BIT|0, B_CONSTRAINT_TEST, "X", *xco+((width/2)-48), *yco-60, 32, 18, &data->flag, 0, 24, 0, 0, "Copy X component");
- but=uiDefButI(block, TOG|BIT|1, B_CONSTRAINT_TEST, "Y", *xco+((width/2)-16), *yco-60, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Y component");
- but=uiDefButI(block, TOG|BIT|2, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+16), *yco-60, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component");
+ uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-40, 96, 18, &data->tar, "Target Object");
+
+ arm = get_armature(data->tar);
+ if (arm){
+ but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-60,96,18, &data->subtarget, 0, 24, 0, 0, "Bone");
+ }
+ else
+ strcpy (data->subtarget, "");
+
+ }
+ break;
+ case CONSTRAINT_TYPE_TRACKTO:
+ {
+ bTrackToConstraint *data = con->data;
+ bArmature *arm;
+
+ height = 66;
+ BIF_ThemeColor(curCol);
+ glRects(*xco+40, *yco-height-16, *xco+width+50, *yco-14);
+ uiEmboss((float)*xco+40, (float)*yco-height-16, (float)*xco+width+50, (float)*yco-14, 1);
+
+ uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object");
+
+ arm = get_armature(data->tar);
+ if (arm){
+ but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-40,96,18, &data->subtarget, 0, 24, 0, 0, "Bone");
+ }
+ else
+ strcpy (data->subtarget, "");
+
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"X", *xco+((width/2)-84), *yco-60,19,18, &data->reserved1, 12.0, 0.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"Y", *xco+((width/2)-65), *yco-60,19,18, &data->reserved1, 12.0, 1.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"Z", *xco+((width/2)-46), *yco-60,19,18, &data->reserved1, 12.0, 2.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"-X", *xco+((width/2)-27), *yco-60,24,18, &data->reserved1, 12.0, 3.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"-Y", *xco+((width/2)-3), *yco-60,24,18, &data->reserved1, 12.0, 4.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"-Z", *xco+((width/2)+21), *yco-60,24,18, &data->reserved1, 12.0, 5.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"X", *xco+((width/2)+60), *yco-60,19,18, &data->reserved2, 13.0, 0.0, 0, 0, "Specify the axis that is points upward");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"Y", *xco+((width/2)+79), *yco-60,19,18, &data->reserved2, 13.0, 1.0, 0, 0, "Specify the axis that is points upward");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"Z", *xco+((width/2)+98), *yco-60,19,18, &data->reserved2, 13.0, 2.0, 0, 0, "Specify the axis that is points upward");
+ }
+ break;
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ {
+ bLockTrackConstraint *data = con->data;
+ bArmature *arm;
+ height = 66;
+ BIF_ThemeColor(curCol);
+ glRects(*xco+40, *yco-height-16, *xco+width+50, *yco-14);
+ uiEmboss((float)*xco+40, (float)*yco-height-16, (float)*xco+width+50, (float)*yco-14, 1);
+
+ /* Draw target parameters */
+ uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object");
+
+ arm = get_armature(data->tar);
+ if (arm){
+ but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-40,96,18, &data->subtarget, 0, 24, 0, 0, "Bone");
+ }
+ else
+ strcpy (data->subtarget, "");
+
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"X", *xco+((width/2)-84), *yco-60,19,18, &data->trackflag, 12.0, 0.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"Y", *xco+((width/2)-65), *yco-60,19,18, &data->trackflag, 12.0, 1.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"Z", *xco+((width/2)-46), *yco-60,19,18, &data->trackflag, 12.0, 2.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"-X", *xco+((width/2)-27), *yco-60,24,18, &data->trackflag, 12.0, 3.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"-Y", *xco+((width/2)-3), *yco-60,24,18, &data->trackflag, 12.0, 4.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"-Z", *xco+((width/2)+21), *yco-60,24,18, &data->trackflag, 12.0, 5.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"X", *xco+((width/2)+60), *yco-60,19,18, &data->lockflag, 13.0, 0.0, 0, 0, "Specify the axis that is locked");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"Y", *xco+((width/2)+79), *yco-60,19,18, &data->lockflag, 13.0, 1.0, 0, 0, "Specify the axis that is locked");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"Z", *xco+((width/2)+98), *yco-60,19,18, &data->lockflag, 13.0, 2.0, 0, 0, "Specify the axis that is locked");
+ }
+ break;
+ case CONSTRAINT_TYPE_FOLLOWPATH:
+ {
+ bFollowPathConstraint *data = con->data;
+
+ height = 66;
+ BIF_ThemeColor(curCol);
+ glRects(*xco+40, *yco-height-16, *xco+width+50, *yco-14);
+ uiEmboss((float)*xco+40, (float)*yco-height-16, (float)*xco+width+50, (float)*yco-14, 1);
+
+ uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object");
+
+ /* Draw Curve Follow toggle */
+ but=uiDefButI(block, TOG|BIT|0, B_CONSTRAINT_TEST, "CurveFollow", *xco+((width/2)-84), *yco-40, 90, 18, &data->followflag, 0, 24, 0, 0, "Object will follow the heading and banking of the curve");
+
+ /* Draw Offset number button */
+ uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Offset:", *xco+((width/2))+20, *yco-40, 96, 18, &data->offset, -9000, 9000, 100.0, 0.0, "Offset from the position corresponding to the time frame");
+
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"X", *xco+((width/2)-84), *yco-60,19,18, &data->trackflag, 12.0, 0.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"Y", *xco+((width/2)-65), *yco-60,19,18, &data->trackflag, 12.0, 1.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"Z", *xco+((width/2)-46), *yco-60,19,18, &data->trackflag, 12.0, 2.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"-X", *xco+((width/2)-27), *yco-60,24,18, &data->trackflag, 12.0, 3.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"-Y", *xco+((width/2)-3), *yco-60,24,18, &data->trackflag, 12.0, 4.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"-Z", *xco+((width/2)+21), *yco-60,24,18, &data->trackflag, 12.0, 5.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"X", *xco+((width/2)+60), *yco-60,19,18, &data->upflag, 13.0, 0.0, 0, 0, "Specify the axis that is points upward");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"Y", *xco+((width/2)+79), *yco-60,19,18, &data->upflag, 13.0, 1.0, 0, 0, "Specify the axis that is points upward");
+ uiDefButC(block, ROW,B_CONSTRAINT_REDRAW,"Z", *xco+((width/2)+98), *yco-60,19,18, &data->upflag, 13.0, 2.0, 0, 0, "Specify the axis that is points upward");
+ }
+ break;
+ case CONSTRAINT_TYPE_NULL:
+ {
+ height = 20;
+ BIF_ThemeColor(curCol);
+ glRects(*xco+40, *yco-height-16, *xco+width+50, *yco-14);
+ uiEmboss((float)*xco+40, (float)*yco-height-16, (float)*xco+width+50, (float)*yco-14, 1);
+ }
+ break;
+ default:
+ height = 0;
+ break;
}
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- {
- bRotateLikeConstraint *data = con->data;
- bArmature *arm;
- height = 46;
- BIF_ThemeColor(curCol);
- glRects(*xco+34, *yco-height-16, *xco+width+24, *yco-14);
- uiEmboss((float)*xco+34, (float)*yco-height-16, (float)*xco+width+24, (float)*yco-14, 1);
- uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object");
-
- arm = get_armature(data->tar);
- if (arm){
- but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-40,96,18, &data->subtarget, 0, 24, 0, 0, "Bone");
- }
- else
- strcpy (data->subtarget, "");
+ (*yco)-=(22+height);
+ }
- }
- break;
- case CONSTRAINT_TYPE_KINEMATIC:
- {
- bKinematicConstraint *data = con->data;
- bArmature *arm;
-
- height = 66;
- BIF_ThemeColor(curCol);
- glRects(*xco+34, *yco-height-16, *xco+width+24, *yco-14);
- uiEmboss((float)*xco+34, (float)*yco-height-16, (float)*xco+width+24, (float)*yco-14, 1);
-
- uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Tolerance:", *xco+((width/2)-96), *yco-20, 96, 18, &data->tolerance, 0.0001, 1.0, 0.0, 0.0, "Maximum distance to target after solving");
- uiDefButI(block, NUM, B_CONSTRAINT_REDRAW, "Iterations:", *xco+((width/2)), *yco-20, 96, 18, &data->iterations, 1, 10000, 0.0, 0.0, "Maximum number of solving iterations");
+ if (con->type!=CONSTRAINT_TYPE_NULL) {
+ uiDefButF(block, NUMSLI, B_CONSTRAINT_REDRAW, "Inf:", *xco+20, *yco, 166, 20, &(con->enforce), 0.0, 1.0, 0.0, 0.0, "Amount of influence this constraint will have on the final solution");
+ but = uiDefBut(block, BUT, B_CONSTRAINT_REDRAW, "Edit", *xco+186, *yco, 41, 20, 0, 0.0, 1.0, 0.0, 0.0, "Show this constraint's ipo in the object's Ipo window");
+ /* If this is on an object, add the constraint to the object */
+ uiButSetFunc (but, activate_constraint_ipo_func, con, NULL);
+ /* If this is on a bone, add the constraint to the action (if any) */
+ but = uiDefBut(block, BUT, B_CONSTRAINT_REDRAW, "Key", *xco+227, *yco, 41, 20, 0, 0.0, 1.0, 0.0, 0.0, "Add an influence keyframe to the constraint");
+ /* Add a keyframe to the influence IPO */
+ uiButSetFunc (but, add_influence_key_to_constraint, con, NULL);
+ (*yco)-=24;
+ }
+}
- uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-40, 96, 18, &data->tar, "Target Object");
-
- arm = get_armature(data->tar);
- if (arm){
- but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-60,96,18, &data->subtarget, 0, 24, 0, 0, "Bone");
- }
- else
- strcpy (data->subtarget, "");
-
- }
- break;
- case CONSTRAINT_TYPE_NULL:
- {
- height = 20;
- BIF_ThemeColor(curCol);
- glRects(*xco+34, *yco-height-16, *xco+width+24, *yco-14);
- uiEmboss((float)*xco+34, (float)*yco-height-16, (float)*xco+width+24, (float)*yco-14, 1);
- }
- break;
- case CONSTRAINT_TYPE_TRACKTO:
- {
- bTrackToConstraint *data = con->data;
- bArmature *arm;
+static uiBlock *add_constraintmenu(void *arg_unused)
+{
+ uiBlock *block;
+
+ ListBase *conlist;
+ char ownerstr[64];
+ short type;
+ short yco= 0;
+
+ conlist = get_constraint_client(ownerstr, &type, NULL);
+
+ block= uiNewBlock(&curarea->uiblocks, "add_constraintmenu", UI_EMBOSSP, UI_HELV, curarea->win);
- height = 46;
- BIF_ThemeColor(curCol);
- glRects(*xco+34, *yco-height-16, *xco+width+24, *yco-14);
- uiEmboss((float)*xco+34, (float)*yco-height-16, (float)*xco+width+24, (float)*yco-14, 1);
-
- uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object");
-
- arm = get_armature(data->tar);
- if (arm){
- but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-40,96,18, &data->subtarget, 0, 24, 0, 0, "Bone");
- }
- else
- strcpy (data->subtarget, "");
- }
- break;
- default:
- height = 0;
- break;
+ uiDefIconTextBut(block, BUTM, B_CONSTRAINT_ADD_LOCLIKE, ICON_BLANK1,"Copy Location", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefIconTextBut(block, BUTM, B_CONSTRAINT_ADD_ROTLIKE, ICON_BLANK1,"Copy Rotation", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, B_CONSTRAINT_ADD_TRACKTO, ICON_BLANK1,"Track To", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefIconTextBut(block, BUTM, B_CONSTRAINT_ADD_LOCKTRACK, ICON_BLANK1,"Lock Track", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefIconTextBut(block, BUTM, B_CONSTRAINT_ADD_FOLLOWPATH, ICON_BLANK1,"Follow Path", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+
+ if (type==TARGET_BONE) {
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, B_CONSTRAINT_ADD_KINEMATIC, ICON_BLANK1,"IK Solver", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefIconTextBut(block, BUTM, B_CONSTRAINT_ADD_ACTION, ICON_BLANK1,"Action", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+
}
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, B_CONSTRAINT_ADD_NULL, ICON_BLANK1,"Null", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+
- (*yco)-=(24+height);
+ uiBlockSetDirection(block, UI_RIGHT);
+ uiTextBoundsBlock(block, 50);
+
+ return block;
}
-
void do_constraintbuts(unsigned short event)
{
- ListBase *list;
- short type;
-
switch(event) {
case B_CONSTRAINT_CHANGENAME:
break;
@@ -549,23 +675,97 @@ void do_constraintbuts(unsigned short event)
allqueue (REDRAWVIEW3D, 0);
allqueue (REDRAWBUTSOBJECT, 0);
break;
- case B_CONSTRAINT_ADD:
+ case B_CONSTRAINT_ADD_NULL:
{
bConstraint *con;
- // ListBase *chanbase;
- // bConstraintChannel *chan;
-
- // Object *ob = OBACT;
- list = get_constraint_client(NULL, &type, NULL);
- // chanbase= get_constraint_client_channels(0);
- if (list){
- con = add_new_constraint();
- unique_constraint_name(con, list);
- // chan = add_new_constraint_channel(con->name);
- // ob->activecon = chan;
- // BLI_addtail(chanbase, chan);
- BLI_addtail(list, con);
- }
+
+ con = add_new_constraint(CONSTRAINT_TYPE_NULL);
+ add_constraint_to_client(con);
+
+ test_scene_constraints();
+ allqueue (REDRAWVIEW3D, 0);
+ allqueue (REDRAWBUTSOBJECT, 0);
+ }
+ break;
+ case B_CONSTRAINT_ADD_KINEMATIC:
+ {
+ bConstraint *con;
+
+ con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
+ add_constraint_to_client(con);
+
+ test_scene_constraints();
+ allqueue (REDRAWVIEW3D, 0);
+ allqueue (REDRAWBUTSOBJECT, 0);
+ }
+ break;
+ case B_CONSTRAINT_ADD_TRACKTO:
+ {
+ bConstraint *con;
+
+ con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
+ add_constraint_to_client(con);
+
+ test_scene_constraints();
+ allqueue (REDRAWVIEW3D, 0);
+ allqueue (REDRAWBUTSOBJECT, 0);
+ }
+ break;
+ case B_CONSTRAINT_ADD_ROTLIKE:
+ {
+ bConstraint *con;
+
+ con = add_new_constraint(CONSTRAINT_TYPE_ROTLIKE);
+ add_constraint_to_client(con);
+
+ test_scene_constraints();
+ allqueue (REDRAWVIEW3D, 0);
+ allqueue (REDRAWBUTSOBJECT, 0);
+ }
+ break;
+ case B_CONSTRAINT_ADD_LOCLIKE:
+ {
+ bConstraint *con;
+
+ con = add_new_constraint(CONSTRAINT_TYPE_LOCLIKE);
+ add_constraint_to_client(con);
+
+ test_scene_constraints();
+ allqueue (REDRAWVIEW3D, 0);
+ allqueue (REDRAWBUTSOBJECT, 0);
+ }
+ break;
+ case B_CONSTRAINT_ADD_ACTION:
+ {
+ bConstraint *con;
+
+ con = add_new_constraint(CONSTRAINT_TYPE_ACTION);
+ add_constraint_to_client(con);
+
+ test_scene_constraints();
+ allqueue (REDRAWVIEW3D, 0);
+ allqueue (REDRAWBUTSOBJECT, 0);
+ }
+ break;
+ case B_CONSTRAINT_ADD_LOCKTRACK:
+ {
+ bConstraint *con;
+
+ con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
+ add_constraint_to_client(con);
+
+ test_scene_constraints();
+ allqueue (REDRAWVIEW3D, 0);
+ allqueue (REDRAWBUTSOBJECT, 0);
+ }
+ break;
+ case B_CONSTRAINT_ADD_FOLLOWPATH:
+ {
+ bConstraint *con;
+
+ con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
+ add_constraint_to_client(con);
+
test_scene_constraints();
allqueue (REDRAWVIEW3D, 0);
allqueue (REDRAWBUTSOBJECT, 0);
@@ -601,7 +801,7 @@ static void object_panel_constraint(void)
if (conlist) {
- uiDefBut(block, BUT, B_CONSTRAINT_ADD, "Add", 10, 190, 95, 20, 0, 0.0, 0, 0, 0,"Add new constraint");
+ uiDefBlockBut(block, add_constraintmenu, NULL, "Add|>> ", 10, 190, 70, 20, "Add a new constraint");
/* Go through the list of constraints and draw them */
xco = 10;
diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c
index 60798fe0b8b..55fa3593140 100644
--- a/source/blender/src/editconstraint.c
+++ b/source/blender/src/editconstraint.c
@@ -81,50 +81,6 @@ const char *g_conString;
Object *g_conObj;
-void unique_constraint_name (bConstraint *con, ListBase *list){
- char tempname[64];
- int number;
- char *dot;
- int exists = 0;
- bConstraint *curcon;
-
- /* See if we even need to do this */
- for (curcon = list->first; curcon; curcon=curcon->next){
- if (curcon!=con){
- if (!strcmp(curcon->name, con->name)){
- exists = 1;
- break;
- }
- }
- }
-
- if (!exists)
- return;
-
- /* Strip off the suffix */
- dot=strchr(con->name, '.');
- if (dot)
- *dot=0;
-
- for (number = 1; number <=999; number++){
- sprintf (tempname, "%s.%03d", con->name, number);
-
- exists = 0;
- for (curcon=list->first; curcon; curcon=curcon->next){
- if (con!=curcon){
- if (!strcmp (curcon->name, tempname)){
- exists = 1;
- break;
- }
- }
- }
- if (!exists){
- strcpy (con->name, tempname);
- return;
- }
- }
-}
-
static int is_child_of_ex(Object *owner, const char *ownersubstr, Object *parent, const char *parsubstr)
{
Object *curob;
@@ -549,6 +505,79 @@ static short detect_constraint_loop (Object *owner, const char* substring, int d
break;
// return 1;
}
+ if (data->reserved2==data->reserved1){
+ curcon->flag |= CONSTRAINT_DISABLE;
+ result = 1;
+ break;
+ // return 1;
+ }
+ if (data->reserved2+3==data->reserved1){
+ curcon->flag |= CONSTRAINT_DISABLE;
+ result = 1;
+ break;
+ // return 1;
+ }
+ }
+ break;
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ {
+ bLockTrackConstraint *data = curcon->data;
+
+ if (!exist_object(data->tar)){
+ data->tar = NULL;
+ break;
+ }
+
+ if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
+ curcon->flag |= CONSTRAINT_DISABLE;
+ result = 1;
+ break;
+ // return 1;
+ }
+ if (detect_constraint_loop (data->tar, data->subtarget, disable)){
+ curcon->flag |= CONSTRAINT_DISABLE;
+ result = 1;
+ break;
+ // return 1;
+ }
+ if (data->lockflag==data->trackflag){
+ curcon->flag |= CONSTRAINT_DISABLE;
+ result = 1;
+ break;
+ // return 1;
+ }
+ if (data->lockflag+3==data->trackflag){
+ curcon->flag |= CONSTRAINT_DISABLE;
+ result = 1;
+ break;
+ // return 1;
+ }
+ }
+ break;
+ case CONSTRAINT_TYPE_FOLLOWPATH:
+ {
+ bFollowPathConstraint *data = curcon->data;
+
+ if (!exist_object(data->tar)){
+ data->tar = NULL;
+ break;
+ }
+ if (data->tar->type != OB_CURVE){
+ data->tar = NULL;
+ break;
+ }
+ if (data->upflag==data->trackflag){
+ curcon->flag |= CONSTRAINT_DISABLE;
+ result = 1;
+ break;
+ // return 1;
+ }
+ if (data->upflag+3==data->trackflag){
+ curcon->flag |= CONSTRAINT_DISABLE;
+ result = 1;
+ break;
+ // return 1;
+ }
}
break;
}
@@ -666,77 +695,14 @@ ListBase *get_constraint_client(char *name, short *clientType, void **clientdata
return list;
}
-void *new_constraint_data (short type)
-{
- void *result;
-
- switch (type){
- case CONSTRAINT_TYPE_KINEMATIC:
- {
- bKinematicConstraint *data;
- data = MEM_callocN(sizeof(bKinematicConstraint), "kinematicConstraint");
-
- data->tolerance = 0.001;
- data->iterations = 500;
-
- result = data;
- }
- break;
- case CONSTRAINT_TYPE_NULL:
- {
- result = NULL;
- }
- break;
- case CONSTRAINT_TYPE_TRACKTO:
- {
- bTrackToConstraint *data;
- data = MEM_callocN(sizeof(bTrackToConstraint), "tracktoConstraint");
-
- result = data;
-
- }
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- {
- bRotateLikeConstraint *data;
- data = MEM_callocN(sizeof(bRotateLikeConstraint), "rotlikeConstraint");
-
- result = data;
- }
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- {
- bLocateLikeConstraint *data;
- data = MEM_callocN(sizeof(bLocateLikeConstraint), "loclikeConstraint");
-
- data->flag |= LOCLIKE_X|LOCLIKE_Y|LOCLIKE_Z;
- result = data;
- }
- break;
- case CONSTRAINT_TYPE_ACTION:
- {
- bActionConstraint *data;
- data = MEM_callocN(sizeof(bActionConstraint), "actionConstraint");
-
- result = data;
- }
- break;
- default:
- result = NULL;
- break;
- }
-
- return result;
-}
-
-bConstraint * add_new_constraint(void)
+bConstraint * add_new_constraint(int type)
{
bConstraint *con;
con = MEM_callocN(sizeof(bConstraint), "constraint");
/* Set up a generic constraint datablock */
- con->type = CONSTRAINT_TYPE_TRACKTO;
+ con->type = type;
con->flag |= CONSTRAINT_EXPAND;
con->enforce=1.0F;
/* Load the data for it */
@@ -745,6 +711,29 @@ bConstraint * add_new_constraint(void)
return con;
}
+void add_constraint_to_object(bConstraint *con, Object *ob)
+{
+ ListBase *list;
+ list = &ob->constraints;
+ if (list)
+ {
+ unique_constraint_name(con, list);
+ BLI_addtail(list, con);
+ }
+}
+
+void add_constraint_to_client(bConstraint *con)
+{
+ ListBase *list;
+ short type;
+ list = get_constraint_client(NULL, &type, NULL);
+ if (list)
+ {
+ unique_constraint_name(con, list);
+ BLI_addtail(list, con);
+ }
+}
+
bConstraintChannel *add_new_constraint_channel(const char* name)
{
bConstraintChannel *chan = NULL;
@@ -755,3 +744,6 @@ bConstraintChannel *add_new_constraint_channel(const char* name)
return chan;
}
+void add_influence_key_to_constraint (bConstraint *con){
+ printf("doesn't do anything yet\n");
+} \ No newline at end of file
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index 0e12094a845..fe9d9d92d11 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -258,38 +258,59 @@ extern int undo_push(char *);
void make_track(void)
{
Base *base;
+ short mode=0;
if(G.scene->id.lib) return;
if(G.obedit) {
return;
}
if(BASACT==0) return;
-
-#if 0
- /* Not yet */
- notice ("Make Track no longer supported. Use constraints instead.");
- return;
- /* hrms, i would suppose then just to add a constraint for the user. be nice! (ton) */
-#endif
+ mode= pupmenu("Make Track %t|Constraint %x1|Old Track %x2");
+ if (mode == 0){
+ return;
+ }
+ else if (mode == 1){
+ bConstraint *con;
+ bTrackToConstraint *data;
- if(okee("Make Track")==0) return;
-
- base= FIRSTBASE;
- while(base) {
- if TESTBASELIB(base) {
- if(base!=BASACT) {
+ base= FIRSTBASE;
+ while(base) {
+ if TESTBASELIB(base) {
+ if(base!=BASACT) {
+ con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
+ strcpy (con->name, "AutoTrack");
+
+ data = con->data;
+ data->tar = BASACT->object;
- base->object->track= BASACT->object;
+ add_constraint_to_object(con, base->object);
+ }
}
+ base= base->next;
}
- base= base->next;
+
+ test_scene_constraints();
+ allqueue(REDRAWVIEW3D, 0);
+ sort_baselist(G.scene);
}
+ else if (mode == 2){
+ base= FIRSTBASE;
+ while(base) {
+ if TESTBASELIB(base) {
+ if(base!=BASACT) {
- test_scene_constraints();
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWOOPS, 0);
- sort_baselist(G.scene);
+ base->object->track= BASACT->object;
+ }
+ }
+ base= base->next;
+ }
+
+ test_scene_constraints();
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWOOPS, 0);
+ sort_baselist(G.scene);
+ }
}
void apply_obmat(Object *ob)
@@ -699,6 +720,47 @@ void make_parent(void)
base= base->next;
}
}
+ else if(par->type == OB_CURVE){
+ bConstraint *con;
+ bFollowPathConstraint *data;
+
+ mode= pupmenu("Make Parent %t|Normal Parent %x1|Follow Path %x2");
+ if (mode == 0){
+ return;
+ }
+ else if (mode == 2){
+
+ base= FIRSTBASE;
+ while(base) {
+ if TESTBASELIB(base) {
+ if(base!=BASACT) {
+ float cmat[4][4], vec[3], size[3];
+
+ con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
+ strcpy (con->name, "AutoPath");
+
+ data = con->data;
+ data->tar = BASACT->object;
+
+ add_constraint_to_object(con, base->object);
+
+ get_constraint_target(con, TARGET_OBJECT, NULL, cmat, size, G.scene->r.cfra - base->object->sf);
+ VecSubf(vec, &base->object->obmat[3], cmat[3]);
+
+ base->object->loc[0] = vec[0];
+ base->object->loc[1] = vec[1];
+ base->object->loc[2] = vec[2];
+ }
+ }
+ base= base->next;
+ }
+
+ test_scene_constraints();
+ allqueue(REDRAWVIEW3D, 0);
+ sort_baselist(G.scene);
+ return;
+ }
+ }
else if(par->type == OB_ARMATURE){
mode= pupmenu("Make Parent %t|Use Bone %x1|Use Armature %x2|Use Object %x3");
switch (mode){