diff options
-rw-r--r-- | source/blender/blenkernel/BKE_constraint.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 558 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_arithb.h | 5 | ||||
-rw-r--r-- | source/blender/blenlib/intern/arithb.c | 11 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 105 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 6 | ||||
-rw-r--r-- | source/blender/include/BIF_editconstraint.h | 7 | ||||
-rw-r--r-- | source/blender/include/butspace.h | 11 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_constraint_types.h | 33 | ||||
-rw-r--r-- | source/blender/src/buttons_object.c | 518 | ||||
-rw-r--r-- | source/blender/src/editconstraint.c | 210 | ||||
-rw-r--r-- | source/blender/src/editobject.c | 100 |
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){ |