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:
-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){