4 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version. The Blender
10 * Foundation also sells licenses for use in proprietary software under
11 * the Blender License. See http://www.blender.org/BL/ for information
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24 * All rights reserved.
26 * The Original Code is: all of this file.
28 * Contributor(s): none yet.
30 * ***** END GPL/BL DUAL LICENSE BLOCK *****
37 #include "MEM_guardedalloc.h"
40 #include "BLI_blenlib.h"
41 #include "BLI_arithb.h"
43 #include "DNA_armature_types.h"
44 #include "DNA_constraint_types.h"
45 #include "DNA_object_types.h"
46 #include "DNA_action_types.h"
47 #include "DNA_curve_types.h"
48 #include "DNA_scene_types.h"
50 #include "BKE_utildefines.h"
51 #include "BKE_action.h"
52 #include "BKE_anim.h" // for the curve calculation part
53 #include "BKE_armature.h"
54 #include "BKE_blender.h"
55 #include "BKE_constraint.h"
56 #include "BKE_object.h"
58 #include "BKE_global.h"
59 #include "BKE_library.h"
68 #define M_PI 3.14159265358979323846
71 /* used by object.c */
72 void Mat4BlendMat4(float [][4], float [][4], float [][4], float );
74 /* Local function prototypes */
76 /* ********************* Data level ****************** */
78 void free_constraint_data (bConstraint *con)
86 MEM_freeN (con->data);
90 void free_constraints (ListBase *conlist)
94 /* Do any specific freeing */
95 for (con=conlist->first; con; con=con->next) {
96 free_constraint_data (con);
99 /* Free the whole list */
100 BLI_freelistN(conlist);
103 void free_constraint_channels (ListBase *chanbase)
105 bConstraintChannel *chan;
107 for (chan=chanbase->first; chan; chan=chan->next)
114 BLI_freelistN(chanbase);
117 void relink_constraints (struct ListBase *list)
121 for (con = list->first; con; con=con->next){
123 case CONSTRAINT_TYPE_KINEMATIC:
125 bKinematicConstraint *data;
131 case CONSTRAINT_TYPE_NULL:
135 case CONSTRAINT_TYPE_TRACKTO:
137 bTrackToConstraint *data;
143 case CONSTRAINT_TYPE_MINMAX:
145 bMinMaxConstraint *data;
151 case CONSTRAINT_TYPE_LOCKTRACK:
153 bLockTrackConstraint *data;
159 case CONSTRAINT_TYPE_ACTION:
161 bActionConstraint *data;
167 case CONSTRAINT_TYPE_LOCLIKE:
169 bLocateLikeConstraint *data;
175 case CONSTRAINT_TYPE_ROTLIKE:
177 bRotateLikeConstraint *data;
183 case CONSTRAINT_TYPE_FOLLOWPATH:
185 bFollowPathConstraint *data;
191 case CONSTRAINT_TYPE_STRETCHTO:
193 bStretchToConstraint *data;
204 void copy_constraint_channels (ListBase *dst, ListBase *src)
206 bConstraintChannel *dchan, *schan;
208 dst->first=dst->last=NULL;
209 duplicatelist(dst, src);
211 for (dchan=dst->first, schan=src->first; dchan; dchan=dchan->next, schan=schan->next){
212 dchan->ipo = copy_ipo(schan->ipo);
216 void clone_constraint_channels (ListBase *dst, ListBase *src)
218 bConstraintChannel *dchan, *schan;
220 dst->first=dst->last=NULL;
221 duplicatelist(dst, src);
223 for (dchan=dst->first, schan=src->first; dchan; dchan=dchan->next, schan=schan->next){
224 id_us_plus((ID *)dchan->ipo);
228 void copy_constraints (ListBase *dst, ListBase *src)
232 dst->first= dst->last= NULL;
234 duplicatelist (dst, src);
236 for (con = dst->first; con; con=con->next) {
237 con->data = MEM_dupallocN (con->data);
238 /* removed a whole lot of useless code here (ton) */
243 /* **************** Editor Functions **************** */
245 char constraint_has_target (bConstraint *con)
248 case CONSTRAINT_TYPE_TRACKTO:
250 bTrackToConstraint *data = con->data;
255 case CONSTRAINT_TYPE_KINEMATIC:
257 bKinematicConstraint *data = con->data;
262 case CONSTRAINT_TYPE_FOLLOWPATH:
264 bFollowPathConstraint *data = con->data;
269 case CONSTRAINT_TYPE_ROTLIKE:
271 bRotateLikeConstraint *data = con->data;
276 case CONSTRAINT_TYPE_LOCLIKE:
278 bLocateLikeConstraint *data = con->data;
283 case CONSTRAINT_TYPE_MINMAX:
285 bMinMaxConstraint *data = con->data;
290 case CONSTRAINT_TYPE_ACTION:
292 bActionConstraint *data = con->data;
297 case CONSTRAINT_TYPE_LOCKTRACK:
299 bLockTrackConstraint *data = con->data;
303 case CONSTRAINT_TYPE_STRETCHTO:
305 bStretchToConstraint *data = con->data;
311 // Unknown types or CONSTRAINT_TYPE_NULL or no target
315 Object *get_constraint_target(bConstraint *con, char **subtarget)
318 * If the target for this constraint is target, return a pointer
319 * to the name for this constraints subtarget ... NULL otherwise
322 case CONSTRAINT_TYPE_ACTION:
324 bActionConstraint *data = con->data;
325 *subtarget= data->subtarget;
329 case CONSTRAINT_TYPE_LOCLIKE:
331 bLocateLikeConstraint *data = con->data;
332 *subtarget= data->subtarget;
336 case CONSTRAINT_TYPE_ROTLIKE:
338 bRotateLikeConstraint *data = con->data;
339 *subtarget= data->subtarget;
343 case CONSTRAINT_TYPE_KINEMATIC:
345 bKinematicConstraint *data = con->data;
346 *subtarget= data->subtarget;
350 case CONSTRAINT_TYPE_TRACKTO:
352 bTrackToConstraint *data = con->data;
353 *subtarget= data->subtarget;
357 case CONSTRAINT_TYPE_MINMAX:
359 bMinMaxConstraint *data = con->data;
360 *subtarget= data->subtarget;
364 case CONSTRAINT_TYPE_LOCKTRACK:
366 bLockTrackConstraint *data = con->data;
367 *subtarget= data->subtarget;
371 case CONSTRAINT_TYPE_FOLLOWPATH:
373 bFollowPathConstraint *data = con->data;
378 case CONSTRAINT_TYPE_STRETCHTO:
380 bStretchToConstraint *data = con->data;
381 *subtarget= data->subtarget;
390 void set_constraint_target(bConstraint *con, Object *ob, char *subtarget)
393 * Set the target for this constraint
396 case CONSTRAINT_TYPE_ACTION:
398 bActionConstraint *data = con->data;
400 if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
403 case CONSTRAINT_TYPE_LOCLIKE:
405 bLocateLikeConstraint *data = con->data;
407 if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
410 case CONSTRAINT_TYPE_ROTLIKE:
412 bRotateLikeConstraint *data = con->data;
414 if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
417 case CONSTRAINT_TYPE_KINEMATIC:
419 bKinematicConstraint *data = con->data;
421 if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
424 case CONSTRAINT_TYPE_TRACKTO:
426 bTrackToConstraint *data = con->data;
428 if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
431 case CONSTRAINT_TYPE_LOCKTRACK:
433 bLockTrackConstraint *data = con->data;
435 if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
438 case CONSTRAINT_TYPE_FOLLOWPATH:
440 bFollowPathConstraint *data = con->data;
444 case CONSTRAINT_TYPE_STRETCHTO:
446 bStretchToConstraint *data = con->data;
448 if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
454 void unique_constraint_name (bConstraint *con, ListBase *list)
462 /* See if we even need to do this */
463 for (curcon = list->first; curcon; curcon=curcon->next){
465 if (!strcmp(curcon->name, con->name)){
475 /* Strip off the suffix */
476 dot=strchr(con->name, '.');
480 for (number = 1; number <=999; number++){
481 sprintf (tempname, "%s.%03d", con->name, number);
484 for (curcon=list->first; curcon; curcon=curcon->next){
486 if (!strcmp (curcon->name, tempname)){
493 strcpy (con->name, tempname);
499 void *new_constraint_data (short type)
504 case CONSTRAINT_TYPE_KINEMATIC:
506 bKinematicConstraint *data;
507 data = MEM_callocN(sizeof(bKinematicConstraint), "kinematicConstraint");
509 data->tolerance = (float)0.001;
510 data->weight= (float)1.0;
511 data->iterations = 500;
512 data->flag= CONSTRAINT_IK_TIP;
517 case CONSTRAINT_TYPE_NULL:
522 case CONSTRAINT_TYPE_TRACKTO:
524 bTrackToConstraint *data;
525 data = MEM_callocN(sizeof(bTrackToConstraint), "tracktoConstraint");
528 data->reserved1 = TRACK_Y;
529 data->reserved2 = UP_Z;
535 case CONSTRAINT_TYPE_MINMAX:
537 bMinMaxConstraint *data;
538 data = MEM_callocN(sizeof(bMinMaxConstraint), "minmaxConstraint");
541 data->minmaxflag = TRACK_Z;
543 data->cache[0] = data->cache[1] = data->cache[2] = 0.0f;
551 case CONSTRAINT_TYPE_ROTLIKE:
553 bRotateLikeConstraint *data;
554 data = MEM_callocN(sizeof(bRotateLikeConstraint), "rotlikeConstraint");
559 case CONSTRAINT_TYPE_LOCLIKE:
561 bLocateLikeConstraint *data;
562 data = MEM_callocN(sizeof(bLocateLikeConstraint), "loclikeConstraint");
564 data->flag |= LOCLIKE_X|LOCLIKE_Y|LOCLIKE_Z;
568 case CONSTRAINT_TYPE_ACTION:
570 bActionConstraint *data;
571 data = MEM_callocN(sizeof(bActionConstraint), "actionConstraint");
577 case CONSTRAINT_TYPE_LOCKTRACK:
579 bLockTrackConstraint *data;
580 data = MEM_callocN(sizeof(bLockTrackConstraint), "locktrackConstraint");
582 data->trackflag = TRACK_Y;
583 data->lockflag = LOCK_Z;
588 case CONSTRAINT_TYPE_FOLLOWPATH:
590 bFollowPathConstraint *data;
591 data = MEM_callocN(sizeof(bFollowPathConstraint), "followpathConstraint");
593 data->trackflag = TRACK_Y;
596 data->followflag = 0;
601 case CONSTRAINT_TYPE_STRETCHTO:
603 bStretchToConstraint *data;
604 data = MEM_callocN(sizeof(bStretchToConstraint), "StretchToConstraint");
608 data->orglength = 0.0;
621 bConstraintChannel *get_constraint_channel (ListBase *list, const char *name)
623 bConstraintChannel *chan;
625 for (chan = list->first; chan; chan=chan->next) {
626 if (!strcmp(name, chan->name)) {
633 /* finds or creates new constraint channel */
634 bConstraintChannel *verify_constraint_channel (ListBase *list, const char *name)
636 bConstraintChannel *chan;
638 chan= get_constraint_channel (list, name);
640 chan= MEM_callocN(sizeof(bConstraintChannel), "new constraint chan");
641 BLI_addtail(list, chan);
642 strcpy(chan->name, name);
649 /* ***************** Evaluating ********************* */
652 void do_constraint_channels (ListBase *conbase, ListBase *chanbase, float ctime)
655 bConstraintChannel *chan;
658 for (con=conbase->first; con; con=con->next) {
659 chan = get_constraint_channel(chanbase, con->name);
660 if (chan && chan->ipo){
661 calc_ipo(chan->ipo, ctime);
662 for (icu=chan->ipo->curve.first; icu; icu=icu->next){
663 switch (icu->adrcode){
665 con->enforce = icu->curval;
666 if (con->enforce<0) con->enforce=0;
667 else if (con->enforce>1) con->enforce=1;
675 void Mat4BlendMat4(float out[][4], float dst[][4], float src[][4], float srcweight)
677 float squat[4], dquat[4], fquat[4];
678 float ssize[3], dsize[3], fsize[4];
679 float sloc[3], dloc[3], floc[3];
680 float mat3[3][3], dstweight;
681 float qmat[3][3], smat[3][3];
684 dstweight = 1.0F-srcweight;
686 Mat3CpyMat4(mat3, dst);
687 Mat3ToQuat(mat3, dquat);
688 Mat3ToSize(mat3, dsize);
689 VECCOPY (dloc, dst[3]);
691 Mat3CpyMat4(mat3, src);
692 Mat3ToQuat(mat3, squat);
693 Mat3ToSize(mat3, ssize);
694 VECCOPY (sloc, src[3]);
696 /* Do the actual blend */
698 floc[i] = (dloc[i]*dstweight) + (sloc[i]*srcweight);
699 fsize[i] = 1.0f + ((dsize[i]-1.0f)*dstweight) + ((ssize[i]-1.0f)*srcweight);
700 fquat[i+1] = (dquat[i+1]*dstweight) + (squat[i+1]*srcweight);
703 /* Do one more iteration for the quaternions only and normalize the quaternion if needed */
704 fquat[0] = 1.0f + ((dquat[0]-1.0f)*dstweight) + ((squat[0]-1.0f)*srcweight);
707 QuatToMat3(fquat, qmat);
708 SizeToMat3(fsize, smat);
710 Mat3MulMat3(mat3, qmat, smat);
711 Mat4CpyMat3(out, mat3);
712 VECCOPY (out[3], floc);
715 static void constraint_target_to_mat4 (Object *ob, const char *substring, float mat[][4], float size[3], float ctime)
719 if (!strlen(substring)) {
720 Mat4CpyMat4 (mat, ob->obmat);
721 VECCOPY (size, ob->size); // whats this for, hack! (ton)
726 float bsize[3]={1, 1, 1};
728 pchan = get_pose_channel(ob->pose, substring);
731 * Multiply the objectspace bonematrix by the skeletons's global
732 * transform to obtain the worldspace transformation of the target
734 Mat4MulMat4 (mat, pchan->pose_mat, ob->obmat);
737 Mat4CpyMat4 (mat, ob->obmat);
739 VECCOPY(size, bsize); // whats this for, hack! (ton)
743 /* called during solve_constraints */
744 /* also for make_parent, to find correct inverse of "follow path" */
745 /* warning, ownerdata is void... is not Bone anymore, but posechannel */
746 short get_constraint_target_matrix (bConstraint *con, short ownertype, void* ownerdata, float mat[][4], float size[3], float ctime)
751 case CONSTRAINT_TYPE_NULL:
756 case CONSTRAINT_TYPE_ACTION:
758 if (ownertype == TARGET_BONE) {
759 extern void chan_calc_mat(bPoseChannel *chan);
760 bActionConstraint *data = (bActionConstraint*)con->data;
762 bPoseChannel *pchan, *tchan;
763 float tempmat3[3][3];
767 Mat4One(mat); // return mat
769 if (data->tar==NULL) return 0;
771 /* need proper check for bone... */
772 if(data->subtarget[0]) {
773 pchan = get_pose_channel(data->tar->pose, data->subtarget);
775 float arm_mat[3][3], pose_mat[3][3]; /* arm mat should be bone mat! bug... */
777 Mat3CpyMat4(arm_mat, pchan->bone->arm_mat);
778 Mat3CpyMat4(pose_mat, pchan->pose_mat);
780 /* new; true local rotation constraint */
782 float diff_mat[3][3], par_mat[3][3], ipar_mat[3][3];
783 /* we need the local rotation = current rotation - (parent rotation + restpos) */
786 Mat3CpyMat4(par_mat, pchan->parent->pose_mat);
787 Mat3MulMat3(diff_mat, par_mat, arm_mat);
789 Mat3Inv(ipar_mat, diff_mat);
792 Mat3Inv(ipar_mat, arm_mat);
795 Mat3MulMat3(tempmat3, ipar_mat, pose_mat);
797 else { /* we use the deform mat, for backwards compatibility */
800 Mat3Inv(imat, arm_mat);
801 Mat3MulMat3(tempmat3, pose_mat, imat);
804 else Mat3One(tempmat3);
809 constraint_target_to_mat4(data->tar, data->subtarget, ans, size, ctime);
810 /* extract rotation, is in global world coordinates */
811 Mat3CpyMat4(tempmat3, ans);
814 Mat3ToEul(tempmat3, eul);
815 eul[0]*=(float)(180.0/M_PI);
816 eul[1]*=(float)(180.0/M_PI);
817 eul[2]*=(float)(180.0/M_PI);
819 /* Target defines the animation */
820 s = (eul[data->type]-data->min)/(data->max-data->min);
826 t = ( s * (data->end-data->start)) + data->start;
828 /* Get the appropriate information from the action, we make temp pose */
829 pose = MEM_callocN(sizeof(bPose), "pose");
832 tchan= verify_pose_channel(pose, pchan->name);
833 extract_pose_from_action (pose, data->act, t);
835 chan_calc_mat(tchan);
837 Mat4CpyMat4(mat, tchan->chan_mat);
840 free_pose_channels(pose);
846 case CONSTRAINT_TYPE_LOCLIKE:
848 bLocateLikeConstraint *data = (bLocateLikeConstraint*)con->data;
851 constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime);
858 case CONSTRAINT_TYPE_MINMAX:
860 bMinMaxConstraint *data = (bMinMaxConstraint*)con->data;
863 constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime);
870 case CONSTRAINT_TYPE_ROTLIKE:
872 bRotateLikeConstraint *data;
873 data = (bRotateLikeConstraint*)con->data;
876 constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime);
883 case CONSTRAINT_TYPE_TRACKTO:
885 bTrackToConstraint *data;
886 data = (bTrackToConstraint*)con->data;
889 constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime);
896 case CONSTRAINT_TYPE_KINEMATIC:
898 bKinematicConstraint *data;
899 data = (bKinematicConstraint*)con->data;
902 constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime);
909 case CONSTRAINT_TYPE_LOCKTRACK:
911 bLockTrackConstraint *data;
912 data = (bLockTrackConstraint*)con->data;
915 constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime);
922 case CONSTRAINT_TYPE_FOLLOWPATH:
924 bFollowPathConstraint *data;
925 data = (bFollowPathConstraint*)con->data;
929 float q[4], vec[4], dir[3], *quat, x1, totmat[4][4];
937 /* note; when creating constraints that follow path, the curve gets the CU_PATH set now,
938 currently for paths to work it needs to go through the bevlist/displist system (ton) */
939 if(cu->path && cu->path->data) {
940 curvetime= bsystem_time(data->tar, data->tar->parent, (float)ctime, 0.0) - data->offset;
942 if(calc_ipo_spec(cu->ipo, CU_SPEED, &curvetime)==0) {
943 curvetime /= cu->pathlen;
944 CLAMP(curvetime, 0.0, 1.0);
947 if(where_on_path(data->tar, curvetime, vec, dir) ) {
949 if(data->followflag){
950 quat= vectoquat(dir, (short) data->trackflag, (short) data->upflag);
953 q[0]= (float)cos(0.5*vec[3]);
954 x1= (float)sin(0.5*vec[3]);
958 QuatMul(quat, q, quat);
961 QuatToMat4(quat, totmat);
963 VECCOPY(totmat[3], vec);
965 Mat4MulSerie(mat, data->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL);
974 case CONSTRAINT_TYPE_STRETCHTO:
976 bStretchToConstraint *data;
977 data = (bStretchToConstraint*)con->data;
980 constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime);
997 /* only called during solve_constraints */
998 /* bone constraints create a fake object to work on, then ob is a workob */
999 void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype, void *ownerdata, float targetmat[][4])
1001 float M_oldmat[4][4];
1002 float M_identity[4][4];
1004 if (!constraint || !ob)
1007 Mat4One (M_identity);
1009 switch (constraint->type){
1010 case CONSTRAINT_TYPE_ACTION:
1013 bActionConstraint *data;
1015 data = constraint->data;
1016 Mat4CpyMat4 (temp, ob->obmat);
1018 Mat4MulMat4(ob->obmat, targetmat, temp);
1021 case CONSTRAINT_TYPE_LOCLIKE:
1023 bLocateLikeConstraint *data;
1025 data = constraint->data;
1027 if (data->flag & LOCLIKE_X)
1028 ob->obmat[3][0] = targetmat[3][0];
1029 if (data->flag & LOCLIKE_Y)
1030 ob->obmat[3][1] = targetmat[3][1];
1031 if (data->flag & LOCLIKE_Z)
1032 ob->obmat[3][2] = targetmat[3][2];
1035 case CONSTRAINT_TYPE_ROTLIKE:
1040 Mat4ToSize(ob->obmat, size);
1042 Mat4CpyMat4 (tmat, targetmat);
1045 ob->obmat[0][0] = tmat[0][0]*size[0];
1046 ob->obmat[0][1] = tmat[0][1]*size[1];
1047 ob->obmat[0][2] = tmat[0][2]*size[2];
1049 ob->obmat[1][0] = tmat[1][0]*size[0];
1050 ob->obmat[1][1] = tmat[1][1]*size[1];
1051 ob->obmat[1][2] = tmat[1][2]*size[2];
1053 ob->obmat[2][0] = tmat[2][0]*size[0];
1054 ob->obmat[2][1] = tmat[2][1]*size[1];
1055 ob->obmat[2][2] = tmat[2][2]*size[2];
1058 case CONSTRAINT_TYPE_NULL:
1062 case CONSTRAINT_TYPE_MINMAX:
1066 bMinMaxConstraint *data;
1068 data = constraint->data;
1070 switch (data->minmaxflag){
1072 val1 = targetmat[3][2];
1073 val2 = ob->obmat[3][2]-data->offset;
1077 val1 = targetmat[3][1];
1078 val2 = ob->obmat[3][1]-data->offset;
1082 val1 = targetmat[3][0];
1083 val2 = ob->obmat[3][0]-data->offset;
1087 val2 = targetmat[3][2];
1088 val1 = ob->obmat[3][2]-data->offset;
1092 val2 = targetmat[3][1];
1093 val1 = ob->obmat[3][1]-data->offset;
1097 val2 = targetmat[3][0];
1098 val1 = ob->obmat[3][0]-data->offset;
1106 ob->obmat[3][index] = targetmat[3][index] + data->offset;
1107 if (data->sticky==1) {
1108 if (data->stuck==1) {
1109 VECCOPY(ob->obmat[3], data->cache);
1111 VECCOPY(data->cache, ob->obmat[3]);
1120 case CONSTRAINT_TYPE_TRACKTO:
1122 bTrackToConstraint *data;
1129 data=(bTrackToConstraint*)constraint->data;
1133 /* Get size property, since ob->size is only the object's own relative size, not its global one */
1134 Mat4ToSize (ob->obmat, size);
1136 Mat4CpyMat4 (M_oldmat, ob->obmat);
1138 // Clear the object's rotation
1139 ob->obmat[0][0]=size[0];
1143 ob->obmat[1][1]=size[1];
1147 ob->obmat[2][2]=size[2];
1150 VecSubf(vec, ob->obmat[3], targetmat[3]);
1151 quat= vectoquat(vec, (short)data->reserved1, (short)data->reserved2);
1152 QuatToMat3(quat, totmat);
1154 Mat4CpyMat4(tmat, ob->obmat);
1156 Mat4MulMat34(ob->obmat, totmat, tmat);
1160 case CONSTRAINT_TYPE_KINEMATIC:
1165 case CONSTRAINT_TYPE_LOCKTRACK:
1167 bLockTrackConstraint *data;
1168 float vec[3],vec2[3];
1176 data=(bLockTrackConstraint*)constraint->data;
1181 Mat4CpyMat4 (M_oldmat, ob->obmat);
1183 /* Vector object -> target */
1184 VecSubf(vec, targetmat[3], ob->obmat[3]);
1185 switch (data->lockflag){
1186 case LOCK_X: /* LOCK X */
1188 switch (data->trackflag){
1189 case TRACK_Y: /* LOCK X TRACK Y */
1191 /* Projection of Vector on the plane */
1192 Projf(vec2, vec, ob->obmat[0]);
1193 VecSubf(totmat[1], vec, vec2);
1194 Normalise(totmat[1]);
1196 /* the x axis is fixed*/
1197 totmat[0][0] = ob->obmat[0][0];
1198 totmat[0][1] = ob->obmat[0][1];
1199 totmat[0][2] = ob->obmat[0][2];
1200 Normalise(totmat[0]);
1202 /* the z axis gets mapped onto
1203 a third orthogonal vector */
1204 Crossf(totmat[2], totmat[0], totmat[1]);
1207 case TRACK_Z: /* LOCK X TRACK Z */
1209 /* Projection of Vector on the plane */
1210 Projf(vec2, vec, ob->obmat[0]);
1211 VecSubf(totmat[2], vec, vec2);
1212 Normalise(totmat[2]);
1214 /* the x axis is fixed*/
1215 totmat[0][0] = ob->obmat[0][0];
1216 totmat[0][1] = ob->obmat[0][1];
1217 totmat[0][2] = ob->obmat[0][2];
1218 Normalise(totmat[0]);
1220 /* the z axis gets mapped onto
1221 a third orthogonal vector */
1222 Crossf(totmat[1], totmat[2], totmat[0]);
1225 case TRACK_nY: /* LOCK X TRACK -Y */
1227 /* Projection of Vector on the plane */
1228 Projf(vec2, vec, ob->obmat[0]);
1229 VecSubf(totmat[1], vec, vec2);
1230 Normalise(totmat[1]);
1231 VecMulf(totmat[1],-1);
1233 /* the x axis is fixed*/
1234 totmat[0][0] = ob->obmat[0][0];
1235 totmat[0][1] = ob->obmat[0][1];
1236 totmat[0][2] = ob->obmat[0][2];
1237 Normalise(totmat[0]);
1239 /* the z axis gets mapped onto
1240 a third orthogonal vector */
1241 Crossf(totmat[2], totmat[0], totmat[1]);
1244 case TRACK_nZ: /* LOCK X TRACK -Z */
1246 /* Projection of Vector on the plane */
1247 Projf(vec2, vec, ob->obmat[0]);
1248 VecSubf(totmat[2], vec, vec2);
1249 Normalise(totmat[2]);
1250 VecMulf(totmat[2],-1);
1252 /* the x axis is fixed*/
1253 totmat[0][0] = ob->obmat[0][0];
1254 totmat[0][1] = ob->obmat[0][1];
1255 totmat[0][2] = ob->obmat[0][2];
1256 Normalise(totmat[0]);
1258 /* the z axis gets mapped onto
1259 a third orthogonal vector */
1260 Crossf(totmat[1], totmat[2], totmat[0]);
1265 totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
1266 totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
1267 totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
1273 case LOCK_Y: /* LOCK Y */
1275 switch (data->trackflag){
1276 case TRACK_X: /* LOCK Y TRACK X */
1278 /* Projection of Vector on the plane */
1279 Projf(vec2, vec, ob->obmat[1]);
1280 VecSubf(totmat[0], vec, vec2);
1281 Normalise(totmat[0]);
1283 /* the y axis is fixed*/
1284 totmat[1][0] = ob->obmat[1][0];
1285 totmat[1][1] = ob->obmat[1][1];
1286 totmat[1][2] = ob->obmat[1][2];
1287 Normalise(totmat[1]);
1289 /* the z axis gets mapped onto
1290 a third orthogonal vector */
1291 Crossf(totmat[2], totmat[0], totmat[1]);
1294 case TRACK_Z: /* LOCK Y TRACK Z */
1296 /* Projection of Vector on the plane */
1297 Projf(vec2, vec, ob->obmat[1]);
1298 VecSubf(totmat[2], vec, vec2);
1299 Normalise(totmat[2]);
1301 /* the y axis is fixed*/
1302 totmat[1][0] = ob->obmat[1][0];
1303 totmat[1][1] = ob->obmat[1][1];
1304 totmat[1][2] = ob->obmat[1][2];
1305 Normalise(totmat[1]);
1307 /* the z axis gets mapped onto
1308 a third orthogonal vector */
1309 Crossf(totmat[0], totmat[1], totmat[2]);
1312 case TRACK_nX: /* LOCK Y TRACK -X */
1314 /* Projection of Vector on the plane */
1315 Projf(vec2, vec, ob->obmat[1]);
1316 VecSubf(totmat[0], vec, vec2);
1317 Normalise(totmat[0]);
1318 VecMulf(totmat[0],-1);
1320 /* the y axis is fixed*/
1321 totmat[1][0] = ob->obmat[1][0];
1322 totmat[1][1] = ob->obmat[1][1];
1323 totmat[1][2] = ob->obmat[1][2];
1324 Normalise(totmat[1]);
1326 /* the z axis gets mapped onto
1327 a third orthogonal vector */
1328 Crossf(totmat[2], totmat[0], totmat[1]);
1331 case TRACK_nZ: /* LOCK Y TRACK -Z */
1333 /* Projection of Vector on the plane */
1334 Projf(vec2, vec, ob->obmat[1]);
1335 VecSubf(totmat[2], vec, vec2);
1336 Normalise(totmat[2]);
1337 VecMulf(totmat[2],-1);
1339 /* the y axis is fixed*/
1340 totmat[1][0] = ob->obmat[1][0];
1341 totmat[1][1] = ob->obmat[1][1];
1342 totmat[1][2] = ob->obmat[1][2];
1343 Normalise(totmat[1]);
1345 /* the z axis gets mapped onto
1346 a third orthogonal vector */
1347 Crossf(totmat[0], totmat[1], totmat[2]);
1352 totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
1353 totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
1354 totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
1360 case LOCK_Z: /* LOCK Z */
1362 switch (data->trackflag){
1363 case TRACK_X: /* LOCK Z TRACK X */
1365 /* Projection of Vector on the plane */
1366 Projf(vec2, vec, ob->obmat[2]);
1367 VecSubf(totmat[0], vec, vec2);
1368 Normalise(totmat[0]);
1370 /* the z axis is fixed*/
1371 totmat[2][0] = ob->obmat[2][0];
1372 totmat[2][1] = ob->obmat[2][1];
1373 totmat[2][2] = ob->obmat[2][2];
1374 Normalise(totmat[2]);
1376 /* the x axis gets mapped onto
1377 a third orthogonal vector */
1378 Crossf(totmat[1], totmat[2], totmat[0]);
1381 case TRACK_Y: /* LOCK Z TRACK Y */
1383 /* Projection of Vector on the plane */
1384 Projf(vec2, vec, ob->obmat[2]);
1385 VecSubf(totmat[1], vec, vec2);
1386 Normalise(totmat[1]);
1388 /* the z axis is fixed*/
1389 totmat[2][0] = ob->obmat[2][0];
1390 totmat[2][1] = ob->obmat[2][1];
1391 totmat[2][2] = ob->obmat[2][2];
1392 Normalise(totmat[2]);
1394 /* the x axis gets mapped onto
1395 a third orthogonal vector */
1396 Crossf(totmat[0], totmat[1], totmat[2]);
1399 case TRACK_nX: /* LOCK Z TRACK -X */
1401 /* Projection of Vector on the plane */
1402 Projf(vec2, vec, ob->obmat[2]);
1403 VecSubf(totmat[0], vec, vec2);
1404 Normalise(totmat[0]);
1405 VecMulf(totmat[0],-1);
1407 /* the z axis is fixed*/
1408 totmat[2][0] = ob->obmat[2][0];
1409 totmat[2][1] = ob->obmat[2][1];
1410 totmat[2][2] = ob->obmat[2][2];
1411 Normalise(totmat[2]);
1413 /* the x axis gets mapped onto
1414 a third orthogonal vector */
1415 Crossf(totmat[1], totmat[2], totmat[0]);
1418 case TRACK_nY: /* LOCK Z TRACK -Y */
1420 /* Projection of Vector on the plane */
1421 Projf(vec2, vec, ob->obmat[2]);
1422 VecSubf(totmat[1], vec, vec2);
1423 Normalise(totmat[1]);
1424 VecMulf(totmat[1],-1);
1426 /* the z axis is fixed*/
1427 totmat[2][0] = ob->obmat[2][0];
1428 totmat[2][1] = ob->obmat[2][1];
1429 totmat[2][2] = ob->obmat[2][2];
1430 Normalise(totmat[2]);
1432 /* the x axis gets mapped onto
1433 a third orthogonal vector */
1434 Crossf(totmat[0], totmat[1], totmat[2]);
1439 totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
1440 totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
1441 totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
1449 totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
1450 totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
1451 totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
1455 /* Block to keep matrix heading */
1456 tmpmat[0][0] = ob->obmat[0][0];tmpmat[0][1] = ob->obmat[0][1];tmpmat[0][2] = ob->obmat[0][2];
1457 tmpmat[1][0] = ob->obmat[1][0];tmpmat[1][1] = ob->obmat[1][1];tmpmat[1][2] = ob->obmat[1][2];
1458 tmpmat[2][0] = ob->obmat[2][0];tmpmat[2][1] = ob->obmat[2][1];tmpmat[2][2] = ob->obmat[2][2];
1459 Normalise(tmpmat[0]);
1460 Normalise(tmpmat[1]);
1461 Normalise(tmpmat[2]);
1462 Mat3Inv(invmat,tmpmat);
1463 Mat3MulMat3(tmpmat,totmat,invmat);
1464 totmat[0][0] = tmpmat[0][0];totmat[0][1] = tmpmat[0][1];totmat[0][2] = tmpmat[0][2];
1465 totmat[1][0] = tmpmat[1][0];totmat[1][1] = tmpmat[1][1];totmat[1][2] = tmpmat[1][2];
1466 totmat[2][0] = tmpmat[2][0];totmat[2][1] = tmpmat[2][1];totmat[2][2] = tmpmat[2][2];
1468 Mat4CpyMat4(tmat, ob->obmat);
1470 mdet = Det3x3( totmat[0][0],totmat[0][1],totmat[0][2],
1471 totmat[1][0],totmat[1][1],totmat[1][2],
1472 totmat[2][0],totmat[2][1],totmat[2][2]);
1475 totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
1476 totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
1477 totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
1480 /* apply out transformaton to the object */
1481 Mat4MulMat34(ob->obmat, totmat, tmat);
1485 case CONSTRAINT_TYPE_FOLLOWPATH:
1487 bFollowPathConstraint *data;
1490 data=(bFollowPathConstraint*)constraint->data;
1493 // weird, this is needed? doesnt work for workob (ton)
1494 object_to_mat4(ob, obmat);
1496 Mat4MulSerie(ob->obmat, targetmat, obmat, NULL, NULL, NULL, NULL, NULL, NULL);
1500 case CONSTRAINT_TYPE_STRETCHTO:
1502 bStretchToConstraint *data;
1503 float size[3],scale[3],vec[3],xx[3],zz[3],orth[3];
1507 data=(bStretchToConstraint*)constraint->data;
1508 Mat4ToSize (ob->obmat, size);
1513 /* store X orientation before destroying obmat */
1514 xx[0] = ob->obmat[0][0];
1515 xx[1] = ob->obmat[0][1];
1516 xx[2] = ob->obmat[0][2];
1519 /* store Z orientation before destroying obmat */
1520 zz[0] = ob->obmat[2][0];
1521 zz[1] = ob->obmat[2][1];
1522 zz[2] = ob->obmat[2][2];
1525 VecSubf(vec, ob->obmat[3], targetmat[3]);
1530 dist = Normalise(vec);
1531 //dist = VecLenf( ob->obmat[3], targetmat[3]);
1533 if (data->orglength == 0) data->orglength = dist;
1534 if (data->bulge ==0) data->bulge = 1.0;
1536 scale[1] = dist/data->orglength;
1537 switch (data->volmode){
1538 /* volume preserving scaling */
1540 scale[0] = 1.0f - (float)sqrt(data->bulge) + (float)sqrt(data->bulge*(data->orglength/dist));
1541 scale[2] = scale[0];
1544 scale[0] = 1.0f + data->bulge * (data->orglength /dist - 1);
1549 scale[2] = 1.0f + data->bulge * (data->orglength /dist - 1);
1551 /* don't care for volume */
1556 default: /* should not happen, but in case*/
1558 } /* switch (data->volmode) */
1560 /* Clear the object's rotation and scale */
1561 ob->obmat[0][0]=size[0]*scale[0];
1565 ob->obmat[1][1]=size[1]*scale[1];
1569 ob->obmat[2][2]=size[2]*scale[2];
1571 VecSubf(vec, ob->obmat[3], targetmat[3]);
1573 /* new Y aligns object target connection*/
1574 totmat[1][0] = -vec[0];
1575 totmat[1][1] = -vec[1];
1576 totmat[1][2] = -vec[2];
1577 switch (data->plane){
1579 /* build new Z vector */
1580 /* othogonal to "new Y" "old X! plane */
1581 Crossf(orth, vec, xx);
1585 totmat[2][0] = orth[0];
1586 totmat[2][1] = orth[1];
1587 totmat[2][2] = orth[2];
1589 /* we decided to keep X plane*/
1590 Crossf(xx,orth, vec);
1592 totmat[0][0] = xx[0];
1593 totmat[0][1] = xx[1];
1594 totmat[0][2] = xx[2];
1597 /* build new X vector */
1598 /* othogonal to "new Y" "old Z! plane */
1599 Crossf(orth, vec, zz);
1603 totmat[0][0] = -orth[0];
1604 totmat[0][1] = -orth[1];
1605 totmat[0][2] = -orth[2];
1607 /* we decided to keep Z */
1608 Crossf(zz,orth, vec);
1610 totmat[2][0] = zz[0];
1611 totmat[2][1] = zz[1];
1612 totmat[2][2] = zz[2];
1614 } /* switch (data->plane) */
1617 Mat4CpyMat4(tmat, ob->obmat);
1619 Mat4MulMat34(ob->obmat, totmat, tmat);
1626 printf ("Error: Unknown constraint type\n");