4 * ***** BEGIN GPL 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.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): 2007, Joshua Leung, major recode
27 * ***** END GPL LICENSE BLOCK *****
36 #include "MEM_guardedalloc.h"
37 //XXX #include "nla.h"
39 #include "BLI_blenlib.h"
40 #include "BLI_arithb.h"
41 #include "BLI_editVert.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_mesh_types.h"
49 #include "DNA_meshdata_types.h"
50 #include "DNA_lattice_types.h"
51 #include "DNA_scene_types.h"
52 #include "DNA_text_types.h"
54 #include "BKE_utildefines.h"
55 #include "BKE_action.h"
56 #include "BKE_anim.h" /* for the curve calculation part */
57 #include "BKE_armature.h"
58 #include "BKE_blender.h"
59 #include "BKE_constraint.h"
60 #include "BKE_displist.h"
61 #include "BKE_deform.h"
62 #include "BKE_DerivedMesh.h" /* for geometry targets */
63 #include "BKE_cdderivedmesh.h" /* for geometry targets */
64 #include "BKE_object.h"
66 #include "BKE_global.h"
67 #include "BKE_library.h"
68 #include "BKE_idprop.h"
70 #ifndef DISABLE_PYTHON
71 #include "BPY_extern.h"
81 #define M_PI 3.14159265358979323846
86 /* ************************ Constraints - General Utilities *************************** */
87 /* These functions here don't act on any specific constraints, and are therefore should/will
88 * not require any of the special function-pointers afforded by the relevant constraint
92 /* -------------- Naming -------------- */
94 /* Find the first available, non-duplicate name for a given constraint */
95 void unique_constraint_name (bConstraint *con, ListBase *list)
97 BLI_uniquename(list, con, "Const", offsetof(bConstraint, name), 32);
100 /* ----------------- Evaluation Loop Preparation --------------- */
102 /* package an object/bone for use in constraint evaluation */
103 /* This function MEM_calloc's a bConstraintOb struct, that will need to be freed after evaluation */
104 bConstraintOb *constraints_make_evalob (Scene *scene, Object *ob, void *subdata, short datatype)
108 /* create regardless of whether we have any data! */
109 cob= MEM_callocN(sizeof(bConstraintOb), "bConstraintOb");
111 /* for system time, part of deglobalization, code nicer later with local time (ton) */
114 /* based on type of available data */
116 case CONSTRAINT_OBTYPE_OBJECT:
118 /* disregard subdata... calloc should set other values right */
121 cob->type = datatype;
122 Mat4CpyMat4(cob->matrix, ob->obmat);
125 Mat4One(cob->matrix);
127 Mat4CpyMat4(cob->startmat, cob->matrix);
130 case CONSTRAINT_OBTYPE_BONE:
132 /* only set if we have valid bone, otherwise default */
135 cob->pchan = (bPoseChannel *)subdata;
136 cob->type = datatype;
138 /* matrix in world-space */
139 Mat4MulMat4(cob->matrix, cob->pchan->pose_mat, ob->obmat);
142 Mat4One(cob->matrix);
144 Mat4CpyMat4(cob->startmat, cob->matrix);
148 default: /* other types not yet handled */
149 Mat4One(cob->matrix);
150 Mat4One(cob->startmat);
157 /* cleanup after constraint evaluation */
158 void constraints_clear_evalob (bConstraintOb *cob)
160 float delta[4][4], imat[4][4];
162 /* prevent crashes */
166 /* calculate delta of constraints evaluation */
167 Mat4Invert(imat, cob->startmat);
168 Mat4MulMat4(delta, imat, cob->matrix);
170 /* copy matrices back to source */
172 case CONSTRAINT_OBTYPE_OBJECT:
174 /* cob->ob might not exist! */
176 /* copy new ob-matrix back to owner */
177 Mat4CpyMat4(cob->ob->obmat, cob->matrix);
179 /* copy inverse of delta back to owner */
180 Mat4Invert(cob->ob->constinv, delta);
184 case CONSTRAINT_OBTYPE_BONE:
186 /* cob->ob or cob->pchan might not exist */
187 if (cob->ob && cob->pchan) {
188 /* copy new pose-matrix back to owner */
189 Mat4MulMat4(cob->pchan->pose_mat, cob->matrix, cob->ob->imat);
191 /* copy inverse of delta back to owner */
192 Mat4Invert(cob->pchan->constinv, delta);
198 /* free tempolary struct */
202 /* -------------- Space-Conversion API -------------- */
204 /* This function is responsible for the correct transformations/conversions
205 * of a matrix from one space to another for constraint evaluation.
206 * For now, this is only implemented for Objects and PoseChannels.
208 void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4], short from, short to)
211 float diff_mat[4][4];
214 /* prevent crashes in these unlikely events */
215 if (ob==NULL || mat==NULL) return;
216 /* optimise trick - check if need to do anything */
217 if (from == to) return;
219 /* are we dealing with pose-channels or objects */
223 case CONSTRAINT_SPACE_WORLD: /* ---------- FROM WORLDSPACE ---------- */
226 Mat4Invert(imat, ob->obmat);
227 Mat4CpyMat4(tempmat, mat);
228 Mat4MulMat4(mat, tempmat, imat);
230 /* use pose-space as stepping stone for other spaces... */
231 if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) {
232 /* call self with slightly different values */
233 constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
237 case CONSTRAINT_SPACE_POSE: /* ---------- FROM POSESPACE ---------- */
240 if (to == CONSTRAINT_SPACE_WORLD) {
241 Mat4CpyMat4(tempmat, mat);
242 Mat4MulMat4(mat, tempmat, ob->obmat);
245 else if (to == CONSTRAINT_SPACE_LOCAL) {
248 float offs_bone[4][4];
250 /* construct offs_bone the same way it is done in armature.c */
251 Mat4CpyMat3(offs_bone, pchan->bone->bone_mat);
252 VECCOPY(offs_bone[3], pchan->bone->head);
253 offs_bone[3][1]+= pchan->bone->parent->length;
255 if (pchan->bone->flag & BONE_HINGE) {
256 /* pose_mat = par_pose-space_location * chan_mat */
259 /* the rotation of the parent restposition */
260 Mat4CpyMat4(tmat, pchan->bone->parent->arm_mat);
262 /* the location of actual parent transform */
263 VECCOPY(tmat[3], offs_bone[3]);
264 offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f;
265 Mat4MulVecfl(pchan->parent->pose_mat, tmat[3]);
267 Mat4MulMat4(diff_mat, offs_bone, tmat);
268 Mat4Invert(imat, diff_mat);
271 /* pose_mat = par_pose_mat * bone_mat * chan_mat */
272 Mat4MulMat4(diff_mat, offs_bone, pchan->parent->pose_mat);
273 Mat4Invert(imat, diff_mat);
277 /* pose_mat = chan_mat * arm_mat */
278 Mat4Invert(imat, pchan->bone->arm_mat);
281 Mat4CpyMat4(tempmat, mat);
282 Mat4MulMat4(mat, tempmat, imat);
285 /* pose to local with parent */
286 else if (to == CONSTRAINT_SPACE_PARLOCAL) {
288 Mat4Invert(imat, pchan->bone->arm_mat);
289 Mat4CpyMat4(tempmat, mat);
290 Mat4MulMat4(mat, tempmat, imat);
295 case CONSTRAINT_SPACE_LOCAL: /* ------------ FROM LOCALSPACE --------- */
297 /* local to pose - do inverse procedure that was done for pose to local */
299 /* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */
301 float offs_bone[4][4];
303 /* construct offs_bone the same way it is done in armature.c */
304 Mat4CpyMat3(offs_bone, pchan->bone->bone_mat);
305 VECCOPY(offs_bone[3], pchan->bone->head);
306 offs_bone[3][1]+= pchan->bone->parent->length;
308 if (pchan->bone->flag & BONE_HINGE) {
309 /* pose_mat = par_pose-space_location * chan_mat */
312 /* the rotation of the parent restposition */
313 Mat4CpyMat4(tmat, pchan->bone->parent->arm_mat);
315 /* the location of actual parent transform */
316 VECCOPY(tmat[3], offs_bone[3]);
317 offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f;
318 Mat4MulVecfl(pchan->parent->pose_mat, tmat[3]);
320 Mat4MulMat4(diff_mat, offs_bone, tmat);
321 Mat4CpyMat4(tempmat, mat);
322 Mat4MulMat4(mat, tempmat, diff_mat);
325 /* pose_mat = par_pose_mat * bone_mat * chan_mat */
326 Mat4MulMat4(diff_mat, offs_bone, pchan->parent->pose_mat);
327 Mat4CpyMat4(tempmat, mat);
328 Mat4MulMat4(mat, tempmat, diff_mat);
332 Mat4CpyMat4(diff_mat, pchan->bone->arm_mat);
334 Mat4CpyMat4(tempmat, mat);
335 Mat4MulMat4(mat, tempmat, diff_mat);
339 /* use pose-space as stepping stone for other spaces */
340 if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL)) {
341 /* call self with slightly different values */
342 constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
346 case CONSTRAINT_SPACE_PARLOCAL: /* -------------- FROM LOCAL WITH PARENT ---------- */
348 /* local + parent to pose */
350 Mat4CpyMat4(diff_mat, pchan->bone->arm_mat);
351 Mat4CpyMat4(tempmat, mat);
352 Mat4MulMat4(mat, diff_mat, tempmat);
355 /* use pose-space as stepping stone for other spaces */
356 if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL)) {
357 /* call self with slightly different values */
358 constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
366 if (from==CONSTRAINT_SPACE_WORLD && to==CONSTRAINT_SPACE_LOCAL) {
367 /* check if object has a parent - otherwise this won't work */
369 /* 'subtract' parent's effects from owner */
370 Mat4MulMat4(diff_mat, ob->parentinv, ob->parent->obmat);
371 Mat4Invert(imat, diff_mat);
372 Mat4CpyMat4(tempmat, mat);
373 Mat4MulMat4(mat, tempmat, imat);
376 else if (from==CONSTRAINT_SPACE_LOCAL && to==CONSTRAINT_SPACE_WORLD) {
377 /* check that object has a parent - otherwise this won't work */
379 /* 'add' parent's effect back to owner */
380 Mat4CpyMat4(tempmat, mat);
381 Mat4MulMat4(diff_mat, ob->parentinv, ob->parent->obmat);
382 Mat4MulMat4(mat, tempmat, diff_mat);
388 /* ------------ General Target Matrix Tools ---------- */
390 /* function that sets the given matrix based on given vertex group in mesh */
391 static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4])
395 EditMesh *em = EM_GetEditMesh(me);
396 float vec[3] = {0.0f, 0.0f, 0.0f}, tvec[3];
397 float normal[3] = {0.0f, 0.0f, 0.0f}, plane[3];
398 float imat[3][3], tmat[3][3];
401 /* initialize target matrix using target matrix */
402 Mat4CpyMat4(mat, ob->obmat);
404 /* get index of vertex group */
405 dgroup = get_named_vertexgroup_num(ob, substring);
406 if (dgroup < 0) return;
408 /* get DerivedMesh */
410 /* target is in editmode, so get a special derived mesh */
411 dm = CDDM_from_editmesh(em, ob->data);
414 /* when not in EditMode, this should exist */
415 dm = (DerivedMesh *)ob->derivedFinal;
418 /* only continue if there's a valid DerivedMesh */
420 MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
421 int *index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
422 int numVerts = dm->getNumVerts(dm);
426 /* check that dvert and index are valid pointers (just in case) */
427 if (dvert && index) {
428 /* get the average of all verts with that are in the vertex-group */
429 for (i = 0; i < numVerts; i++, index++) {
430 for (j = 0; j < dvert[i].totweight; j++) {
431 /* does this vertex belong to nominated vertex group? */
432 if (dvert[i].dw[j].def_nr == dgroup) {
433 dm->getVertCo(dm, i, co);
434 dm->getVertNo(dm, i, nor);
435 VecAddf(vec, vec, co);
436 VecAddf(normal, normal, nor);
445 /* calculate averages of normal and coordinates */
447 VecMulf(vec, 1.0f / count);
448 VecMulf(normal, 1.0f / count);
452 /* derive the rotation from the average normal:
453 * - code taken from transform_manipulator.c,
454 * calc_manipulator_stats, V3D_MANIP_NORMAL case
456 /* we need the transpose of the inverse for a normal... */
457 Mat3CpyMat4(imat, ob->obmat);
461 Mat3MulVecfl(tmat, normal);
464 VECCOPY(plane, tmat[1]);
466 VECCOPY(tmat[2], normal);
467 Crossf(tmat[0], normal, plane);
468 Crossf(tmat[1], tmat[2], tmat[0]);
470 Mat4CpyMat3(mat, tmat);
474 /* apply the average coordinate as the new location */
475 VecMat4MulVecfl(tvec, ob->obmat, vec);
476 VECCOPY(mat[3], tvec);
480 /* free temporary DerivedMesh created (in EditMode case) */
482 if (dm) dm->release(dm);
483 EM_EndEditMesh(me, em);
487 /* function that sets the given matrix based on given vertex group in lattice */
488 static void contarget_get_lattice_mat (Object *ob, char *substring, float mat[][4])
490 Lattice *lt= (Lattice *)ob->data;
492 DispList *dl = find_displist(&ob->disp, DL_VERTS);
493 float *co = dl?dl->verts:NULL;
494 BPoint *bp = lt->def;
496 MDeformVert *dvert = lt->dvert;
497 int tot_verts= lt->pntsu*lt->pntsv*lt->pntsw;
498 float vec[3]= {0.0f, 0.0f, 0.0f}, tvec[3];
499 int dgroup=0, grouped=0;
502 /* initialize target matrix using target matrix */
503 Mat4CpyMat4(mat, ob->obmat);
505 /* get index of vertex group */
506 dgroup = get_named_vertexgroup_num(ob, substring);
507 if (dgroup < 0) return;
508 if (dvert == NULL) return;
510 /* 1. Loop through control-points checking if in nominated vertex-group.
511 * 2. If it is, add it to vec to find the average point.
513 for (i=0; i < tot_verts; i++, dvert++) {
514 for (n= 0; n < dvert->totweight; n++) {
515 /* found match - vert is in vgroup */
516 if (dvert->dw[n].def_nr == dgroup) {
517 /* copy coordinates of point to temporary vector, then add to find average */
519 memcpy(tvec, co, 3*sizeof(float));
521 memcpy(tvec, bp->vec, 3*sizeof(float));
523 VecAddf(vec, vec, tvec);
530 /* advance pointer to coordinate data */
535 /* find average location, then multiply by ob->obmat to find world-space location */
537 VecMulf(vec, 1.0f / grouped);
538 VecMat4MulVecfl(tvec, ob->obmat, vec);
540 /* copy new location to matrix */
541 VECCOPY(mat[3], tvec);
544 /* generic function to get the appropriate matrix for most target cases */
545 /* The cases where the target can be object data have not been implemented */
546 static void constraint_target_to_mat4 (Object *ob, char *substring, float mat[][4], short from, short to, float headtail)
549 if (!strlen(substring)) {
550 Mat4CpyMat4(mat, ob->obmat);
551 constraint_mat_convertspace(ob, NULL, mat, from, to);
553 /* Case VERTEXGROUP */
554 /* Current method just takes the average location of all the points in the
555 * VertexGroup, and uses that as the location value of the targets. Where
556 * possible, the orientation will also be calculated, by calculating an
557 * 'average' vertex normal, and deriving the rotaation from that.
559 * NOTE: EditMode is not currently supported, and will most likely remain that
560 * way as constraints can only really affect things on object/bone level.
562 else if (ob->type == OB_MESH) {
563 contarget_get_mesh_mat(ob, substring, mat);
564 constraint_mat_convertspace(ob, NULL, mat, from, to);
566 else if (ob->type == OB_LATTICE) {
567 contarget_get_lattice_mat(ob, substring, mat);
568 constraint_mat_convertspace(ob, NULL, mat, from, to);
574 pchan = get_pose_channel(ob->pose, substring);
576 /* Multiply the PoseSpace accumulation/final matrix for this
577 * PoseChannel by the Armature Object's Matrix to get a worldspace
580 if (headtail < 0.000001) {
581 /* skip length interpolation if set to head */
582 Mat4MulMat4(mat, pchan->pose_mat, ob->obmat);
585 float tempmat[4][4], loc[3];
587 /* interpolate along length of bone */
588 VecLerpf(loc, pchan->pose_head, pchan->pose_tail, headtail);
590 /* use interpolated distance for subtarget */
591 Mat4CpyMat4(tempmat, pchan->pose_mat);
592 VecCopyf(tempmat[3], loc);
594 Mat4MulMat4(mat, tempmat, ob->obmat);
598 Mat4CpyMat4(mat, ob->obmat);
600 /* convert matrix space as required */
601 constraint_mat_convertspace(ob, pchan, mat, from, to);
605 /* ************************* Specific Constraints ***************************** */
606 /* Each constraint defines a set of functions, which will be called at the appropriate
607 * times. In addition to this, each constraint should have a type-info struct, where
608 * its functions are attached for use.
611 /* Template for type-info data:
612 * - make a copy of this when creating new constraints, and just change the functions
613 * pointed to as necessary
614 * - although the naming of functions doesn't matter, it would help for code
615 * readability, to follow the same naming convention as is presented here
616 * - any functions that a constraint doesn't need to define, don't define
617 * for such cases, just use NULL
618 * - these should be defined after all the functions have been defined, so that
619 * forward-definitions/prototypes don't need to be used!
620 * - keep this copy #if-def'd so that future constraints can get based off this
623 static bConstraintTypeInfo CTI_CONSTRNAME = {
624 CONSTRAINT_TYPE_CONSTRNAME, /* type */
625 sizeof(bConstrNameConstraint), /* size */
626 "ConstrName", /* name */
627 "bConstrNameConstraint", /* struct name */
628 constrname_free, /* free data */
629 constrname_relink, /* relink data */
630 constrname_copy, /* copy data */
631 constrname_new_data, /* new data */
632 constrname_get_tars, /* get constraint targets */
633 constrname_flush_tars, /* flush constraint targets */
634 constrname_get_tarmat, /* get target matrix */
635 constrname_evaluate /* evaluate */
639 /* This function should be used for the get_target_matrix member of all
640 * constraints that are not picky about what happens to their target matrix.
642 static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
644 if (VALID_CONS_TARGET(ct))
645 constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
650 /* This following macro should be used for all standard single-target *_get_tars functions
651 * to save typing and reduce maintainance woes.
652 * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
653 * really just to help this code easier to read)
655 #define SINGLETARGET_GET_TARS(con, datatar, datasubtarget, ct, list) \
657 ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \
660 strcpy(ct->subtarget, datasubtarget); \
661 ct->space= con->tarspace; \
662 ct->flag= CONSTRAINT_TAR_TEMP; \
665 if ((ct->tar->type==OB_ARMATURE) && (ct->subtarget[0])) ct->type = CONSTRAINT_OBTYPE_BONE; \
666 else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) ct->type = CONSTRAINT_OBTYPE_VERT; \
667 else ct->type = CONSTRAINT_OBTYPE_OBJECT; \
670 BLI_addtail(list, ct); \
673 /* This following macro should be used for all standard single-target *_get_tars functions
674 * to save typing and reduce maintainance woes. It does not do the subtarget related operations
675 * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
676 * really just to help this code easier to read)
678 #define SINGLETARGETNS_GET_TARS(con, datatar, ct, list) \
680 ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \
683 ct->space= con->tarspace; \
684 ct->flag= CONSTRAINT_TAR_TEMP; \
686 if (ct->tar) ct->type = CONSTRAINT_OBTYPE_OBJECT; \
688 BLI_addtail(list, ct); \
691 /* This following macro should be used for all standard single-target *_flush_tars functions
692 * to save typing and reduce maintainance woes.
693 * Note: the pointer to ct will be changed to point to the next in the list (as it gets removed)
694 * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
695 * really just to help this code easier to read)
697 #define SINGLETARGET_FLUSH_TARS(con, datatar, datasubtarget, ct, list, nocopy) \
700 bConstraintTarget *ctn = ct->next; \
703 strcpy(datasubtarget, ct->subtarget); \
704 con->tarspace= (char)ct->space; \
707 BLI_freelinkN(list, ct); \
712 /* This following macro should be used for all standard single-target *_flush_tars functions
713 * to save typing and reduce maintainance woes. It does not do the subtarget related operations.
714 * Note: the pointer to ct will be changed to point to the next in the list (as it gets removed)
715 * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
716 * really just to help this code easier to read)
718 #define SINGLETARGETNS_FLUSH_TARS(con, datatar, ct, list, nocopy) \
721 bConstraintTarget *ctn = ct->next; \
724 con->tarspace= (char)ct->space; \
727 BLI_freelinkN(list, ct); \
732 /* --------- ChildOf Constraint ------------ */
734 static void childof_new_data (void *cdata)
736 bChildOfConstraint *data= (bChildOfConstraint *)cdata;
738 data->flag = (CHILDOF_LOCX | CHILDOF_LOCY | CHILDOF_LOCZ |
739 CHILDOF_ROTX |CHILDOF_ROTY | CHILDOF_ROTZ |
740 CHILDOF_SIZEX | CHILDOF_SIZEY | CHILDOF_SIZEZ);
741 Mat4One(data->invmat);
744 static int childof_get_tars (bConstraint *con, ListBase *list)
747 bChildOfConstraint *data= con->data;
748 bConstraintTarget *ct;
750 /* standard target-getting macro for single-target constraints */
751 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
759 static void childof_flush_tars (bConstraint *con, ListBase *list, short nocopy)
762 bChildOfConstraint *data= con->data;
763 bConstraintTarget *ct= list->first;
765 /* the following macro is used for all standard single-target constraints */
766 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
770 static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
772 bChildOfConstraint *data= con->data;
773 bConstraintTarget *ct= targets->first;
775 /* only evaluate if there is a target */
776 if (VALID_CONS_TARGET(ct)) {
777 float parmat[4][4], invmat[4][4], tempmat[4][4];
778 float loc[3], eul[3], size[3];
779 float loco[3], eulo[3], sizo[3];
781 /* get offset (parent-inverse) matrix */
782 Mat4CpyMat4(invmat, data->invmat);
784 /* extract components of both matrices */
785 VECCOPY(loc, ct->matrix[3]);
786 Mat4ToEul(ct->matrix, eul);
787 Mat4ToSize(ct->matrix, size);
789 VECCOPY(loco, invmat[3]);
790 Mat4ToEul(invmat, eulo);
791 Mat4ToSize(invmat, sizo);
793 /* disable channels not enabled */
794 if (!(data->flag & CHILDOF_LOCX)) loc[0]= loco[0]= 0.0f;
795 if (!(data->flag & CHILDOF_LOCY)) loc[1]= loco[1]= 0.0f;
796 if (!(data->flag & CHILDOF_LOCZ)) loc[2]= loco[2]= 0.0f;
797 if (!(data->flag & CHILDOF_ROTX)) eul[0]= eulo[0]= 0.0f;
798 if (!(data->flag & CHILDOF_ROTY)) eul[1]= eulo[1]= 0.0f;
799 if (!(data->flag & CHILDOF_ROTZ)) eul[2]= eulo[2]= 0.0f;
800 if (!(data->flag & CHILDOF_SIZEX)) size[0]= sizo[0]= 1.0f;
801 if (!(data->flag & CHILDOF_SIZEY)) size[1]= sizo[1]= 1.0f;
802 if (!(data->flag & CHILDOF_SIZEZ)) size[2]= sizo[2]= 1.0f;
804 /* make new target mat and offset mat */
805 LocEulSizeToMat4(ct->matrix, loc, eul, size);
806 LocEulSizeToMat4(invmat, loco, eulo, sizo);
808 /* multiply target (parent matrix) by offset (parent inverse) to get
809 * the effect of the parent that will be exherted on the owner
811 Mat4MulMat4(parmat, invmat, ct->matrix);
813 /* now multiply the parent matrix by the owner matrix to get the
814 * the effect of this constraint (i.e. owner is 'parented' to parent)
816 Mat4CpyMat4(tempmat, cob->matrix);
817 Mat4MulMat4(cob->matrix, tempmat, parmat);
821 static bConstraintTypeInfo CTI_CHILDOF = {
822 CONSTRAINT_TYPE_CHILDOF, /* type */
823 sizeof(bChildOfConstraint), /* size */
824 "ChildOf", /* name */
825 "bChildOfConstraint", /* struct name */
826 NULL, /* free data */
827 NULL, /* relink data */
828 NULL, /* copy data */
829 childof_new_data, /* new data */
830 childof_get_tars, /* get constraint targets */
831 childof_flush_tars, /* flush constraint targets */
832 default_get_tarmat, /* get a target matrix */
833 childof_evaluate /* evaluate */
836 /* -------- TrackTo Constraint ------- */
838 static void trackto_new_data (void *cdata)
840 bTrackToConstraint *data= (bTrackToConstraint *)cdata;
842 data->reserved1 = TRACK_Y;
843 data->reserved2 = UP_Z;
846 static int trackto_get_tars (bConstraint *con, ListBase *list)
849 bTrackToConstraint *data= con->data;
850 bConstraintTarget *ct;
852 /* standard target-getting macro for single-target constraints */
853 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
861 static void trackto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
864 bTrackToConstraint *data= con->data;
865 bConstraintTarget *ct= list->first;
867 /* the following macro is used for all standard single-target constraints */
868 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
873 static int basis_cross (int n, int m)
889 static void vectomat (float *vec, float *target_up, short axis, short upflag, short flags, float m[][3])
892 float u[3]; /* vector specifying the up axis */
899 if (Normalize(n) == 0.0) {
904 if (axis > 2) axis -= 3;
907 /* n specifies the transformation of the track axis */
908 if (flags & TARGET_Z_UP) {
909 /* target Z axis is the global up axis */
915 /* world Z axis is the global up axis */
921 /* project the up vector onto the plane specified by n */
922 Projf(proj, u, n); /* first u onto n... */
923 VecSubf(proj, u, proj); /* then onto the plane */
924 /* proj specifies the transformation of the up axis */
926 if (Normalize(proj) == 0.0) { /* degenerate projection */
932 /* Normalized cross product of n and proj specifies transformation of the right axis */
933 Crossf(right, proj, n);
936 if (axis != upflag) {
937 right_index = 3 - axis - upflag;
938 neg = (float)basis_cross(axis, upflag);
940 /* account for up direction, track direction */
941 m[right_index][0] = neg * right[0];
942 m[right_index][1] = neg * right[1];
943 m[right_index][2] = neg * right[2];
945 m[upflag][0] = proj[0];
946 m[upflag][1] = proj[1];
947 m[upflag][2] = proj[2];
953 /* identity matrix - don't do anything if the two axes are the same */
955 m[0][0]= m[1][1]= m[2][2]= 1.0;
956 m[0][1]= m[0][2]= 0.0;
957 m[1][0]= m[1][2]= 0.0;
958 m[2][0]= m[2][1]= 0.0;
963 static void trackto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
965 bTrackToConstraint *data= con->data;
966 bConstraintTarget *ct= targets->first;
968 if (VALID_CONS_TARGET(ct)) {
969 float size[3], vec[3];
973 /* Get size property, since ob->size is only the object's own relative size, not its global one */
974 Mat4ToSize(cob->matrix, size);
976 /* Clear the object's rotation */
977 cob->matrix[0][0]=size[0];
981 cob->matrix[1][1]=size[1];
985 cob->matrix[2][2]=size[2];
987 /* targetmat[2] instead of ownermat[2] is passed to vectomat
988 * for backwards compatability it seems... (Aligorith)
990 VecSubf(vec, cob->matrix[3], ct->matrix[3]);
991 vectomat(vec, ct->matrix[2],
992 (short)data->reserved1, (short)data->reserved2,
993 data->flags, totmat);
995 Mat4CpyMat4(tmat, cob->matrix);
996 Mat4MulMat34(cob->matrix, totmat, tmat);
1000 static bConstraintTypeInfo CTI_TRACKTO = {
1001 CONSTRAINT_TYPE_TRACKTO, /* type */
1002 sizeof(bTrackToConstraint), /* size */
1003 "TrackTo", /* name */
1004 "bTrackToConstraint", /* struct name */
1005 NULL, /* free data */
1006 NULL, /* relink data */
1007 NULL, /* copy data */
1008 trackto_new_data, /* new data */
1009 trackto_get_tars, /* get constraint targets */
1010 trackto_flush_tars, /* flush constraint targets */
1011 default_get_tarmat, /* get target matrix */
1012 trackto_evaluate /* evaluate */
1015 /* --------- Inverse-Kinemetics --------- */
1017 static void kinematic_new_data (void *cdata)
1019 bKinematicConstraint *data= (bKinematicConstraint *)cdata;
1021 data->weight= (float)1.0;
1022 data->orientweight= (float)1.0;
1023 data->iterations = 500;
1024 data->flag= CONSTRAINT_IK_TIP|CONSTRAINT_IK_STRETCH|CONSTRAINT_IK_POS;
1027 static int kinematic_get_tars (bConstraint *con, ListBase *list)
1030 bKinematicConstraint *data= con->data;
1031 bConstraintTarget *ct;
1033 /* standard target-getting macro for single-target constraints is used twice here */
1034 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
1035 SINGLETARGET_GET_TARS(con, data->poletar, data->polesubtarget, ct, list)
1043 static void kinematic_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1046 bKinematicConstraint *data= con->data;
1047 bConstraintTarget *ct= list->first;
1049 /* the following macro is used for all standard single-target constraints */
1050 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
1051 SINGLETARGET_FLUSH_TARS(con, data->poletar, data->polesubtarget, ct, list, nocopy)
1055 static void kinematic_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
1057 bKinematicConstraint *data= con->data;
1059 if (VALID_CONS_TARGET(ct))
1060 constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
1062 if (data->flag & CONSTRAINT_IK_AUTO) {
1063 Object *ob= cob->ob;
1066 Mat4One(ct->matrix);
1070 /* move grabtarget into world space */
1071 VECCOPY(vec, data->grabtarget);
1072 Mat4MulVecfl(ob->obmat, vec);
1073 Mat4CpyMat4(ct->matrix, ob->obmat);
1074 VECCOPY(ct->matrix[3], vec);
1078 Mat4One(ct->matrix);
1082 static bConstraintTypeInfo CTI_KINEMATIC = {
1083 CONSTRAINT_TYPE_KINEMATIC, /* type */
1084 sizeof(bKinematicConstraint), /* size */
1086 "bKinematicConstraint", /* struct name */
1087 NULL, /* free data */
1088 NULL, /* relink data */
1089 NULL, /* copy data */
1090 kinematic_new_data, /* new data */
1091 kinematic_get_tars, /* get constraint targets */
1092 kinematic_flush_tars, /* flush constraint targets */
1093 kinematic_get_tarmat, /* get target matrix */
1094 NULL /* evaluate - solved as separate loop */
1097 /* -------- Follow-Path Constraint ---------- */
1099 static void followpath_new_data (void *cdata)
1101 bFollowPathConstraint *data= (bFollowPathConstraint *)cdata;
1103 data->trackflag = TRACK_Y;
1104 data->upflag = UP_Z;
1106 data->followflag = 0;
1109 static int followpath_get_tars (bConstraint *con, ListBase *list)
1112 bFollowPathConstraint *data= con->data;
1113 bConstraintTarget *ct;
1115 /* standard target-getting macro for single-target constraints without subtargets */
1116 SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
1124 static void followpath_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1127 bFollowPathConstraint *data= con->data;
1128 bConstraintTarget *ct= list->first;
1130 /* the following macro is used for all standard single-target constraints */
1131 SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy)
1135 static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
1137 bFollowPathConstraint *data= con->data;
1139 if (VALID_CONS_TARGET(ct)) {
1140 Curve *cu= ct->tar->data;
1141 float q[4], vec[4], dir[3], quat[4], x1;
1146 Mat4One(ct->matrix);
1148 /* note: when creating constraints that follow path, the curve gets the CU_PATH set now,
1149 * currently for paths to work it needs to go through the bevlist/displist system (ton)
1152 /* only happens on reload file, but violates depsgraph still... fix! */
1153 if (cu->path==NULL || cu->path->data==NULL)
1154 makeDispListCurveTypes(cob->scene, ct->tar, 0);
1156 if (cu->path && cu->path->data) {
1157 curvetime= bsystem_time(cob->scene, ct->tar, (float)ctime, 0.0) - data->offset;
1159 #if 0 // XXX old animation system
1160 if (calc_ipo_spec(cu->ipo, CU_SPEED, &curvetime)==0) {
1161 curvetime /= cu->pathlen;
1162 CLAMP(curvetime, 0.0, 1.0);
1164 #endif // XXX old animation system
1166 if ( where_on_path(ct->tar, curvetime, vec, dir) ) {
1167 if (data->followflag) {
1168 vectoquat(dir, (short) data->trackflag, (short) data->upflag, quat);
1171 q[0]= (float)cos(0.5*vec[3]);
1172 x1= (float)sin(0.5*vec[3]);
1176 QuatMul(quat, q, quat);
1178 QuatToMat4(quat, totmat);
1180 VECCOPY(totmat[3], vec);
1182 Mat4MulSerie(ct->matrix, ct->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL);
1187 Mat4One(ct->matrix);
1190 static void followpath_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1192 bConstraintTarget *ct= targets->first;
1194 /* only evaluate if there is a target */
1195 if (VALID_CONS_TARGET(ct)) {
1197 float size[3], obsize[3];
1199 /* get Object local transform (loc/rot/size) to determine transformation from path */
1200 //object_to_mat4(ob, obmat);
1201 Mat4CpyMat4(obmat, cob->matrix); // FIXME!!!
1203 /* get scaling of object before applying constraint */
1204 Mat4ToSize(cob->matrix, size);
1206 /* apply targetmat - containing location on path, and rotation */
1207 Mat4MulSerie(cob->matrix, ct->matrix, obmat, NULL, NULL, NULL, NULL, NULL, NULL);
1209 /* un-apply scaling caused by path */
1210 Mat4ToSize(cob->matrix, obsize);
1212 VecMulf(cob->matrix[0], size[0] / obsize[0]);
1214 VecMulf(cob->matrix[1], size[1] / obsize[1]);
1216 VecMulf(cob->matrix[2], size[2] / obsize[2]);
1220 static bConstraintTypeInfo CTI_FOLLOWPATH = {
1221 CONSTRAINT_TYPE_FOLLOWPATH, /* type */
1222 sizeof(bFollowPathConstraint), /* size */
1223 "Follow Path", /* name */
1224 "bFollowPathConstraint", /* struct name */
1225 NULL, /* free data */
1226 NULL, /* relink data */
1227 NULL, /* copy data */
1228 followpath_new_data, /* new data */
1229 followpath_get_tars, /* get constraint targets */
1230 followpath_flush_tars, /* flush constraint targets */
1231 followpath_get_tarmat, /* get target matrix */
1232 followpath_evaluate /* evaluate */
1235 /* --------- Limit Location --------- */
1238 static void loclimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1240 bLocLimitConstraint *data = con->data;
1242 if (data->flag & LIMIT_XMIN) {
1243 if (cob->matrix[3][0] < data->xmin)
1244 cob->matrix[3][0] = data->xmin;
1246 if (data->flag & LIMIT_XMAX) {
1247 if (cob->matrix[3][0] > data->xmax)
1248 cob->matrix[3][0] = data->xmax;
1250 if (data->flag & LIMIT_YMIN) {
1251 if (cob->matrix[3][1] < data->ymin)
1252 cob->matrix[3][1] = data->ymin;
1254 if (data->flag & LIMIT_YMAX) {
1255 if (cob->matrix[3][1] > data->ymax)
1256 cob->matrix[3][1] = data->ymax;
1258 if (data->flag & LIMIT_ZMIN) {
1259 if (cob->matrix[3][2] < data->zmin)
1260 cob->matrix[3][2] = data->zmin;
1262 if (data->flag & LIMIT_ZMAX) {
1263 if (cob->matrix[3][2] > data->zmax)
1264 cob->matrix[3][2] = data->zmax;
1268 static bConstraintTypeInfo CTI_LOCLIMIT = {
1269 CONSTRAINT_TYPE_LOCLIMIT, /* type */
1270 sizeof(bLocLimitConstraint), /* size */
1271 "Limit Location", /* name */
1272 "bLocLimitConstraint", /* struct name */
1273 NULL, /* free data */
1274 NULL, /* relink data */
1275 NULL, /* copy data */
1276 NULL, /* new data */
1277 NULL, /* get constraint targets */
1278 NULL, /* flush constraint targets */
1279 NULL, /* get target matrix */
1280 loclimit_evaluate /* evaluate */
1283 /* -------- Limit Rotation --------- */
1285 static void rotlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1287 bRotLimitConstraint *data = con->data;
1292 VECCOPY(loc, cob->matrix[3]);
1293 Mat4ToSize(cob->matrix, size);
1295 Mat4ToEul(cob->matrix, eul);
1297 /* eulers: radians to degrees! */
1298 eul[0] = (float)(eul[0] / M_PI * 180);
1299 eul[1] = (float)(eul[1] / M_PI * 180);
1300 eul[2] = (float)(eul[2] / M_PI * 180);
1302 /* limiting of euler values... */
1303 if (data->flag & LIMIT_XROT) {
1304 if (eul[0] < data->xmin)
1305 eul[0] = data->xmin;
1307 if (eul[0] > data->xmax)
1308 eul[0] = data->xmax;
1310 if (data->flag & LIMIT_YROT) {
1311 if (eul[1] < data->ymin)
1312 eul[1] = data->ymin;
1314 if (eul[1] > data->ymax)
1315 eul[1] = data->ymax;
1317 if (data->flag & LIMIT_ZROT) {
1318 if (eul[2] < data->zmin)
1319 eul[2] = data->zmin;
1321 if (eul[2] > data->zmax)
1322 eul[2] = data->zmax;
1325 /* eulers: degrees to radians ! */
1326 eul[0] = (float)(eul[0] / 180 * M_PI);
1327 eul[1] = (float)(eul[1] / 180 * M_PI);
1328 eul[2] = (float)(eul[2] / 180 * M_PI);
1330 LocEulSizeToMat4(cob->matrix, loc, eul, size);
1333 static bConstraintTypeInfo CTI_ROTLIMIT = {
1334 CONSTRAINT_TYPE_ROTLIMIT, /* type */
1335 sizeof(bRotLimitConstraint), /* size */
1336 "Limit Rotation", /* name */
1337 "bRotLimitConstraint", /* struct name */
1338 NULL, /* free data */
1339 NULL, /* relink data */
1340 NULL, /* copy data */
1341 NULL, /* new data */
1342 NULL, /* get constraint targets */
1343 NULL, /* flush constraint targets */
1344 NULL, /* get target matrix */
1345 rotlimit_evaluate /* evaluate */
1348 /* --------- Limit Scaling --------- */
1351 static void sizelimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1353 bSizeLimitConstraint *data = con->data;
1354 float obsize[3], size[3];
1356 Mat4ToSize(cob->matrix, size);
1357 Mat4ToSize(cob->matrix, obsize);
1359 if (data->flag & LIMIT_XMIN) {
1360 if (size[0] < data->xmin)
1361 size[0] = data->xmin;
1363 if (data->flag & LIMIT_XMAX) {
1364 if (size[0] > data->xmax)
1365 size[0] = data->xmax;
1367 if (data->flag & LIMIT_YMIN) {
1368 if (size[1] < data->ymin)
1369 size[1] = data->ymin;
1371 if (data->flag & LIMIT_YMAX) {
1372 if (size[1] > data->ymax)
1373 size[1] = data->ymax;
1375 if (data->flag & LIMIT_ZMIN) {
1376 if (size[2] < data->zmin)
1377 size[2] = data->zmin;
1379 if (data->flag & LIMIT_ZMAX) {
1380 if (size[2] > data->zmax)
1381 size[2] = data->zmax;
1385 VecMulf(cob->matrix[0], size[0]/obsize[0]);
1387 VecMulf(cob->matrix[1], size[1]/obsize[1]);
1389 VecMulf(cob->matrix[2], size[2]/obsize[2]);
1392 static bConstraintTypeInfo CTI_SIZELIMIT = {
1393 CONSTRAINT_TYPE_SIZELIMIT, /* type */
1394 sizeof(bSizeLimitConstraint), /* size */
1395 "Limit Scaling", /* name */
1396 "bSizeLimitConstraint", /* struct name */
1397 NULL, /* free data */
1398 NULL, /* relink data */
1399 NULL, /* copy data */
1400 NULL, /* new data */
1401 NULL, /* get constraint targets */
1402 NULL, /* flush constraint targets */
1403 NULL, /* get target matrix */
1404 sizelimit_evaluate /* evaluate */
1407 /* ----------- Copy Location ------------- */
1409 static void loclike_new_data (void *cdata)
1411 bLocateLikeConstraint *data= (bLocateLikeConstraint *)cdata;
1413 data->flag = LOCLIKE_X|LOCLIKE_Y|LOCLIKE_Z;
1416 static int loclike_get_tars (bConstraint *con, ListBase *list)
1419 bLocateLikeConstraint *data= con->data;
1420 bConstraintTarget *ct;
1422 /* standard target-getting macro for single-target constraints */
1423 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
1431 static void loclike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1434 bLocateLikeConstraint *data= con->data;
1435 bConstraintTarget *ct= list->first;
1437 /* the following macro is used for all standard single-target constraints */
1438 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
1442 static void loclike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1444 bLocateLikeConstraint *data= con->data;
1445 bConstraintTarget *ct= targets->first;
1447 if (VALID_CONS_TARGET(ct)) {
1448 float offset[3] = {0.0f, 0.0f, 0.0f};
1450 if (data->flag & LOCLIKE_OFFSET)
1451 VECCOPY(offset, cob->matrix[3]);
1453 if (data->flag & LOCLIKE_X) {
1454 cob->matrix[3][0] = ct->matrix[3][0];
1456 if (data->flag & LOCLIKE_X_INVERT) cob->matrix[3][0] *= -1;
1457 cob->matrix[3][0] += offset[0];
1459 if (data->flag & LOCLIKE_Y) {
1460 cob->matrix[3][1] = ct->matrix[3][1];
1462 if (data->flag & LOCLIKE_Y_INVERT) cob->matrix[3][1] *= -1;
1463 cob->matrix[3][1] += offset[1];
1465 if (data->flag & LOCLIKE_Z) {
1466 cob->matrix[3][2] = ct->matrix[3][2];
1468 if (data->flag & LOCLIKE_Z_INVERT) cob->matrix[3][2] *= -1;
1469 cob->matrix[3][2] += offset[2];
1474 static bConstraintTypeInfo CTI_LOCLIKE = {
1475 CONSTRAINT_TYPE_LOCLIKE, /* type */
1476 sizeof(bLocateLikeConstraint), /* size */
1477 "Copy Location", /* name */
1478 "bLocateLikeConstraint", /* struct name */
1479 NULL, /* free data */
1480 NULL, /* relink data */
1481 NULL, /* copy data */
1482 loclike_new_data, /* new data */
1483 loclike_get_tars, /* get constraint targets */
1484 loclike_flush_tars, /* flush constraint targets */
1485 default_get_tarmat, /* get target matrix */
1486 loclike_evaluate /* evaluate */
1489 /* ----------- Copy Rotation ------------- */
1491 static void rotlike_new_data (void *cdata)
1493 bRotateLikeConstraint *data= (bRotateLikeConstraint *)cdata;
1495 data->flag = ROTLIKE_X|ROTLIKE_Y|ROTLIKE_Z;
1498 static int rotlike_get_tars (bConstraint *con, ListBase *list)
1501 bRotateLikeConstraint *data= con->data;
1502 bConstraintTarget *ct;
1504 /* standard target-getting macro for single-target constraints */
1505 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
1513 static void rotlike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1516 bRotateLikeConstraint *data= con->data;
1517 bConstraintTarget *ct= list->first;
1519 /* the following macro is used for all standard single-target constraints */
1520 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
1524 static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1526 bRotateLikeConstraint *data= con->data;
1527 bConstraintTarget *ct= targets->first;
1529 if (VALID_CONS_TARGET(ct)) {
1531 float eul[3], obeul[3];
1534 VECCOPY(loc, cob->matrix[3]);
1535 Mat4ToSize(cob->matrix, size);
1537 Mat4ToEul(ct->matrix, eul);
1538 Mat4ToEul(cob->matrix, obeul);
1540 if ((data->flag & ROTLIKE_X)==0)
1543 if (data->flag & ROTLIKE_OFFSET)
1544 euler_rot(eul, obeul[0], 'x');
1546 if (data->flag & ROTLIKE_X_INVERT)
1550 if ((data->flag & ROTLIKE_Y)==0)
1553 if (data->flag & ROTLIKE_OFFSET)
1554 euler_rot(eul, obeul[1], 'y');
1556 if (data->flag & ROTLIKE_Y_INVERT)
1560 if ((data->flag & ROTLIKE_Z)==0)
1563 if (data->flag & ROTLIKE_OFFSET)
1564 euler_rot(eul, obeul[2], 'z');
1566 if (data->flag & ROTLIKE_Z_INVERT)
1570 compatible_eul(eul, obeul);
1571 LocEulSizeToMat4(cob->matrix, loc, eul, size);
1575 static bConstraintTypeInfo CTI_ROTLIKE = {
1576 CONSTRAINT_TYPE_ROTLIKE, /* type */
1577 sizeof(bRotateLikeConstraint), /* size */
1578 "Copy Rotation", /* name */
1579 "bRotateLikeConstraint", /* struct name */
1580 NULL, /* free data */
1581 NULL, /* relink data */
1582 NULL, /* copy data */
1583 rotlike_new_data, /* new data */
1584 rotlike_get_tars, /* get constraint targets */
1585 rotlike_flush_tars, /* flush constraint targets */
1586 default_get_tarmat, /* get target matrix */
1587 rotlike_evaluate /* evaluate */
1590 /* ---------- Copy Scaling ---------- */
1592 static void sizelike_new_data (void *cdata)
1594 bSizeLikeConstraint *data= (bSizeLikeConstraint *)cdata;
1596 data->flag = SIZELIKE_X|SIZELIKE_Y|SIZELIKE_Z;
1599 static int sizelike_get_tars (bConstraint *con, ListBase *list)
1602 bSizeLikeConstraint *data= con->data;
1603 bConstraintTarget *ct;
1605 /* standard target-getting macro for single-target constraints */
1606 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
1614 static void sizelike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1617 bSizeLikeConstraint *data= con->data;
1618 bConstraintTarget *ct= list->first;
1620 /* the following macro is used for all standard single-target constraints */
1621 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
1625 static void sizelike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1627 bSizeLikeConstraint *data= con->data;
1628 bConstraintTarget *ct= targets->first;
1630 if (VALID_CONS_TARGET(ct)) {
1631 float obsize[3], size[3];
1633 Mat4ToSize(ct->matrix, size);
1634 Mat4ToSize(cob->matrix, obsize);
1636 if ((data->flag & SIZELIKE_X) && (obsize[0] != 0)) {
1637 if (data->flag & SIZELIKE_OFFSET) {
1638 size[0] += (obsize[0] - 1.0f);
1639 VecMulf(cob->matrix[0], size[0] / obsize[0]);
1642 VecMulf(cob->matrix[0], size[0] / obsize[0]);
1644 if ((data->flag & SIZELIKE_Y) && (obsize[1] != 0)) {
1645 if (data->flag & SIZELIKE_OFFSET) {
1646 size[1] += (obsize[1] - 1.0f);
1647 VecMulf(cob->matrix[1], size[1] / obsize[1]);
1650 VecMulf(cob->matrix[1], size[1] / obsize[1]);
1652 if ((data->flag & SIZELIKE_Z) && (obsize[2] != 0)) {
1653 if (data->flag & SIZELIKE_OFFSET) {
1654 size[2] += (obsize[2] - 1.0f);
1655 VecMulf(cob->matrix[2], size[2] / obsize[2]);
1658 VecMulf(cob->matrix[2], size[2] / obsize[2]);
1663 static bConstraintTypeInfo CTI_SIZELIKE = {
1664 CONSTRAINT_TYPE_SIZELIKE, /* type */
1665 sizeof(bSizeLikeConstraint), /* size */
1666 "Copy Scale", /* name */
1667 "bSizeLikeConstraint", /* struct name */
1668 NULL, /* free data */
1669 NULL, /* relink data */
1670 NULL, /* copy data */
1671 sizelike_new_data, /* new data */
1672 sizelike_get_tars, /* get constraint targets */
1673 sizelike_flush_tars, /* flush constraint targets */
1674 default_get_tarmat, /* get target matrix */
1675 sizelike_evaluate /* evaluate */
1679 /* ----------- Python Constraint -------------- */
1681 static void pycon_free (bConstraint *con)
1683 bPythonConstraint *data= con->data;
1686 IDP_FreeProperty(data->prop);
1687 MEM_freeN(data->prop);
1689 /* multiple targets */
1690 BLI_freelistN(&data->targets);
1693 static void pycon_relink (bConstraint *con)
1695 bPythonConstraint *data= con->data;
1700 static void pycon_copy (bConstraint *con, bConstraint *srccon)
1702 bPythonConstraint *pycon = (bPythonConstraint *)con->data;
1703 bPythonConstraint *opycon = (bPythonConstraint *)srccon->data;
1705 pycon->prop = IDP_CopyProperty(opycon->prop);
1706 BLI_duplicatelist(&pycon->targets, &opycon->targets);
1709 static void pycon_new_data (void *cdata)
1711 bPythonConstraint *data= (bPythonConstraint *)cdata;
1713 /* everything should be set correctly by calloc, except for the prop->type constant.*/
1714 data->prop = MEM_callocN(sizeof(IDProperty), "PyConstraintProps");
1715 data->prop->type = IDP_GROUP;
1718 static int pycon_get_tars (bConstraint *con, ListBase *list)
1721 bPythonConstraint *data= con->data;
1723 list->first = data->targets.first;
1724 list->last = data->targets.last;
1726 return data->tarnum;
1732 /* Whether this approach is maintained remains to be seen (aligorith) */
1733 static void pycon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
1735 bPythonConstraint *data= con->data;
1737 if (VALID_CONS_TARGET(ct)) {
1738 /* special exception for curves - depsgraph issues */
1739 if (ct->tar->type == OB_CURVE) {
1740 Curve *cu= ct->tar->data;
1742 /* this check is to make sure curve objects get updated on file load correctly.*/
1743 if (cu->path==NULL || cu->path->data==NULL) /* only happens on reload file, but violates depsgraph still... fix! */
1744 makeDispListCurveTypes(cob->scene, ct->tar, 0);
1747 /* firstly calculate the matrix the normal way, then let the py-function override
1748 * this matrix if it needs to do so
1750 constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
1752 /* only execute target calculation if allowed */
1753 #ifndef DISABLE_PYTHON
1754 if (G.f & G_DOSCRIPTLINKS)
1755 BPY_pyconstraint_target(data, ct);
1759 Mat4One(ct->matrix);
1762 static void pycon_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1764 #ifdef DISABLE_PYTHON
1767 bPythonConstraint *data= con->data;
1769 /* only evaluate in python if we're allowed to do so */
1770 if ((G.f & G_DOSCRIPTLINKS)==0) return;
1772 /* currently removed, until I this can be re-implemented for multiple targets */
1774 /* Firstly, run the 'driver' function which has direct access to the objects involved
1775 * Technically, this is potentially dangerous as users may abuse this and cause dependency-problems,
1776 * but it also allows certain 'clever' rigging hacks to work.
1778 BPY_pyconstraint_driver(data, cob, targets);
1781 /* Now, run the actual 'constraint' function, which should only access the matrices */
1782 BPY_pyconstraint_eval(data, cob, targets);
1783 #endif /* DISABLE_PYTHON */
1786 static bConstraintTypeInfo CTI_PYTHON = {
1787 CONSTRAINT_TYPE_PYTHON, /* type */
1788 sizeof(bPythonConstraint), /* size */
1789 "Script", /* name */
1790 "bPythonConstraint", /* struct name */
1791 pycon_free, /* free data */
1792 pycon_relink, /* relink data */
1793 pycon_copy, /* copy data */
1794 pycon_new_data, /* new data */
1795 pycon_get_tars, /* get constraint targets */
1796 NULL, /* flush constraint targets */
1797 pycon_get_tarmat, /* get target matrix */
1798 pycon_evaluate /* evaluate */
1801 /* -------- Action Constraint ----------- */
1803 static void actcon_relink (bConstraint *con)
1805 bActionConstraint *data= con->data;
1809 static void actcon_new_data (void *cdata)
1811 bActionConstraint *data= (bActionConstraint *)cdata;
1813 /* set type to 20 (Loc X), as 0 is Rot X for backwards compatability */
1817 static int actcon_get_tars (bConstraint *con, ListBase *list)
1820 bActionConstraint *data= con->data;
1821 bConstraintTarget *ct;
1823 /* standard target-getting macro for single-target constraints */
1824 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
1832 static void actcon_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1835 bActionConstraint *data= con->data;
1836 bConstraintTarget *ct= list->first;
1838 /* the following macro is used for all standard single-target constraints */
1839 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
1843 static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
1845 extern void chan_calc_mat(bPoseChannel *chan);
1846 bActionConstraint *data = con->data;
1848 if (VALID_CONS_TARGET(ct)) {
1849 float tempmat[4][4], vec[3];
1853 /* initialise return matrix */
1854 Mat4One(ct->matrix);
1856 /* get the transform matrix of the target */
1857 constraint_target_to_mat4(ct->tar, ct->subtarget, tempmat, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
1859 /* determine where in transform range target is */
1860 /* data->type is mapped as follows for backwards compatability:
1861 * 00,01,02 - rotation (it used to be like this)
1862 * 10,11,12 - scaling
1863 * 20,21,22 - location
1865 if (data->type < 10) {
1866 /* extract rotation (is in whatever space target should be in) */
1867 Mat4ToEul(tempmat, vec);
1868 vec[0] *= (float)(180.0/M_PI);
1869 vec[1] *= (float)(180.0/M_PI);
1870 vec[2] *= (float)(180.0/M_PI);
1873 else if (data->type < 20) {
1874 /* extract scaling (is in whatever space target should be in) */
1875 Mat4ToSize(tempmat, vec);
1876 axis= data->type - 10;
1879 /* extract location */
1880 VECCOPY(vec, tempmat[3]);
1881 axis= data->type - 20;
1884 /* Target defines the animation */
1885 s = (vec[axis]-data->min) / (data->max-data->min);
1887 t = ( s * (data->end-data->start)) + data->start;
1890 printf("do Action Constraint %s - Ob %s Pchan %s \n", con->name, cob->ob->id.name+2, (cob->pchan)?cob->pchan->name:NULL);
1892 /* Get the appropriate information from the action */
1893 // XXX probably we might need some special filtering methods to make this more efficient
1894 if (cob->type == CONSTRAINT_OBTYPE_BONE) {
1897 bPoseChannel *pchan, *tchan;
1899 /* make a temporary pose and evaluate using that */
1900 pose = MEM_callocN(sizeof(bPose), "pose");
1902 /* make a copy of the bone of interest in the temp pose before evaluating action, so that it can get set */
1904 tchan= verify_pose_channel(pose, pchan->name);
1906 /* evaluate action using workob (it will only set the PoseChannel in question) */
1907 // XXX we need some flags to prevent evaluation from setting disabled flags on all other settings
1908 what_does_obaction(cob->scene, cob->ob, &workob, pose, data->act, t);
1910 /* convert animation to matrices for use here */
1911 chan_calc_mat(tchan);
1912 Mat4CpyMat4(ct->matrix, tchan->chan_mat);
1917 else if (cob->type == CONSTRAINT_OBTYPE_OBJECT) {
1920 /* evaluate using workob */
1921 what_does_obaction(cob->scene, cob->ob, &workob, NULL, data->act, t);
1922 object_to_mat4(&workob, ct->matrix);
1925 /* behaviour undefined... */
1926 puts("Error: unknown owner type for Action Constraint");
1931 static void actcon_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1933 bConstraintTarget *ct= targets->first;
1935 if (VALID_CONS_TARGET(ct)) {
1938 /* Nice and simple... we just need to multiply the matrices, as the get_target_matrix
1939 * function has already taken care of everything else.
1941 Mat4CpyMat4(temp, cob->matrix);
1942 Mat4MulMat4(cob->matrix, ct->matrix, temp);
1946 static bConstraintTypeInfo CTI_ACTION = {
1947 CONSTRAINT_TYPE_ACTION, /* type */
1948 sizeof(bActionConstraint), /* size */
1949 "Action", /* name */
1950 "bActionConstraint", /* struct name */
1951 NULL, /* free data */
1952 actcon_relink, /* relink data */
1953 NULL, /* copy data */
1954 actcon_new_data, /* new data */
1955 actcon_get_tars, /* get constraint targets */
1956 actcon_flush_tars, /* flush constraint targets */
1957 actcon_get_tarmat, /* get target matrix */
1958 actcon_evaluate /* evaluate */
1961 /* --------- Locked Track ---------- */
1963 static void locktrack_new_data (void *cdata)
1965 bLockTrackConstraint *data= (bLockTrackConstraint *)cdata;
1967 data->trackflag = TRACK_Y;
1968 data->lockflag = LOCK_Z;
1971 static int locktrack_get_tars (bConstraint *con, ListBase *list)
1974 bLockTrackConstraint *data= con->data;
1975 bConstraintTarget *ct;
1977 /* the following macro is used for all standard single-target constraints */
1978 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
1986 static void locktrack_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1989 bLockTrackConstraint *data= con->data;
1990 bConstraintTarget *ct= list->first;
1992 /* the following macro is used for all standard single-target constraints */
1993 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
1997 static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1999 bLockTrackConstraint *data= con->data;
2000 bConstraintTarget *ct= targets->first;
2002 if (VALID_CONS_TARGET(ct)) {
2003 float vec[3],vec2[3];
2010 /* Vector object -> target */
2011 VecSubf(vec, ct->matrix[3], cob->matrix[3]);
2012 switch (data->lockflag){
2013 case LOCK_X: /* LOCK X */
2015 switch (data->trackflag) {
2016 case TRACK_Y: /* LOCK X TRACK Y */
2018 /* Projection of Vector on the plane */
2019 Projf(vec2, vec, cob->matrix[0]);
2020 VecSubf(totmat[1], vec, vec2);
2021 Normalize(totmat[1]);
2023 /* the x axis is fixed */
2024 totmat[0][0] = cob->matrix[0][0];
2025 totmat[0][1] = cob->matrix[0][1];
2026 totmat[0][2] = cob->matrix[0][2];
2027 Normalize(totmat[0]);
2029 /* the z axis gets mapped onto a third orthogonal vector */
2030 Crossf(totmat[2], totmat[0], totmat[1]);
2033 case TRACK_Z: /* LOCK X TRACK Z */
2035 /* Projection of Vector on the plane */
2036 Projf(vec2, vec, cob->matrix[0]);
2037 VecSubf(totmat[2], vec, vec2);
2038 Normalize(totmat[2]);
2040 /* the x axis is fixed */
2041 totmat[0][0] = cob->matrix[0][0];
2042 totmat[0][1] = cob->matrix[0][1];
2043 totmat[0][2] = cob->matrix[0][2];
2044 Normalize(totmat[0]);
2046 /* the z axis gets mapped onto a third orthogonal vector */
2047 Crossf(totmat[1], totmat[2], totmat[0]);
2050 case TRACK_nY: /* LOCK X TRACK -Y */
2052 /* Projection of Vector on the plane */
2053 Projf(vec2, vec, cob->matrix[0]);
2054 VecSubf(totmat[1], vec, vec2);
2055 Normalize(totmat[1]);
2058 /* the x axis is fixed */
2059 totmat[0][0] = cob->matrix[0][0];
2060 totmat[0][1] = cob->matrix[0][1];
2061 totmat[0][2] = cob->matrix[0][2];
2062 Normalize(totmat[0]);
2064 /* the z axis gets mapped onto a third orthogonal vector */
2065 Crossf(totmat[2], totmat[0], totmat[1]);
2068 case TRACK_nZ: /* LOCK X TRACK -Z */
2070 /* Projection of Vector on the plane */
2071 Projf(vec2, vec, cob->matrix[0]);
2072 VecSubf(totmat[2], vec, vec2);
2073 Normalize(totmat[2]);
2076 /* the x axis is fixed */
2077 totmat[0][0] = cob->matrix[0][0];
2078 totmat[0][1] = cob->matrix[0][1];
2079 totmat[0][2] = cob->matrix[0][2];
2080 Normalize(totmat[0]);
2082 /* the z axis gets mapped onto a third orthogonal vector */
2083 Crossf(totmat[1], totmat[2], totmat[0]);
2088 totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
2089 totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
2090 totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
2096 case LOCK_Y: /* LOCK Y */
2098 switch (data->trackflag) {
2099 case TRACK_X: /* LOCK Y TRACK X */
2101 /* Projection of Vector on the plane */
2102 Projf(vec2, vec, cob->matrix[1]);
2103 VecSubf(totmat[0], vec, vec2);
2104 Normalize(totmat[0]);
2106 /* the y axis is fixed */
2107 totmat[1][0] = cob->matrix[1][0];
2108 totmat[1][1] = cob->matrix[1][1];
2109 totmat[1][2] = cob->matrix[1][2];
2110 Normalize(totmat[1]);
2112 /* the z axis gets mapped onto a third orthogonal vector */
2113 Crossf(totmat[2], totmat[0], totmat[1]);
2116 case TRACK_Z: /* LOCK Y TRACK Z */
2118 /* Projection of Vector on the plane */
2119 Projf(vec2, vec, cob->matrix[1]);
2120 VecSubf(totmat[2], vec, vec2);
2121 Normalize(totmat[2]);
2123 /* the y axis is fixed */
2124 totmat[1][0] = cob->matrix[1][0];
2125 totmat[1][1] = cob->matrix[1][1];
2126 totmat[1][2] = cob->matrix[1][2];
2127 Normalize(totmat[1]);
2129 /* the z axis gets mapped onto a third orthogonal vector */
2130 Crossf(totmat[0], totmat[1], totmat[2]);
2133 case TRACK_nX: /* LOCK Y TRACK -X */
2135 /* Projection of Vector on the plane */
2136 Projf(vec2, vec, cob->matrix[1]);
2137 VecSubf(totmat[0], vec, vec2);
2138 Normalize(totmat[0]);
2141 /* the y axis is fixed */
2142 totmat[1][0] = cob->matrix[1][0];
2143 totmat[1][1] = cob->matrix[1][1];
2144 totmat[1][2] = cob->matrix[1][2];
2145 Normalize(totmat[1]);
2147 /* the z axis gets mapped onto a third orthogonal vector */
2148 Crossf(totmat[2], totmat[0], totmat[1]);
2151 case TRACK_nZ: /* LOCK Y TRACK -Z */
2153 /* Projection of Vector on the plane */
2154 Projf(vec2, vec, cob->matrix[1]);
2155 VecSubf(totmat[2], vec, vec2);
2156 Normalize(totmat[2]);
2159 /* the y axis is fixed */
2160 totmat[1][0] = cob->matrix[1][0];
2161 totmat[1][1] = cob->matrix[1][1];
2162 totmat[1][2] = cob->matrix[1][2];
2163 Normalize(totmat[1]);
2165 /* the z axis gets mapped onto a third orthogonal vector */
2166 Crossf(totmat[0], totmat[1], totmat[2]);
2171 totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
2172 totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
2173 totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
2179 case LOCK_Z: /* LOCK Z */
2181 switch (data->trackflag) {
2182 case TRACK_X: /* LOCK Z TRACK X */
2184 /* Projection of Vector on the plane */
2185 Projf(vec2, vec, cob->matrix[2]);
2186 VecSubf(totmat[0], vec, vec2);
2187 Normalize(totmat[0]);
2189 /* the z axis is fixed */
2190 totmat[2][0] = cob->matrix[2][0];
2191 totmat[2][1] = cob->matrix[2][1];
2192 totmat[2][2] = cob->matrix[2][2];
2193 Normalize(totmat[2]);
2195 /* the x axis gets mapped onto a third orthogonal vector */
2196 Crossf(totmat[1], totmat[2], totmat[0]);
2199 case TRACK_Y: /* LOCK Z TRACK Y */
2201 /* Projection of Vector on the plane */
2202 Projf(vec2, vec, cob->matrix[2]);
2203 VecSubf(totmat[1], vec, vec2);
2204 Normalize(totmat[1]);
2206 /* the z axis is fixed */
2207 totmat[2][0] = cob->matrix[2][0];
2208 totmat[2][1] = cob->matrix[2][1];
2209 totmat[2][2] = cob->matrix[2][2];
2210 Normalize(totmat[2]);
2212 /* the x axis gets mapped onto a third orthogonal vector */
2213 Crossf(totmat[0], totmat[1], totmat[2]);
2216 case TRACK_nX: /* LOCK Z TRACK -X */
2218 /* Projection of Vector on the plane */
2219 Projf(vec2, vec, cob->matrix[2]);
2220 VecSubf(totmat[0], vec, vec2);
2221 Normalize(totmat[0]);
2224 /* the z axis is fixed */
2225 totmat[2][0] = cob->matrix[2][0];
2226 totmat[2][1] = cob->matrix[2][1];
2227 totmat[2][2] = cob->matrix[2][2];
2228 Normalize(totmat[2]);
2230 /* the x axis gets mapped onto a third orthogonal vector */
2231 Crossf(totmat[1], totmat[2], totmat[0]);
2234 case TRACK_nY: /* LOCK Z TRACK -Y */
2236 /* Projection of Vector on the plane */
2237 Projf(vec2, vec, cob->matrix[2]);
2238 VecSubf(totmat[1], vec, vec2);
2239 Normalize(totmat[1]);
2242 /* the z axis is fixed */
2243 totmat[2][0] = cob->matrix[2][0];
2244 totmat[2][1] = cob->matrix[2][1];
2245 totmat[2][2] = cob->matrix[2][2];
2246 Normalize(totmat[2]);
2248 /* the x axis gets mapped onto a third orthogonal vector */
2249 Crossf(totmat[0], totmat[1], totmat[2]);
2254 totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
2255 totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
2256 totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
2264 totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
2265 totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
2266 totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
2270 /* Block to keep matrix heading */
2271 tmpmat[0][0] = cob->matrix[0][0];tmpmat[0][1] = cob->matrix[0][1];tmpmat[0][2] = cob->matrix[0][2];
2272 tmpmat[1][0] = cob->matrix[1][0];tmpmat[1][1] = cob->matrix[1][1];tmpmat[1][2] = cob->matrix[1][2];
2273 tmpmat[2][0] = cob->matrix[2][0];tmpmat[2][1] = cob->matrix[2][1];tmpmat[2][2] = cob->matrix[2][2];
2274 Normalize(tmpmat[0]);
2275 Normalize(tmpmat[1]);
2276 Normalize(tmpmat[2]);
2277 Mat3Inv(invmat, tmpmat);
2278 Mat3MulMat3(tmpmat, totmat, invmat);
2279 totmat[0][0] = tmpmat[0][0];totmat[0][1] = tmpmat[0][1];totmat[0][2] = tmpmat[0][2];
2280 totmat[1][0] = tmpmat[1][0];totmat[1][1] = tmpmat[1][1];totmat[1][2] = tmpmat[1][2];
2281 totmat[2][0] = tmpmat[2][0];totmat[2][1] = tmpmat[2][1];totmat[2][2] = tmpmat[2][2];
2283 Mat4CpyMat4(tmat, cob->matrix);
2285 mdet = Det3x3( totmat[0][0],totmat[0][1],totmat[0][2],
2286 totmat[1][0],totmat[1][1],totmat[1][2],
2287 totmat[2][0],totmat[2][1],totmat[2][2]);
2289 totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
2290 totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
2291 totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
2294 /* apply out transformaton to the object */
2295 Mat4MulMat34(cob->matrix, totmat, tmat);
2299 static bConstraintTypeInfo CTI_LOCKTRACK = {
2300 CONSTRAINT_TYPE_LOCKTRACK, /* type */
2301 sizeof(bLockTrackConstraint), /* size */
2302 "Locked Track", /* name */
2303 "bLockTrackConstraint", /* struct name */
2304 NULL, /* free data */
2305 NULL, /* relink data */
2306 NULL, /* copy data */
2307 locktrack_new_data, /* new data */
2308 locktrack_get_tars, /* get constraint targets */
2309 locktrack_flush_tars, /* flush constraint targets */
2310 default_get_tarmat, /* get target matrix */
2311 locktrack_evaluate /* evaluate */
2314 /* ---------- Limit Distance Constraint ----------- */
2316 static void distlimit_new_data (void *cdata)
2318 bDistLimitConstraint *data= (bDistLimitConstraint *)cdata;
2323 static int distlimit_get_tars (bConstraint *con, ListBase *list)
2326 bDistLimitConstraint *data= con->data;
2327 bConstraintTarget *ct;
2329 /* standard target-getting macro for single-target constraints */
2330 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
2338 static void distlimit_flush_tars (bConstraint *con, ListBase *list, short nocopy)
2341 bDistLimitConstraint *data= con->data;
2342 bConstraintTarget *ct= list->first;
2344 /* the following macro is used for all standard single-target constraints */
2345 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
2349 static void distlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
2351 bDistLimitConstraint *data= con->data;
2352 bConstraintTarget *ct= targets->first;
2354 /* only evaluate if there is a target */
2355 if (VALID_CONS_TARGET(ct)) {
2356 float dvec[3], dist=0.0f, sfac=1.0f;
2357 short clamp_surf= 0;
2359 /* calculate our current distance from the target */
2360 dist= VecLenf(cob->matrix[3], ct->matrix[3]);
2362 /* set distance (flag is only set when user demands it) */
2363 if (data->dist == 0)
2366 /* check if we're which way to clamp from, and calculate interpolation factor (if needed) */
2367 if (data->mode == LIMITDIST_OUTSIDE) {
2368 /* if inside, then move to surface */
2369 if (dist <= data->dist) {
2371 sfac= data->dist / dist;
2373 /* if soft-distance is enabled, start fading once owner is dist+softdist from the target */
2374 else if (data->flag & LIMITDIST_USESOFT) {
2375 if (dist <= (data->dist + data->soft)) {
2380 else if (data->mode == LIMITDIST_INSIDE) {
2381 /* if outside, then move to surface */
2382 if (dist >= data->dist) {
2384 sfac= data->dist / dist;
2386 /* if soft-distance is enabled, start fading once owner is dist-soft from the target */
2387 else if (data->flag & LIMITDIST_USESOFT) {
2388 // FIXME: there's a problem with "jumping" when this kicks in
2389 if (dist >= (data->dist - data->soft)) {
2390 sfac = (float)( data->soft*(1.0 - exp(-(dist - data->dist)/data->soft)) + data->dist );
2398 if (IS_EQ(dist, data->dist)==0) {
2400 sfac= data->dist / dist;
2404 /* clamp to 'surface' (i.e. move owner so that dist == data->dist) */
2406 /* simply interpolate along line formed by target -> owner */
2407 VecLerpf(dvec, ct->matrix[3], cob->matrix[3], sfac);
2409 /* copy new vector onto owner */
2410 VECCOPY(cob->matrix[3], dvec);
2415 static bConstraintTypeInfo CTI_DISTLIMIT = {
2416 CONSTRAINT_TYPE_DISTLIMIT, /* type */
2417 sizeof(bDistLimitConstraint), /* size */
2418 "Limit Distance", /* name */
2419 "bDistLimitConstraint", /* struct name */
2420 NULL, /* free data */
2421 NULL, /* relink data */
2422 NULL, /* copy data */
2423 distlimit_new_data, /* new data */
2424 distlimit_get_tars, /* get constraint targets */
2425 distlimit_flush_tars, /* flush constraint targets */
2426 default_get_tarmat, /* get a target matrix */
2427 distlimit_evaluate /* evaluate */
2430 /* ---------- Stretch To ------------ */
2432 static void stretchto_new_data (void *cdata)
2434 bStretchToConstraint *data= (bStretchToConstraint *)cdata;
2438 data->orglength = 0.0;
2442 static int stretchto_get_tars (bConstraint *con, ListBase *list)
2445 bStretchToConstraint *data= con->data;
2446 bConstraintTarget *ct;
2448 /* standard target-getting macro for single-target constraints */
2449 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
2457 static void stretchto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
2460 bStretchToConstraint *data= con->data;
2461 bConstraintTarget *ct= list->first;
2463 /* the following macro is used for all standard single-target constraints */
2464 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
2468 static void stretchto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
2470 bStretchToConstraint *data= con->data;
2471 bConstraintTarget *ct= targets->first;
2473 /* only evaluate if there is a target */
2474 if (VALID_CONS_TARGET(ct)) {
2475 float size[3], scale[3], vec[3], xx[3], zz[3], orth[3];
2480 /* store scaling before destroying obmat */
2481 Mat4ToSize(cob->matrix, size);
2483 /* store X orientation before destroying obmat */
2484 xx[0] = cob->matrix[0][0];
2485 xx[1] = cob->matrix[0][1];
2486 xx[2] = cob->matrix[0][2];
2489 /* store Z orientation before destroying obmat */
2490 zz[0] = cob->matrix[2][0];
2491 zz[1] = cob->matrix[2][1];
2492 zz[2] = cob->matrix[2][2];
2495 VecSubf(vec, cob->matrix[3], ct->matrix[3]);
2500 dist = Normalize(vec);
2501 //dist = VecLenf( ob->obmat[3], targetmat[3]);
2503 /* data->orglength==0 occurs on first run, and after 'R' button is clicked */
2504 if (data->orglength == 0)
2505 data->orglength = dist;
2506 if (data->bulge == 0)
2509 scale[1] = dist/data->orglength;
2510 switch (data->volmode) {
2511 /* volume preserving scaling */
2513 scale[0] = 1.0f - (float)sqrt(data->bulge) + (float)sqrt(data->bulge*(data->orglength/dist));
2514 scale[2] = scale[0];
2517 scale[0] = 1.0f + data->bulge * (data->orglength /dist - 1);
2522 scale[2] = 1.0f + data->bulge * (data->orglength /dist - 1);
2524 /* don't care for volume */
2529 default: /* should not happen, but in case*/
2531 } /* switch (data->volmode) */
2533 /* Clear the object's rotation and scale */
2534 cob->matrix[0][0]=size[0]*scale[0];
2535 cob->matrix[0][1]=0;
2536 cob->matrix[0][2]=0;
2537 cob->matrix[1][0]=0;
2538 cob->matrix[1][1]=size[1]*scale[1];
2539 cob->matrix[1][2]=0;
2540 cob->matrix[2][0]=0;
2541 cob->matrix[2][1]=0;
2542 cob->matrix[2][2]=size[2]*scale[2];
2544 VecSubf(vec, cob->matrix[3], ct->matrix[3]);
2547 /* new Y aligns object target connection*/
2548 totmat[1][0] = -vec[0];
2549 totmat[1][1] = -vec[1];
2550 totmat[1][2] = -vec[2];
2551 switch (data->plane) {
2553 /* build new Z vector */
2554 /* othogonal to "new Y" "old X! plane */
2555 Crossf(orth, vec, xx);
2559 totmat[2][0] = orth[0];
2560 totmat[2][1] = orth[1];
2561 totmat[2][2] = orth[2];
2563 /* we decided to keep X plane*/
2564 Crossf(xx, orth, vec);
2566 totmat[0][0] = xx[0];
2567 totmat[0][1] = xx[1];
2568 totmat[0][2] = xx[2];
2571 /* build new X vector */
2572 /* othogonal to "new Y" "old Z! plane */
2573 Crossf(orth, vec, zz);
2577 totmat[0][0] = -orth[0];
2578 totmat[0][1] = -orth[1];
2579 totmat[0][2] = -orth[2];
2581 /* we decided to keep Z */
2582 Crossf(zz, orth, vec);
2584 totmat[2][0] = zz[0];
2585 totmat[2][1] = zz[1];
2586 totmat[2][2] = zz[2];
2588 } /* switch (data->plane) */
2590 Mat4CpyMat4(tmat, cob->matrix);
2591 Mat4MulMat34(cob->matrix, totmat, tmat);
2595 static bConstraintTypeInfo CTI_STRETCHTO = {
2596 CONSTRAINT_TYPE_STRETCHTO, /* type */
2597 sizeof(bStretchToConstraint), /* size */
2598 "Stretch To", /* name */
2599 "bStretchToConstraint", /* struct name */
2600 NULL, /* free data */
2601 NULL, /* relink data */
2602 NULL, /* copy data */
2603 stretchto_new_data, /* new data */
2604 stretchto_get_tars, /* get constraint targets */
2605 stretchto_flush_tars, /* flush constraint targets */
2606 default_get_tarmat, /* get target matrix */
2607 stretchto_evaluate /* evaluate */
2610 /* ---------- Floor ------------ */
2612 static void minmax_new_data (void *cdata)
2614 bMinMaxConstraint *data= (bMinMaxConstraint *)cdata;
2616 data->minmaxflag = TRACK_Z;
2617 data->offset = 0.0f;
2618 data->cache[0] = data->cache[1] = data->cache[2] = 0.0f;
2622 static int minmax_get_tars (bConstraint *con, ListBase *list)
2625 bMinMaxConstraint *data= con->data;
2626 bConstraintTarget *ct;
2628 /* standard target-getting macro for single-target constraints */
2629 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
2637 static void minmax_flush_tars (bConstraint *con, ListBase *list, short nocopy)
2640 bMinMaxConstraint *data= con->data;
2641 bConstraintTarget *ct= list->first;
2643 /* the following macro is used for all standard single-target constraints */
2644 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
2648 static void minmax_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
2650 bMinMaxConstraint *data= con->data;
2651 bConstraintTarget *ct= targets->first;
2653 /* only evaluate if there is a target */
2654 if (VALID_CONS_TARGET(ct)) {
2655 float obmat[4][4], imat[4][4], tarmat[4][4], tmat[4][4];
2659 Mat4CpyMat4(obmat, cob->matrix);
2660 Mat4CpyMat4(tarmat, ct->matrix);
2662 if (data->flag & MINMAX_USEROT) {
2663 /* take rotation of target into account by doing the transaction in target's localspace */
2664 Mat4Invert(imat, tarmat);
2665 Mat4MulMat4(tmat, obmat, imat);
2666 Mat4CpyMat4(obmat, tmat);
2670 switch (data->minmaxflag) {
2672 val1 = tarmat[3][2];
2673 val2 = obmat[3][2]-data->offset;
2677 val1 = tarmat[3][1];
2678 val2 = obmat[3][1]-data->offset;
2682 val1 = tarmat[3][0];
2683 val2 = obmat[3][0]-data->offset;
2687 val2 = tarmat[3][2];
2688 val1 = obmat[3][2]-data->offset;
2692 val2 = tarmat[3][1];
2693 val1 = obmat[3][1]-data->offset;
2697 val2 = tarmat[3][0];
2698 val1 = obmat[3][0]-data->offset;
2706 obmat[3][index] = tarmat[3][index] + data->offset;
2707 if (data->flag & MINMAX_STICKY) {
2708 if (data->flag & MINMAX_STUCK) {
2709 VECCOPY(obmat[3], data->cache);
2712 VECCOPY(data->cache, obmat[3]);
2713 data->flag |= MINMAX_STUCK;
2716 if (data->flag & MINMAX_USEROT) {
2717 /* get out of localspace */
2718 Mat4MulMat4(tmat, obmat, ct->matrix);
2719 Mat4CpyMat4(cob->matrix, tmat);
2722 VECCOPY(cob->matrix[3], obmat[3]);
2726 data->flag &= ~MINMAX_STUCK;
2731 static bConstraintTypeInfo CTI_MINMAX = {
2732 CONSTRAINT_TYPE_MINMAX, /* type */
2733 sizeof(bMinMaxConstraint), /* size */
2735 "bMinMaxConstraint", /* struct name */
2736 NULL, /* free data */
2737 NULL, /* relink data */
2738 NULL, /* copy data */
2739 minmax_new_data, /* new data */
2740 minmax_get_tars, /* get constraint targets */
2741 minmax_flush_tars, /* flush constraint targets */
2742 default_get_tarmat, /* get target matrix */
2743 minmax_evaluate /* evaluate */
2746 /* ------- RigidBody Joint ---------- */
2748 static void rbj_new_data (void *cdata)
2750 bRigidBodyJointConstraint *data= (bRigidBodyJointConstraint *)cdata;
2752 // removed code which set target of this constraint
2756 static int rbj_get_tars (bConstraint *con, ListBase *list)
2759 bRigidBodyJointConstraint *data= con->data;
2760 bConstraintTarget *ct;
2762 /* standard target-getting macro for single-target constraints without subtargets */
2763 SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
2771 static void rbj_flush_tars (bConstraint *con, ListBase *list, short nocopy)
2774 bRigidBodyJointConstraint *data= con->data;
2775 bConstraintTarget *ct= list->first;
2777 /* the following macro is used for all standard single-target constraints */
2778 SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy)
2782 static bConstraintTypeInfo CTI_RIGIDBODYJOINT = {
2783 CONSTRAINT_TYPE_RIGIDBODYJOINT, /* type */
2784 sizeof(bRigidBodyJointConstraint), /* size */
2785 "RigidBody Joint", /* name */
2786 "bRigidBodyJointConstraint", /* struct name */
2787 NULL, /* free data */
2788 NULL, /* relink data */
2789 NULL, /* copy data */
2790 rbj_new_data, /* new data */
2791 rbj_get_tars, /* get constraint targets */
2792 rbj_flush_tars, /* flush constraint targets */
2793 default_get_tarmat, /* get target matrix */
2794 NULL /* evaluate - this is not solved here... is just an interface for game-engine */
2797 /* -------- Clamp To ---------- */
2799 static int clampto_get_tars (bConstraint *con, ListBase *list)
2802 bClampToConstraint *data= con->data;
2803 bConstraintTarget *ct;
2805 /* standard target-getting macro for single-target constraints without subtargets */
2806 SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
2814 static void clampto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
2817 bClampToConstraint *data= con->data;
2818 bConstraintTarget *ct= list->first;
2820 /* the following macro is used for all standard single-target constraints */
2821 SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy)
2825 static void clampto_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
2827 if (VALID_CONS_TARGET(ct)) {
2828 Curve *cu= ct->tar->data;
2830 /* note: when creating constraints that follow path, the curve gets the CU_PATH set now,
2831 * currently for paths to work it needs to go through the bevlist/displist system (ton)
2834 /* only happens on reload file, but violates depsgraph still... fix! */
2835 if (cu->path==NULL || cu->path->data==NULL)
2836 makeDispListCurveTypes(cob->scene, ct->tar, 0);
2839 /* technically, this isn't really needed for evaluation, but we don't know what else
2840 * might end up calling this...
2843 Mat4One(ct->matrix);
2846 static void clampto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
2848 bClampToConstraint *data= con->data;
2849 bConstraintTarget *ct= targets->first;
2851 /* only evaluate if there is a target and it is a curve */