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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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"
38 #include "BLI_blenlib.h"
39 #include "BLI_listbase.h"
41 #include "BLI_editVert.h"
43 #include "DNA_armature_types.h"
44 #include "DNA_constraint_types.h"
45 #include "DNA_modifier_types.h"
46 #include "DNA_object_types.h"
47 #include "DNA_action_types.h"
48 #include "DNA_curve_types.h"
49 #include "DNA_mesh_types.h"
50 #include "DNA_meshdata_types.h"
51 #include "DNA_lattice_types.h"
52 #include "DNA_scene_types.h"
53 #include "DNA_text_types.h"
55 #include "BKE_utildefines.h"
56 #include "BKE_action.h"
57 #include "BKE_anim.h" /* for the curve calculation part */
58 #include "BKE_armature.h"
59 #include "BKE_blender.h"
60 #include "BKE_constraint.h"
61 #include "BKE_displist.h"
62 #include "BKE_deform.h"
63 #include "BKE_DerivedMesh.h" /* for geometry targets */
64 #include "BKE_cdderivedmesh.h" /* for geometry targets */
65 #include "BKE_object.h"
67 #include "BKE_global.h"
68 #include "BKE_library.h"
69 #include "BKE_idprop.h"
70 #include "BKE_shrinkwrap.h"
74 #include "BPY_extern.h"
78 #define M_PI 3.14159265358979323846
83 /* ************************ Constraints - General Utilities *************************** */
84 /* These functions here don't act on any specific constraints, and are therefore should/will
85 * not require any of the special function-pointers afforded by the relevant constraint
89 /* -------------- Naming -------------- */
91 /* Find the first available, non-duplicate name for a given constraint */
92 void unique_constraint_name (bConstraint *con, ListBase *list)
94 BLI_uniquename(list, con, "Const", '.', offsetof(bConstraint, name), sizeof(con->name));
97 /* ----------------- Evaluation Loop Preparation --------------- */
99 /* package an object/bone for use in constraint evaluation */
100 /* This function MEM_calloc's a bConstraintOb struct, that will need to be freed after evaluation */
101 bConstraintOb *constraints_make_evalob (Scene *scene, Object *ob, void *subdata, short datatype)
105 /* create regardless of whether we have any data! */
106 cob= MEM_callocN(sizeof(bConstraintOb), "bConstraintOb");
108 /* for system time, part of deglobalization, code nicer later with local time (ton) */
111 /* based on type of available data */
113 case CONSTRAINT_OBTYPE_OBJECT:
115 /* disregard subdata... calloc should set other values right */
118 cob->type = datatype;
119 cob->rotOrder = EULER_ORDER_DEFAULT; // TODO: when objects have rotation order too, use that
120 copy_m4_m4(cob->matrix, ob->obmat);
123 unit_m4(cob->matrix);
125 copy_m4_m4(cob->startmat, cob->matrix);
128 case CONSTRAINT_OBTYPE_BONE:
130 /* only set if we have valid bone, otherwise default */
133 cob->pchan = (bPoseChannel *)subdata;
134 cob->type = datatype;
136 if (cob->pchan->rotmode > 0) {
137 /* should be some type of Euler order */
138 cob->rotOrder= cob->pchan->rotmode;
141 /* Quats, so eulers should just use default order */
142 cob->rotOrder= EULER_ORDER_DEFAULT;
145 /* matrix in world-space */
146 mul_m4_m4m4(cob->matrix, cob->pchan->pose_mat, ob->obmat);
149 unit_m4(cob->matrix);
151 copy_m4_m4(cob->startmat, cob->matrix);
155 default: /* other types not yet handled */
156 unit_m4(cob->matrix);
157 unit_m4(cob->startmat);
164 /* cleanup after constraint evaluation */
165 void constraints_clear_evalob (bConstraintOb *cob)
167 float delta[4][4], imat[4][4];
169 /* prevent crashes */
173 /* calculate delta of constraints evaluation */
174 invert_m4_m4(imat, cob->startmat);
175 mul_m4_m4m4(delta, imat, cob->matrix);
177 /* copy matrices back to source */
179 case CONSTRAINT_OBTYPE_OBJECT:
181 /* cob->ob might not exist! */
183 /* copy new ob-matrix back to owner */
184 copy_m4_m4(cob->ob->obmat, cob->matrix);
186 /* copy inverse of delta back to owner */
187 invert_m4_m4(cob->ob->constinv, delta);
191 case CONSTRAINT_OBTYPE_BONE:
193 /* cob->ob or cob->pchan might not exist */
194 if (cob->ob && cob->pchan) {
195 /* copy new pose-matrix back to owner */
196 mul_m4_m4m4(cob->pchan->pose_mat, cob->matrix, cob->ob->imat);
198 /* copy inverse of delta back to owner */
199 invert_m4_m4(cob->pchan->constinv, delta);
205 /* free tempolary struct */
209 /* -------------- Space-Conversion API -------------- */
211 /* This function is responsible for the correct transformations/conversions
212 * of a matrix from one space to another for constraint evaluation.
213 * For now, this is only implemented for Objects and PoseChannels.
215 void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4], short from, short to)
218 float diff_mat[4][4];
221 /* prevent crashes in these unlikely events */
222 if (ob==NULL || mat==NULL) return;
223 /* optimise trick - check if need to do anything */
224 if (from == to) return;
226 /* are we dealing with pose-channels or objects */
230 case CONSTRAINT_SPACE_WORLD: /* ---------- FROM WORLDSPACE ---------- */
233 invert_m4_m4(imat, ob->obmat);
234 copy_m4_m4(tempmat, mat);
235 mul_m4_m4m4(mat, tempmat, imat);
237 /* use pose-space as stepping stone for other spaces... */
238 if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) {
239 /* call self with slightly different values */
240 constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
244 case CONSTRAINT_SPACE_POSE: /* ---------- FROM POSESPACE ---------- */
247 if (to == CONSTRAINT_SPACE_WORLD) {
248 copy_m4_m4(tempmat, mat);
249 mul_m4_m4m4(mat, tempmat, ob->obmat);
252 else if (to == CONSTRAINT_SPACE_LOCAL) {
255 float offs_bone[4][4];
257 /* construct offs_bone the same way it is done in armature.c */
258 copy_m4_m3(offs_bone, pchan->bone->bone_mat);
259 copy_v3_v3(offs_bone[3], pchan->bone->head);
260 offs_bone[3][1]+= pchan->bone->parent->length;
262 if (pchan->bone->flag & BONE_HINGE) {
263 /* pose_mat = par_pose-space_location * chan_mat */
266 /* the rotation of the parent restposition */
267 copy_m4_m4(tmat, pchan->bone->parent->arm_mat);
269 /* the location of actual parent transform */
270 copy_v3_v3(tmat[3], offs_bone[3]);
271 offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f;
272 mul_m4_v3(pchan->parent->pose_mat, tmat[3]);
274 mul_m4_m4m4(diff_mat, offs_bone, tmat);
275 invert_m4_m4(imat, diff_mat);
278 /* pose_mat = par_pose_mat * bone_mat * chan_mat */
279 mul_m4_m4m4(diff_mat, offs_bone, pchan->parent->pose_mat);
280 invert_m4_m4(imat, diff_mat);
284 /* pose_mat = chan_mat * arm_mat */
285 invert_m4_m4(imat, pchan->bone->arm_mat);
288 copy_m4_m4(tempmat, mat);
289 mul_m4_m4m4(mat, tempmat, imat);
292 /* pose to local with parent */
293 else if (to == CONSTRAINT_SPACE_PARLOCAL) {
295 invert_m4_m4(imat, pchan->bone->arm_mat);
296 copy_m4_m4(tempmat, mat);
297 mul_m4_m4m4(mat, tempmat, imat);
302 case CONSTRAINT_SPACE_LOCAL: /* ------------ FROM LOCALSPACE --------- */
304 /* local to pose - do inverse procedure that was done for pose to local */
306 /* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */
308 float offs_bone[4][4];
310 /* construct offs_bone the same way it is done in armature.c */
311 copy_m4_m3(offs_bone, pchan->bone->bone_mat);
312 copy_v3_v3(offs_bone[3], pchan->bone->head);
313 offs_bone[3][1]+= pchan->bone->parent->length;
315 if (pchan->bone->flag & BONE_HINGE) {
316 /* pose_mat = par_pose-space_location * chan_mat */
319 /* the rotation of the parent restposition */
320 copy_m4_m4(tmat, pchan->bone->parent->arm_mat);
322 /* the location of actual parent transform */
323 copy_v3_v3(tmat[3], offs_bone[3]);
324 zero_v3(offs_bone[3]);
325 mul_m4_v3(pchan->parent->pose_mat, tmat[3]);
327 mul_m4_m4m4(diff_mat, offs_bone, tmat);
328 copy_m4_m4(tempmat, mat);
329 mul_m4_m4m4(mat, tempmat, diff_mat);
332 /* pose_mat = par_pose_mat * bone_mat * chan_mat */
333 mul_m4_m4m4(diff_mat, offs_bone, pchan->parent->pose_mat);
334 copy_m4_m4(tempmat, mat);
335 mul_m4_m4m4(mat, tempmat, diff_mat);
339 copy_m4_m4(diff_mat, pchan->bone->arm_mat);
341 copy_m4_m4(tempmat, mat);
342 mul_m4_m4m4(mat, tempmat, diff_mat);
346 /* use pose-space as stepping stone for other spaces */
347 if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL)) {
348 /* call self with slightly different values */
349 constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
353 case CONSTRAINT_SPACE_PARLOCAL: /* -------------- FROM LOCAL WITH PARENT ---------- */
355 /* local + parent to pose */
357 copy_m4_m4(diff_mat, pchan->bone->arm_mat);
358 copy_m4_m4(tempmat, mat);
359 mul_m4_m4m4(mat, diff_mat, tempmat);
362 /* use pose-space as stepping stone for other spaces */
363 if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL)) {
364 /* call self with slightly different values */
365 constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
373 if (from==CONSTRAINT_SPACE_WORLD && to==CONSTRAINT_SPACE_LOCAL) {
374 /* check if object has a parent - otherwise this won't work */
376 /* 'subtract' parent's effects from owner */
377 mul_m4_m4m4(diff_mat, ob->parentinv, ob->parent->obmat);
378 invert_m4_m4(imat, diff_mat);
379 copy_m4_m4(tempmat, mat);
380 mul_m4_m4m4(mat, tempmat, imat);
383 else if (from==CONSTRAINT_SPACE_LOCAL && to==CONSTRAINT_SPACE_WORLD) {
384 /* check that object has a parent - otherwise this won't work */
386 /* 'add' parent's effect back to owner */
387 copy_m4_m4(tempmat, mat);
388 mul_m4_m4m4(diff_mat, ob->parentinv, ob->parent->obmat);
389 mul_m4_m4m4(mat, tempmat, diff_mat);
395 /* ------------ General Target Matrix Tools ---------- */
397 /* function that sets the given matrix based on given vertex group in mesh */
398 static void contarget_get_mesh_mat (Scene *scene, Object *ob, char *substring, float mat[][4])
400 DerivedMesh *dm = NULL;
402 EditMesh *em = BKE_mesh_get_editmesh(me);
403 float vec[3] = {0.0f, 0.0f, 0.0f};
404 float normal[3] = {0.0f, 0.0f, 0.0f}, plane[3];
405 float imat[3][3], tmat[3][3];
409 /* initialize target matrix using target matrix */
410 copy_m4_m4(mat, ob->obmat);
412 /* get index of vertex group */
413 dgroup = defgroup_name_index(ob, substring);
414 if (dgroup < 0) return;
416 /* get DerivedMesh */
418 /* target is in editmode, so get a special derived mesh */
419 dm = CDDM_from_editmesh(em, ob->data);
423 /* when not in EditMode, use the 'final' derived mesh
424 * - check if the custom data masks for derivedFinal mean that we can just use that
425 * (this is more effficient + sufficient for most cases)
427 if (!(ob->lastDataMask & CD_MASK_MDEFORMVERT)) {
428 dm = mesh_get_derived_final(scene, ob, CD_MASK_MDEFORMVERT);
432 dm = (DerivedMesh *)ob->derivedFinal;
435 /* only continue if there's a valid DerivedMesh */
437 MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
438 int numVerts = dm->getNumVerts(dm);
442 /* check that dvert is a valid pointers (just in case) */
444 /* get the average of all verts with that are in the vertex-group */
445 for (i = 0; i < numVerts; i++) {
446 for (j = 0; j < dvert[i].totweight; j++) {
447 /* does this vertex belong to nominated vertex group? */
448 if (dvert[i].dw[j].def_nr == dgroup) {
449 dm->getVertCo(dm, i, co);
450 dm->getVertNo(dm, i, nor);
452 add_v3_v3(normal, nor);
461 /* calculate averages of normal and coordinates */
463 mul_v3_fl(vec, 1.0f / count);
464 mul_v3_fl(normal, 1.0f / count);
468 /* derive the rotation from the average normal:
469 * - code taken from transform_manipulator.c,
470 * calc_manipulator_stats, V3D_MANIP_NORMAL case
472 /* we need the transpose of the inverse for a normal... */
473 copy_m3_m4(imat, ob->obmat);
475 invert_m3_m3(tmat, imat);
477 mul_m3_v3(tmat, normal);
479 normalize_v3(normal);
480 copy_v3_v3(plane, tmat[1]);
482 copy_v3_v3(tmat[2], normal);
483 cross_v3_v3v3(tmat[0], normal, plane);
484 cross_v3_v3v3(tmat[1], tmat[2], tmat[0]);
486 copy_m4_m3(mat, tmat);
490 /* apply the average coordinate as the new location */
491 mul_v3_m4v3(mat[3], ob->obmat, vec);
495 /* free temporary DerivedMesh created (in EditMode case) */
499 BKE_mesh_end_editmesh(me, em);
502 /* function that sets the given matrix based on given vertex group in lattice */
503 static void contarget_get_lattice_mat (Object *ob, char *substring, float mat[][4])
505 Lattice *lt= (Lattice *)ob->data;
507 DispList *dl = find_displist(&ob->disp, DL_VERTS);
508 float *co = dl?dl->verts:NULL;
509 BPoint *bp = lt->def;
511 MDeformVert *dvert = lt->dvert;
512 int tot_verts= lt->pntsu*lt->pntsv*lt->pntsw;
513 float vec[3]= {0.0f, 0.0f, 0.0f}, tvec[3];
514 int dgroup=0, grouped=0;
517 /* initialize target matrix using target matrix */
518 copy_m4_m4(mat, ob->obmat);
520 /* get index of vertex group */
521 dgroup = defgroup_name_index(ob, substring);
522 if (dgroup < 0) return;
523 if (dvert == NULL) return;
525 /* 1. Loop through control-points checking if in nominated vertex-group.
526 * 2. If it is, add it to vec to find the average point.
528 for (i=0; i < tot_verts; i++, dvert++) {
529 for (n= 0; n < dvert->totweight; n++) {
530 /* found match - vert is in vgroup */
531 if (dvert->dw[n].def_nr == dgroup) {
532 /* copy coordinates of point to temporary vector, then add to find average */
534 memcpy(tvec, co, 3*sizeof(float));
536 memcpy(tvec, bp->vec, 3*sizeof(float));
538 add_v3_v3(vec, tvec);
545 /* advance pointer to coordinate data */
550 /* find average location, then multiply by ob->obmat to find world-space location */
552 mul_v3_fl(vec, 1.0f / grouped);
553 mul_v3_m4v3(tvec, ob->obmat, vec);
555 /* copy new location to matrix */
556 copy_v3_v3(mat[3], tvec);
559 /* generic function to get the appropriate matrix for most target cases */
560 /* The cases where the target can be object data have not been implemented */
561 static void constraint_target_to_mat4 (Scene *scene, Object *ob, char *substring, float mat[][4], short from, short to, float headtail)
564 if (!strlen(substring)) {
565 copy_m4_m4(mat, ob->obmat);
566 constraint_mat_convertspace(ob, NULL, mat, from, to);
568 /* Case VERTEXGROUP */
569 /* Current method just takes the average location of all the points in the
570 * VertexGroup, and uses that as the location value of the targets. Where
571 * possible, the orientation will also be calculated, by calculating an
572 * 'average' vertex normal, and deriving the rotaation from that.
574 * NOTE: EditMode is not currently supported, and will most likely remain that
575 * way as constraints can only really affect things on object/bone level.
577 else if (ob->type == OB_MESH) {
578 contarget_get_mesh_mat(scene, ob, substring, mat);
579 constraint_mat_convertspace(ob, NULL, mat, from, to);
581 else if (ob->type == OB_LATTICE) {
582 contarget_get_lattice_mat(ob, substring, mat);
583 constraint_mat_convertspace(ob, NULL, mat, from, to);
589 pchan = get_pose_channel(ob->pose, substring);
591 /* Multiply the PoseSpace accumulation/final matrix for this
592 * PoseChannel by the Armature Object's Matrix to get a worldspace
595 if (headtail < 0.000001) {
596 /* skip length interpolation if set to head */
597 mul_m4_m4m4(mat, pchan->pose_mat, ob->obmat);
600 float tempmat[4][4], loc[3];
602 /* interpolate along length of bone */
603 interp_v3_v3v3(loc, pchan->pose_head, pchan->pose_tail, headtail);
605 /* use interpolated distance for subtarget */
606 copy_m4_m4(tempmat, pchan->pose_mat);
607 copy_v3_v3(tempmat[3], loc);
609 mul_m4_m4m4(mat, tempmat, ob->obmat);
613 copy_m4_m4(mat, ob->obmat);
615 /* convert matrix space as required */
616 constraint_mat_convertspace(ob, pchan, mat, from, to);
620 /* ************************* Specific Constraints ***************************** */
621 /* Each constraint defines a set of functions, which will be called at the appropriate
622 * times. In addition to this, each constraint should have a type-info struct, where
623 * its functions are attached for use.
626 /* Template for type-info data:
627 * - make a copy of this when creating new constraints, and just change the functions
628 * pointed to as necessary
629 * - although the naming of functions doesn't matter, it would help for code
630 * readability, to follow the same naming convention as is presented here
631 * - any functions that a constraint doesn't need to define, don't define
632 * for such cases, just use NULL
633 * - these should be defined after all the functions have been defined, so that
634 * forward-definitions/prototypes don't need to be used!
635 * - keep this copy #if-def'd so that future constraints can get based off this
638 static bConstraintTypeInfo CTI_CONSTRNAME = {
639 CONSTRAINT_TYPE_CONSTRNAME, /* type */
640 sizeof(bConstrNameConstraint), /* size */
641 "ConstrName", /* name */
642 "bConstrNameConstraint", /* struct name */
643 constrname_free, /* free data */
644 constrname_relink, /* relink data */
645 constrname_id_looper, /* id looper */
646 constrname_copy, /* copy data */
647 constrname_new_data, /* new data */
648 constrname_get_tars, /* get constraint targets */
649 constrname_flush_tars, /* flush constraint targets */
650 constrname_get_tarmat, /* get target matrix */
651 constrname_evaluate /* evaluate */
655 /* This function should be used for the get_target_matrix member of all
656 * constraints that are not picky about what happens to their target matrix.
658 static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
660 if (VALID_CONS_TARGET(ct))
661 constraint_target_to_mat4(cob->scene, ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
666 /* This following macro should be used for all standard single-target *_get_tars functions
667 * to save typing and reduce maintainance woes.
668 * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
669 * really just to help this code easier to read)
671 // TODO: cope with getting rotation order...
672 #define SINGLETARGET_GET_TARS(con, datatar, datasubtarget, ct, list) \
674 ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \
677 strcpy(ct->subtarget, datasubtarget); \
678 ct->space= con->tarspace; \
679 ct->flag= CONSTRAINT_TAR_TEMP; \
682 if ((ct->tar->type==OB_ARMATURE) && (ct->subtarget[0])) { \
683 bPoseChannel *pchan= get_pose_channel(ct->tar->pose, ct->subtarget); \
684 ct->type = CONSTRAINT_OBTYPE_BONE; \
685 ct->rotOrder= (pchan) ? (pchan->rotmode) : EULER_ORDER_DEFAULT; \
687 else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) { \
688 ct->type = CONSTRAINT_OBTYPE_VERT; \
689 ct->rotOrder = EULER_ORDER_DEFAULT; \
692 ct->type = CONSTRAINT_OBTYPE_OBJECT; \
693 ct->rotOrder= ct->tar->rotmode; \
697 BLI_addtail(list, ct); \
700 /* This following macro should be used for all standard single-target *_get_tars functions
701 * to save typing and reduce maintainance woes. It does not do the subtarget related operations
702 * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
703 * really just to help this code easier to read)
705 // TODO: cope with getting rotation order...
706 #define SINGLETARGETNS_GET_TARS(con, datatar, ct, list) \
708 ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \
711 ct->space= con->tarspace; \
712 ct->flag= CONSTRAINT_TAR_TEMP; \
714 if (ct->tar) ct->type = CONSTRAINT_OBTYPE_OBJECT; \
716 BLI_addtail(list, ct); \
719 /* This following macro should be used for all standard single-target *_flush_tars functions
720 * to save typing and reduce maintainance woes.
721 * Note: the pointer to ct will be changed to point to the next in the list (as it gets removed)
722 * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
723 * really just to help this code easier to read)
725 #define SINGLETARGET_FLUSH_TARS(con, datatar, datasubtarget, ct, list, nocopy) \
728 bConstraintTarget *ctn = ct->next; \
731 strcpy(datasubtarget, ct->subtarget); \
732 con->tarspace= (char)ct->space; \
735 BLI_freelinkN(list, ct); \
740 /* This following macro should be used for all standard single-target *_flush_tars functions
741 * to save typing and reduce maintainance woes. It does not do the subtarget related operations.
742 * Note: the pointer to ct will be changed to point to the next in the list (as it gets removed)
743 * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
744 * really just to help this code easier to read)
746 #define SINGLETARGETNS_FLUSH_TARS(con, datatar, ct, list, nocopy) \
749 bConstraintTarget *ctn = ct->next; \
752 con->tarspace= (char)ct->space; \
755 BLI_freelinkN(list, ct); \
760 /* --------- ChildOf Constraint ------------ */
762 static void childof_new_data (void *cdata)
764 bChildOfConstraint *data= (bChildOfConstraint *)cdata;
766 data->flag = (CHILDOF_LOCX | CHILDOF_LOCY | CHILDOF_LOCZ |
767 CHILDOF_ROTX |CHILDOF_ROTY | CHILDOF_ROTZ |
768 CHILDOF_SIZEX | CHILDOF_SIZEY | CHILDOF_SIZEZ);
769 unit_m4(data->invmat);
772 static void childof_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
774 bChildOfConstraint *data= con->data;
777 func(con, (ID**)&data->tar, userdata);
780 static int childof_get_tars (bConstraint *con, ListBase *list)
783 bChildOfConstraint *data= con->data;
784 bConstraintTarget *ct;
786 /* standard target-getting macro for single-target constraints */
787 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
795 static void childof_flush_tars (bConstraint *con, ListBase *list, short nocopy)
798 bChildOfConstraint *data= con->data;
799 bConstraintTarget *ct= list->first;
801 /* the following macro is used for all standard single-target constraints */
802 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
806 static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
808 bChildOfConstraint *data= con->data;
809 bConstraintTarget *ct= targets->first;
811 /* only evaluate if there is a target */
812 if (VALID_CONS_TARGET(ct)) {
813 float parmat[4][4], invmat[4][4], tempmat[4][4];
814 float loc[3], eul[3], size[3];
815 float loco[3], eulo[3], sizo[3];
817 /* get offset (parent-inverse) matrix */
818 copy_m4_m4(invmat, data->invmat);
820 /* extract components of both matrices */
821 copy_v3_v3(loc, ct->matrix[3]);
822 mat4_to_eulO(eul, ct->rotOrder, ct->matrix);
823 mat4_to_size(size, ct->matrix);
825 copy_v3_v3(loco, invmat[3]);
826 mat4_to_eulO(eulo, cob->rotOrder, invmat);
827 mat4_to_size(sizo, invmat);
829 /* disable channels not enabled */
830 if (!(data->flag & CHILDOF_LOCX)) loc[0]= loco[0]= 0.0f;
831 if (!(data->flag & CHILDOF_LOCY)) loc[1]= loco[1]= 0.0f;
832 if (!(data->flag & CHILDOF_LOCZ)) loc[2]= loco[2]= 0.0f;
833 if (!(data->flag & CHILDOF_ROTX)) eul[0]= eulo[0]= 0.0f;
834 if (!(data->flag & CHILDOF_ROTY)) eul[1]= eulo[1]= 0.0f;
835 if (!(data->flag & CHILDOF_ROTZ)) eul[2]= eulo[2]= 0.0f;
836 if (!(data->flag & CHILDOF_SIZEX)) size[0]= sizo[0]= 1.0f;
837 if (!(data->flag & CHILDOF_SIZEY)) size[1]= sizo[1]= 1.0f;
838 if (!(data->flag & CHILDOF_SIZEZ)) size[2]= sizo[2]= 1.0f;
840 /* make new target mat and offset mat */
841 loc_eulO_size_to_mat4(ct->matrix, loc, eul, size, ct->rotOrder);
842 loc_eulO_size_to_mat4(invmat, loco, eulo, sizo, cob->rotOrder);
844 /* multiply target (parent matrix) by offset (parent inverse) to get
845 * the effect of the parent that will be exherted on the owner
847 mul_m4_m4m4(parmat, invmat, ct->matrix);
849 /* now multiply the parent matrix by the owner matrix to get the
850 * the effect of this constraint (i.e. owner is 'parented' to parent)
852 copy_m4_m4(tempmat, cob->matrix);
853 mul_m4_m4m4(cob->matrix, tempmat, parmat);
855 /* without this, changes to scale and rotation can change location
856 * of a parentless bone or a disconnected bone. Even though its set
858 if (!(data->flag & CHILDOF_LOCX)) cob->matrix[3][0]= tempmat[3][0];
859 if (!(data->flag & CHILDOF_LOCY)) cob->matrix[3][1]= tempmat[3][1];
860 if (!(data->flag & CHILDOF_LOCZ)) cob->matrix[3][2]= tempmat[3][2];
864 static bConstraintTypeInfo CTI_CHILDOF = {
865 CONSTRAINT_TYPE_CHILDOF, /* type */
866 sizeof(bChildOfConstraint), /* size */
867 "ChildOf", /* name */
868 "bChildOfConstraint", /* struct name */
869 NULL, /* free data */
870 NULL, /* relink data */
871 childof_id_looper, /* id looper */
872 NULL, /* copy data */
873 childof_new_data, /* new data */
874 childof_get_tars, /* get constraint targets */
875 childof_flush_tars, /* flush constraint targets */
876 default_get_tarmat, /* get a target matrix */
877 childof_evaluate /* evaluate */
880 /* -------- TrackTo Constraint ------- */
882 static void trackto_new_data (void *cdata)
884 bTrackToConstraint *data= (bTrackToConstraint *)cdata;
886 data->reserved1 = TRACK_Y;
887 data->reserved2 = UP_Z;
890 static void trackto_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
892 bTrackToConstraint *data= con->data;
895 func(con, (ID**)&data->tar, userdata);
898 static int trackto_get_tars (bConstraint *con, ListBase *list)
901 bTrackToConstraint *data= con->data;
902 bConstraintTarget *ct;
904 /* standard target-getting macro for single-target constraints */
905 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
913 static void trackto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
916 bTrackToConstraint *data= con->data;
917 bConstraintTarget *ct= list->first;
919 /* the following macro is used for all standard single-target constraints */
920 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
925 static int basis_cross (int n, int m)
941 static void vectomat (float *vec, float *target_up, short axis, short upflag, short flags, float m[][3])
944 float u[3]; /* vector specifying the up axis */
950 if (normalize_v3_v3(n, vec) == 0.0) {
955 if (axis > 2) axis -= 3;
958 /* n specifies the transformation of the track axis */
959 if (flags & TARGET_Z_UP) {
960 /* target Z axis is the global up axis */
961 copy_v3_v3(u, target_up);
964 /* world Z axis is the global up axis */
970 /* project the up vector onto the plane specified by n */
971 project_v3_v3v3(proj, u, n); /* first u onto n... */
972 sub_v3_v3v3(proj, u, proj); /* then onto the plane */
973 /* proj specifies the transformation of the up axis */
975 if (normalize_v3(proj) == 0.0) { /* degenerate projection */
981 /* Normalized cross product of n and proj specifies transformation of the right axis */
982 cross_v3_v3v3(right, proj, n);
985 if (axis != upflag) {
986 right_index = 3 - axis - upflag;
987 neg = (float)basis_cross(axis, upflag);
989 /* account for up direction, track direction */
990 m[right_index][0] = neg * right[0];
991 m[right_index][1] = neg * right[1];
992 m[right_index][2] = neg * right[2];
994 copy_v3_v3(m[upflag], proj);
996 copy_v3_v3(m[axis], n);
998 /* identity matrix - don't do anything if the two axes are the same */
1005 static void trackto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1007 bTrackToConstraint *data= con->data;
1008 bConstraintTarget *ct= targets->first;
1010 if (VALID_CONS_TARGET(ct)) {
1011 float size[3], vec[3];
1015 /* Get size property, since ob->size is only the object's own relative size, not its global one */
1016 mat4_to_size(size, cob->matrix);
1018 /* Clear the object's rotation */
1019 cob->matrix[0][0]=size[0];
1020 cob->matrix[0][1]=0;
1021 cob->matrix[0][2]=0;
1022 cob->matrix[1][0]=0;
1023 cob->matrix[1][1]=size[1];
1024 cob->matrix[1][2]=0;
1025 cob->matrix[2][0]=0;
1026 cob->matrix[2][1]=0;
1027 cob->matrix[2][2]=size[2];
1029 /* targetmat[2] instead of ownermat[2] is passed to vectomat
1030 * for backwards compatability it seems... (Aligorith)
1032 sub_v3_v3v3(vec, cob->matrix[3], ct->matrix[3]);
1033 vectomat(vec, ct->matrix[2],
1034 (short)data->reserved1, (short)data->reserved2,
1035 data->flags, totmat);
1037 copy_m4_m4(tmat, cob->matrix);
1038 mul_m4_m3m4(cob->matrix, totmat, tmat);
1042 static bConstraintTypeInfo CTI_TRACKTO = {
1043 CONSTRAINT_TYPE_TRACKTO, /* type */
1044 sizeof(bTrackToConstraint), /* size */
1045 "TrackTo", /* name */
1046 "bTrackToConstraint", /* struct name */
1047 NULL, /* free data */
1048 NULL, /* relink data */
1049 trackto_id_looper, /* id looper */
1050 NULL, /* copy data */
1051 trackto_new_data, /* new data */
1052 trackto_get_tars, /* get constraint targets */
1053 trackto_flush_tars, /* flush constraint targets */
1054 default_get_tarmat, /* get target matrix */
1055 trackto_evaluate /* evaluate */
1058 /* --------- Inverse-Kinemetics --------- */
1060 static void kinematic_new_data (void *cdata)
1062 bKinematicConstraint *data= (bKinematicConstraint *)cdata;
1064 data->weight= (float)1.0;
1065 data->orientweight= (float)1.0;
1066 data->iterations = 500;
1067 data->dist= (float)1.0;
1068 data->flag= CONSTRAINT_IK_TIP|CONSTRAINT_IK_STRETCH|CONSTRAINT_IK_POS;
1071 static void kinematic_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
1073 bKinematicConstraint *data= con->data;
1076 func(con, (ID**)&data->tar, userdata);
1079 func(con, (ID**)&data->poletar, userdata);
1082 static int kinematic_get_tars (bConstraint *con, ListBase *list)
1085 bKinematicConstraint *data= con->data;
1086 bConstraintTarget *ct;
1088 /* standard target-getting macro for single-target constraints is used twice here */
1089 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
1090 SINGLETARGET_GET_TARS(con, data->poletar, data->polesubtarget, ct, list)
1098 static void kinematic_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1101 bKinematicConstraint *data= con->data;
1102 bConstraintTarget *ct= list->first;
1104 /* the following macro is used for all standard single-target constraints */
1105 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
1106 SINGLETARGET_FLUSH_TARS(con, data->poletar, data->polesubtarget, ct, list, nocopy)
1110 static void kinematic_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
1112 bKinematicConstraint *data= con->data;
1114 if (VALID_CONS_TARGET(ct))
1115 constraint_target_to_mat4(cob->scene, ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
1117 if (data->flag & CONSTRAINT_IK_AUTO) {
1118 Object *ob= cob->ob;
1121 unit_m4(ct->matrix);
1125 /* move grabtarget into world space */
1126 mul_v3_m4v3(vec, ob->obmat, data->grabtarget);
1127 copy_m4_m4(ct->matrix, ob->obmat);
1128 copy_v3_v3(ct->matrix[3], vec);
1132 unit_m4(ct->matrix);
1136 static bConstraintTypeInfo CTI_KINEMATIC = {
1137 CONSTRAINT_TYPE_KINEMATIC, /* type */
1138 sizeof(bKinematicConstraint), /* size */
1140 "bKinematicConstraint", /* struct name */
1141 NULL, /* free data */
1142 NULL, /* relink data */
1143 kinematic_id_looper, /* id looper */
1144 NULL, /* copy data */
1145 kinematic_new_data, /* new data */
1146 kinematic_get_tars, /* get constraint targets */
1147 kinematic_flush_tars, /* flush constraint targets */
1148 kinematic_get_tarmat, /* get target matrix */
1149 NULL /* evaluate - solved as separate loop */
1152 /* -------- Follow-Path Constraint ---------- */
1154 static void followpath_new_data (void *cdata)
1156 bFollowPathConstraint *data= (bFollowPathConstraint *)cdata;
1158 data->trackflag = TRACK_Y;
1159 data->upflag = UP_Z;
1161 data->followflag = 0;
1164 static void followpath_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
1166 bFollowPathConstraint *data= con->data;
1169 func(con, (ID**)&data->tar, userdata);
1172 static int followpath_get_tars (bConstraint *con, ListBase *list)
1175 bFollowPathConstraint *data= con->data;
1176 bConstraintTarget *ct;
1178 /* standard target-getting macro for single-target constraints without subtargets */
1179 SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
1187 static void followpath_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1190 bFollowPathConstraint *data= con->data;
1191 bConstraintTarget *ct= list->first;
1193 /* the following macro is used for all standard single-target constraints */
1194 SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy)
1198 static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
1200 bFollowPathConstraint *data= con->data;
1202 if (VALID_CONS_TARGET(ct)) {
1203 Curve *cu= ct->tar->data;
1204 float vec[4], dir[3], radius;
1209 unit_m4(ct->matrix);
1211 /* note: when creating constraints that follow path, the curve gets the CU_PATH set now,
1212 * currently for paths to work it needs to go through the bevlist/displist system (ton)
1215 /* only happens on reload file, but violates depsgraph still... fix! */
1216 if (cu->path==NULL || cu->path->data==NULL)
1217 makeDispListCurveTypes(cob->scene, ct->tar, 0);
1219 if (cu->path && cu->path->data) {
1221 if ((data->followflag & FOLLOWPATH_STATIC) == 0) {
1222 /* animated position along curve depending on time */
1224 curvetime= bsystem_time(cob->scene, ct->tar, cu->ctime, 0.0) - data->offset;
1226 curvetime= cu->ctime - data->offset;
1228 /* ctime is now a proper var setting of Curve which gets set by Animato like any other var that's animated,
1229 * but this will only work if it actually is animated...
1231 * we divide the curvetime calculated in the previous step by the length of the path, to get a time
1232 * factor, which then gets clamped to lie within 0.0 - 1.0 range
1234 curvetime /= cu->pathlen;
1235 CLAMP(curvetime, 0.0, 1.0);
1238 /* fixed position along curve */
1239 curvetime= data->offset_fac;
1242 if ( where_on_path(ct->tar, curvetime, vec, dir, (data->followflag & FOLLOWPATH_FOLLOW) ? quat : NULL, &radius, NULL) ) { /* quat_pt is quat or NULL*/
1243 if (data->followflag & FOLLOWPATH_FOLLOW) {
1246 vec_to_quat(quat, dir, (short)data->trackflag, (short)data->upflag);
1249 q[0]= (float)cos(0.5*vec[3]);
1250 x1= (float)sin(0.5*vec[3]);
1254 mul_qt_qtqt(quat, q, quat);
1256 quat_apply_track(quat, data->trackflag, data->upflag);
1259 quat_to_mat4(totmat, quat);
1262 if (data->followflag & FOLLOWPATH_RADIUS) {
1263 float tmat[4][4], rmat[4][4];
1264 scale_m4_fl(tmat, radius);
1265 mul_m4_m4m4(rmat, totmat, tmat);
1266 copy_m4_m4(totmat, rmat);
1269 copy_v3_v3(totmat[3], vec);
1271 mul_serie_m4(ct->matrix, ct->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL);
1276 unit_m4(ct->matrix);
1279 static void followpath_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1281 bConstraintTarget *ct= targets->first;
1283 /* only evaluate if there is a target */
1284 if (VALID_CONS_TARGET(ct)) {
1287 bFollowPathConstraint *data= con->data;
1289 /* get Object transform (loc/rot/size) to determine transformation from path */
1290 // TODO: this used to be local at one point, but is probably more useful as-is
1291 copy_m4_m4(obmat, cob->matrix);
1293 /* get scaling of object before applying constraint */
1294 mat4_to_size(size, cob->matrix);
1296 /* apply targetmat - containing location on path, and rotation */
1297 mul_serie_m4(cob->matrix, ct->matrix, obmat, NULL, NULL, NULL, NULL, NULL, NULL);
1299 /* un-apply scaling caused by path */
1300 if ((data->followflag & FOLLOWPATH_RADIUS)==0) { /* XXX - assume that scale correction means that radius will have some scale error in it - Campbell */
1303 mat4_to_size( obsize,cob->matrix);
1305 mul_v3_fl(cob->matrix[0], size[0] / obsize[0]);
1307 mul_v3_fl(cob->matrix[1], size[1] / obsize[1]);
1309 mul_v3_fl(cob->matrix[2], size[2] / obsize[2]);
1314 static bConstraintTypeInfo CTI_FOLLOWPATH = {
1315 CONSTRAINT_TYPE_FOLLOWPATH, /* type */
1316 sizeof(bFollowPathConstraint), /* size */
1317 "Follow Path", /* name */
1318 "bFollowPathConstraint", /* struct name */
1319 NULL, /* free data */
1320 NULL, /* relink data */
1321 followpath_id_looper, /* id looper */
1322 NULL, /* copy data */
1323 followpath_new_data, /* new data */
1324 followpath_get_tars, /* get constraint targets */
1325 followpath_flush_tars, /* flush constraint targets */
1326 followpath_get_tarmat, /* get target matrix */
1327 followpath_evaluate /* evaluate */
1330 /* --------- Limit Location --------- */
1333 static void loclimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
1335 bLocLimitConstraint *data = con->data;
1337 if (data->flag & LIMIT_XMIN) {
1338 if (cob->matrix[3][0] < data->xmin)
1339 cob->matrix[3][0] = data->xmin;
1341 if (data->flag & LIMIT_XMAX) {
1342 if (cob->matrix[3][0] > data->xmax)
1343 cob->matrix[3][0] = data->xmax;
1345 if (data->flag & LIMIT_YMIN) {
1346 if (cob->matrix[3][1] < data->ymin)
1347 cob->matrix[3][1] = data->ymin;
1349 if (data->flag & LIMIT_YMAX) {
1350 if (cob->matrix[3][1] > data->ymax)
1351 cob->matrix[3][1] = data->ymax;
1353 if (data->flag & LIMIT_ZMIN) {
1354 if (cob->matrix[3][2] < data->zmin)
1355 cob->matrix[3][2] = data->zmin;
1357 if (data->flag & LIMIT_ZMAX) {
1358 if (cob->matrix[3][2] > data->zmax)
1359 cob->matrix[3][2] = data->zmax;
1363 static bConstraintTypeInfo CTI_LOCLIMIT = {
1364 CONSTRAINT_TYPE_LOCLIMIT, /* type */
1365 sizeof(bLocLimitConstraint), /* size */
1366 "Limit Location", /* name */
1367 "bLocLimitConstraint", /* struct name */
1368 NULL, /* free data */
1369 NULL, /* relink data */
1370 NULL, /* id looper */
1371 NULL, /* copy data */
1372 NULL, /* new data */
1373 NULL, /* get constraint targets */
1374 NULL, /* flush constraint targets */
1375 NULL, /* get target matrix */
1376 loclimit_evaluate /* evaluate */
1379 /* -------- Limit Rotation --------- */
1381 static void rotlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
1383 bRotLimitConstraint *data = con->data;
1388 copy_v3_v3(loc, cob->matrix[3]);
1389 mat4_to_size(size, cob->matrix);
1391 mat4_to_eulO(eul, cob->rotOrder, cob->matrix);
1393 /* constraint data uses radians internally */
1395 /* limiting of euler values... */
1396 if (data->flag & LIMIT_XROT) {
1397 if (eul[0] < data->xmin)
1398 eul[0] = data->xmin;
1400 if (eul[0] > data->xmax)
1401 eul[0] = data->xmax;
1403 if (data->flag & LIMIT_YROT) {
1404 if (eul[1] < data->ymin)
1405 eul[1] = data->ymin;
1407 if (eul[1] > data->ymax)
1408 eul[1] = data->ymax;
1410 if (data->flag & LIMIT_ZROT) {
1411 if (eul[2] < data->zmin)
1412 eul[2] = data->zmin;
1414 if (eul[2] > data->zmax)
1415 eul[2] = data->zmax;
1418 loc_eulO_size_to_mat4(cob->matrix, loc, eul, size, cob->rotOrder);
1421 static bConstraintTypeInfo CTI_ROTLIMIT = {
1422 CONSTRAINT_TYPE_ROTLIMIT, /* type */
1423 sizeof(bRotLimitConstraint), /* size */
1424 "Limit Rotation", /* name */
1425 "bRotLimitConstraint", /* struct name */
1426 NULL, /* free data */
1427 NULL, /* relink data */
1428 NULL, /* id looper */
1429 NULL, /* copy data */
1430 NULL, /* new data */
1431 NULL, /* get constraint targets */
1432 NULL, /* flush constraint targets */
1433 NULL, /* get target matrix */
1434 rotlimit_evaluate /* evaluate */
1437 /* --------- Limit Scaling --------- */
1440 static void sizelimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
1442 bSizeLimitConstraint *data = con->data;
1443 float obsize[3], size[3];
1445 mat4_to_size( size,cob->matrix);
1446 mat4_to_size( obsize,cob->matrix);
1448 if (data->flag & LIMIT_XMIN) {
1449 if (size[0] < data->xmin)
1450 size[0] = data->xmin;
1452 if (data->flag & LIMIT_XMAX) {
1453 if (size[0] > data->xmax)
1454 size[0] = data->xmax;
1456 if (data->flag & LIMIT_YMIN) {
1457 if (size[1] < data->ymin)
1458 size[1] = data->ymin;
1460 if (data->flag & LIMIT_YMAX) {
1461 if (size[1] > data->ymax)
1462 size[1] = data->ymax;
1464 if (data->flag & LIMIT_ZMIN) {
1465 if (size[2] < data->zmin)
1466 size[2] = data->zmin;
1468 if (data->flag & LIMIT_ZMAX) {
1469 if (size[2] > data->zmax)
1470 size[2] = data->zmax;
1474 mul_v3_fl(cob->matrix[0], size[0]/obsize[0]);
1476 mul_v3_fl(cob->matrix[1], size[1]/obsize[1]);
1478 mul_v3_fl(cob->matrix[2], size[2]/obsize[2]);
1481 static bConstraintTypeInfo CTI_SIZELIMIT = {
1482 CONSTRAINT_TYPE_SIZELIMIT, /* type */
1483 sizeof(bSizeLimitConstraint), /* size */
1484 "Limit Scaling", /* name */
1485 "bSizeLimitConstraint", /* struct name */
1486 NULL, /* free data */
1487 NULL, /* relink data */
1488 NULL, /* id looper */
1489 NULL, /* copy data */
1490 NULL, /* new data */
1491 NULL, /* get constraint targets */
1492 NULL, /* flush constraint targets */
1493 NULL, /* get target matrix */
1494 sizelimit_evaluate /* evaluate */
1497 /* ----------- Copy Location ------------- */
1499 static void loclike_new_data (void *cdata)
1501 bLocateLikeConstraint *data= (bLocateLikeConstraint *)cdata;
1503 data->flag = LOCLIKE_X|LOCLIKE_Y|LOCLIKE_Z;
1506 static void loclike_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
1508 bLocateLikeConstraint *data= con->data;
1511 func(con, (ID**)&data->tar, userdata);
1514 static int loclike_get_tars (bConstraint *con, ListBase *list)
1517 bLocateLikeConstraint *data= con->data;
1518 bConstraintTarget *ct;
1520 /* standard target-getting macro for single-target constraints */
1521 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
1529 static void loclike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1532 bLocateLikeConstraint *data= con->data;
1533 bConstraintTarget *ct= list->first;
1535 /* the following macro is used for all standard single-target constraints */
1536 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
1540 static void loclike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1542 bLocateLikeConstraint *data= con->data;
1543 bConstraintTarget *ct= targets->first;
1545 if (VALID_CONS_TARGET(ct)) {
1546 float offset[3] = {0.0f, 0.0f, 0.0f};
1548 if (data->flag & LOCLIKE_OFFSET)
1549 copy_v3_v3(offset, cob->matrix[3]);
1551 if (data->flag & LOCLIKE_X) {
1552 cob->matrix[3][0] = ct->matrix[3][0];
1554 if (data->flag & LOCLIKE_X_INVERT) cob->matrix[3][0] *= -1;
1555 cob->matrix[3][0] += offset[0];
1557 if (data->flag & LOCLIKE_Y) {
1558 cob->matrix[3][1] = ct->matrix[3][1];
1560 if (data->flag & LOCLIKE_Y_INVERT) cob->matrix[3][1] *= -1;
1561 cob->matrix[3][1] += offset[1];
1563 if (data->flag & LOCLIKE_Z) {
1564 cob->matrix[3][2] = ct->matrix[3][2];
1566 if (data->flag & LOCLIKE_Z_INVERT) cob->matrix[3][2] *= -1;
1567 cob->matrix[3][2] += offset[2];
1572 static bConstraintTypeInfo CTI_LOCLIKE = {
1573 CONSTRAINT_TYPE_LOCLIKE, /* type */
1574 sizeof(bLocateLikeConstraint), /* size */
1575 "Copy Location", /* name */
1576 "bLocateLikeConstraint", /* struct name */
1577 NULL, /* free data */
1578 NULL, /* relink data */
1579 loclike_id_looper, /* id looper */
1580 NULL, /* copy data */
1581 loclike_new_data, /* new data */
1582 loclike_get_tars, /* get constraint targets */
1583 loclike_flush_tars, /* flush constraint targets */
1584 default_get_tarmat, /* get target matrix */
1585 loclike_evaluate /* evaluate */
1588 /* ----------- Copy Rotation ------------- */
1590 static void rotlike_new_data (void *cdata)
1592 bRotateLikeConstraint *data= (bRotateLikeConstraint *)cdata;
1594 data->flag = ROTLIKE_X|ROTLIKE_Y|ROTLIKE_Z;
1597 static void rotlike_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
1599 bChildOfConstraint *data= con->data;
1602 func(con, (ID**)&data->tar, userdata);
1605 static int rotlike_get_tars (bConstraint *con, ListBase *list)
1608 bRotateLikeConstraint *data= con->data;
1609 bConstraintTarget *ct;
1611 /* standard target-getting macro for single-target constraints */
1612 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
1620 static void rotlike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1623 bRotateLikeConstraint *data= con->data;
1624 bConstraintTarget *ct= list->first;
1626 /* the following macro is used for all standard single-target constraints */
1627 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
1631 static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1633 bRotateLikeConstraint *data= con->data;
1634 bConstraintTarget *ct= targets->first;
1636 if (VALID_CONS_TARGET(ct)) {
1638 float eul[3], obeul[3];
1641 copy_v3_v3(loc, cob->matrix[3]);
1642 mat4_to_size(size, cob->matrix);
1644 /* to allow compatible rotations, must get both rotations in the order of the owner... */
1645 mat4_to_eulO(obeul, cob->rotOrder, cob->matrix);
1646 /* we must get compatible eulers from the beginning because some of them can be modified below (see bug #21875) */
1647 mat4_to_compatible_eulO(eul, obeul, cob->rotOrder, ct->matrix);
1649 if ((data->flag & ROTLIKE_X)==0)
1652 if (data->flag & ROTLIKE_OFFSET)
1653 rotate_eulO(eul, cob->rotOrder, 'X', obeul[0]);
1655 if (data->flag & ROTLIKE_X_INVERT)
1659 if ((data->flag & ROTLIKE_Y)==0)
1662 if (data->flag & ROTLIKE_OFFSET)
1663 rotate_eulO(eul, cob->rotOrder, 'Y', obeul[1]);
1665 if (data->flag & ROTLIKE_Y_INVERT)
1669 if ((data->flag & ROTLIKE_Z)==0)
1672 if (data->flag & ROTLIKE_OFFSET)
1673 rotate_eulO(eul, cob->rotOrder, 'Z', obeul[2]);
1675 if (data->flag & ROTLIKE_Z_INVERT)
1679 /* good to make eulers compatible again, since we don't know how much they were changed above */
1680 compatible_eul(eul, obeul);
1681 loc_eulO_size_to_mat4(cob->matrix, loc, eul, size, cob->rotOrder);
1685 static bConstraintTypeInfo CTI_ROTLIKE = {
1686 CONSTRAINT_TYPE_ROTLIKE, /* type */
1687 sizeof(bRotateLikeConstraint), /* size */
1688 "Copy Rotation", /* name */
1689 "bRotateLikeConstraint", /* struct name */
1690 NULL, /* free data */
1691 NULL, /* relink data */
1692 rotlike_id_looper, /* id looper */
1693 NULL, /* copy data */
1694 rotlike_new_data, /* new data */
1695 rotlike_get_tars, /* get constraint targets */
1696 rotlike_flush_tars, /* flush constraint targets */
1697 default_get_tarmat, /* get target matrix */
1698 rotlike_evaluate /* evaluate */
1701 /* ---------- Copy Scaling ---------- */
1703 static void sizelike_new_data (void *cdata)
1705 bSizeLikeConstraint *data= (bSizeLikeConstraint *)cdata;
1707 data->flag = SIZELIKE_X|SIZELIKE_Y|SIZELIKE_Z;
1710 static void sizelike_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
1712 bSizeLikeConstraint *data= con->data;
1715 func(con, (ID**)&data->tar, userdata);
1718 static int sizelike_get_tars (bConstraint *con, ListBase *list)
1721 bSizeLikeConstraint *data= con->data;
1722 bConstraintTarget *ct;
1724 /* standard target-getting macro for single-target constraints */
1725 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
1733 static void sizelike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1736 bSizeLikeConstraint *data= con->data;
1737 bConstraintTarget *ct= list->first;
1739 /* the following macro is used for all standard single-target constraints */
1740 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
1744 static void sizelike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1746 bSizeLikeConstraint *data= con->data;
1747 bConstraintTarget *ct= targets->first;
1749 if (VALID_CONS_TARGET(ct)) {
1750 float obsize[3], size[3];
1752 mat4_to_size(size, ct->matrix);
1753 mat4_to_size(obsize, cob->matrix);
1755 if ((data->flag & SIZELIKE_X) && (obsize[0] != 0)) {
1756 if (data->flag & SIZELIKE_OFFSET) {
1757 size[0] += (obsize[0] - 1.0f);
1758 mul_v3_fl(cob->matrix[0], size[0] / obsize[0]);
1761 mul_v3_fl(cob->matrix[0], size[0] / obsize[0]);
1763 if ((data->flag & SIZELIKE_Y) && (obsize[1] != 0)) {
1764 if (data->flag & SIZELIKE_OFFSET) {
1765 size[1] += (obsize[1] - 1.0f);
1766 mul_v3_fl(cob->matrix[1], size[1] / obsize[1]);
1769 mul_v3_fl(cob->matrix[1], size[1] / obsize[1]);
1771 if ((data->flag & SIZELIKE_Z) && (obsize[2] != 0)) {
1772 if (data->flag & SIZELIKE_OFFSET) {
1773 size[2] += (obsize[2] - 1.0f);
1774 mul_v3_fl(cob->matrix[2], size[2] / obsize[2]);
1777 mul_v3_fl(cob->matrix[2], size[2] / obsize[2]);
1782 static bConstraintTypeInfo CTI_SIZELIKE = {
1783 CONSTRAINT_TYPE_SIZELIKE, /* type */
1784 sizeof(bSizeLikeConstraint), /* size */
1785 "Copy Scale", /* name */
1786 "bSizeLikeConstraint", /* struct name */
1787 NULL, /* free data */
1788 NULL, /* relink data */
1789 sizelike_id_looper, /* id looper */
1790 NULL, /* copy data */
1791 sizelike_new_data, /* new data */
1792 sizelike_get_tars, /* get constraint targets */
1793 sizelike_flush_tars, /* flush constraint targets */
1794 default_get_tarmat, /* get target matrix */
1795 sizelike_evaluate /* evaluate */
1798 /* ----------- Copy Transforms ------------- */
1800 static void translike_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
1802 bTransLikeConstraint *data= con->data;
1805 func(con, (ID**)&data->tar, userdata);
1808 static int translike_get_tars (bConstraint *con, ListBase *list)
1811 bTransLikeConstraint *data= con->data;
1812 bConstraintTarget *ct;
1814 /* standard target-getting macro for single-target constraints */
1815 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
1823 static void translike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1826 bTransLikeConstraint *data= con->data;
1827 bConstraintTarget *ct= list->first;
1829 /* the following macro is used for all standard single-target constraints */
1830 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
1834 static void translike_evaluate (bConstraint *UNUSED(con), bConstraintOb *cob, ListBase *targets)
1836 bConstraintTarget *ct= targets->first;
1838 if (VALID_CONS_TARGET(ct)) {
1839 /* just copy the entire transform matrix of the target */
1840 copy_m4_m4(cob->matrix, ct->matrix);
1844 static bConstraintTypeInfo CTI_TRANSLIKE = {
1845 CONSTRAINT_TYPE_TRANSLIKE, /* type */
1846 sizeof(bTransLikeConstraint), /* size */
1847 "Copy Transforms", /* name */
1848 "bTransLikeConstraint", /* struct name */
1849 NULL, /* free data */
1850 NULL, /* relink data */
1851 translike_id_looper, /* id looper */
1852 NULL, /* copy data */
1853 NULL, /* new data */
1854 translike_get_tars, /* get constraint targets */
1855 translike_flush_tars, /* flush constraint targets */
1856 default_get_tarmat, /* get target matrix */
1857 translike_evaluate /* evaluate */
1860 /* ---------- Maintain Volume ---------- */
1862 static void samevolume_new_data (void *cdata)
1864 bSameVolumeConstraint *data= (bSameVolumeConstraint *)cdata;
1866 data->flag = SAMEVOL_Y;
1867 data->volume = 1.0f;
1870 static void samevolume_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
1872 bSameVolumeConstraint *data= con->data;
1874 float volume = data->volume;
1878 mat4_to_size(obsize, cob->matrix);
1880 /* calculate normalising scale factor for non-essential values */
1881 if (obsize[data->flag] != 0)
1882 fac = sqrt(volume / obsize[data->flag]) / obsize[data->flag];
1884 /* apply scaling factor to the channels not being kept */
1885 switch (data->flag) {
1887 mul_v3_fl(cob->matrix[1], fac);
1888 mul_v3_fl(cob->matrix[2], fac);
1891 mul_v3_fl(cob->matrix[0], fac);
1892 mul_v3_fl(cob->matrix[2], fac);
1895 mul_v3_fl(cob->matrix[0], fac);
1896 mul_v3_fl(cob->matrix[1], fac);
1901 static bConstraintTypeInfo CTI_SAMEVOL = {
1902 CONSTRAINT_TYPE_SAMEVOL, /* type */
1903 sizeof(bSameVolumeConstraint), /* size */
1904 "Maintain Volume", /* name */
1905 "bSameVolumeConstraint", /* struct name */
1906 NULL, /* free data */
1907 NULL, /* relink data */
1908 NULL, /* id looper */
1909 NULL, /* copy data */
1910 samevolume_new_data, /* new data */
1911 NULL, /* get constraint targets */
1912 NULL, /* flush constraint targets */
1913 NULL, /* get target matrix */
1914 samevolume_evaluate /* evaluate */
1917 /* ----------- Python Constraint -------------- */
1919 static void pycon_free (bConstraint *con)
1921 bPythonConstraint *data= con->data;
1924 IDP_FreeProperty(data->prop);
1925 MEM_freeN(data->prop);
1927 /* multiple targets */
1928 BLI_freelistN(&data->targets);
1931 static void pycon_relink (bConstraint *con)
1933 bPythonConstraint *data= con->data;
1938 static void pycon_copy (bConstraint *con, bConstraint *srccon)
1940 bPythonConstraint *pycon = (bPythonConstraint *)con->data;
1941 bPythonConstraint *opycon = (bPythonConstraint *)srccon->data;
1943 pycon->prop = IDP_CopyProperty(opycon->prop);
1944 BLI_duplicatelist(&pycon->targets, &opycon->targets);
1947 static void pycon_new_data (void *cdata)
1949 bPythonConstraint *data= (bPythonConstraint *)cdata;
1951 /* everything should be set correctly by calloc, except for the prop->type constant.*/
1952 data->prop = MEM_callocN(sizeof(IDProperty), "PyConstraintProps");
1953 data->prop->type = IDP_GROUP;
1956 static int pycon_get_tars (bConstraint *con, ListBase *list)
1959 bPythonConstraint *data= con->data;
1961 list->first = data->targets.first;
1962 list->last = data->targets.last;
1964 return data->tarnum;
1970 static void pycon_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
1972 bPythonConstraint *data= con->data;
1973 bConstraintTarget *ct;
1976 for (ct= data->targets.first; ct; ct= ct->next)
1977 func(con, (ID**)&ct->tar, userdata);
1980 func(con, (ID**)&data->text, userdata);
1983 /* Whether this approach is maintained remains to be seen (aligorith) */
1984 static void pycon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
1987 bPythonConstraint *data= con->data;
1990 if (VALID_CONS_TARGET(ct)) {
1991 /* special exception for curves - depsgraph issues */
1992 if (ct->tar->type == OB_CURVE) {
1993 Curve *cu= ct->tar->data;
1995 /* this check is to make sure curve objects get updated on file load correctly.*/
1996 if (cu->path==NULL || cu->path->data==NULL) /* only happens on reload file, but violates depsgraph still... fix! */
1997 makeDispListCurveTypes(cob->scene, ct->tar, 0);
2000 /* firstly calculate the matrix the normal way, then let the py-function override
2001 * this matrix if it needs to do so
2003 constraint_target_to_mat4(cob->scene, ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
2005 /* only execute target calculation if allowed */
2007 if (G.f & G_SCRIPT_AUTOEXEC)
2008 BPY_pyconstraint_target(data, ct);
2012 unit_m4(ct->matrix);
2015 static void pycon_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
2018 (void)con; (void)cob; (void)targets; /* unused */
2021 bPythonConstraint *data= con->data;
2023 /* only evaluate in python if we're allowed to do so */
2024 if ((G.f & G_SCRIPT_AUTOEXEC)==0) return;
2026 /* currently removed, until I this can be re-implemented for multiple targets */
2028 /* Firstly, run the 'driver' function which has direct access to the objects involved
2029 * Technically, this is potentially dangerous as users may abuse this and cause dependency-problems,
2030 * but it also allows certain 'clever' rigging hacks to work.
2032 BPY_pyconstraint_driver(data, cob, targets);
2035 /* Now, run the actual 'constraint' function, which should only access the matrices */
2036 BPY_pyconstraint_eval(data, cob, targets);
2037 #endif /* WITH_PYTHON */
2040 static bConstraintTypeInfo CTI_PYTHON = {
2041 CONSTRAINT_TYPE_PYTHON, /* type */
2042 sizeof(bPythonConstraint), /* size */
2043 "Script", /* name */
2044 "bPythonConstraint", /* struct name */
2045 pycon_free, /* free data */
2046 pycon_relink, /* relink data */
2047 pycon_id_looper, /* id looper */
2048 pycon_copy, /* copy data */
2049 pycon_new_data, /* new data */
2050 pycon_get_tars, /* get constraint targets */
2051 NULL, /* flush constraint targets */
2052 pycon_get_tarmat, /* get target matrix */
2053 pycon_evaluate /* evaluate */
2056 /* -------- Action Constraint ----------- */
2058 static void actcon_relink (bConstraint *con)
2060 bActionConstraint *data= con->data;
2064 static void actcon_new_data (void *cdata)
2066 bActionConstraint *data= (bActionConstraint *)cdata;
2068 /* set type to 20 (Loc X), as 0 is Rot X for backwards compatability */
2072 static void actcon_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
2074 bActionConstraint *data= con->data;
2077 func(con, (ID**)&data->tar, userdata);
2080 func(con, (ID**)&data->act, userdata);
2083 static int actcon_get_tars (bConstraint *con, ListBase *list)
2086 bActionConstraint *data= con->data;
2087 bConstraintTarget *ct;
2089 /* standard target-getting macro for single-target constraints */
2090 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
2098 static void actcon_flush_tars (bConstraint *con, ListBase *list, short nocopy)
2101 bActionConstraint *data= con->data;
2102 bConstraintTarget *ct= list->first;
2104 /* the following macro is used for all standard single-target constraints */
2105 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
2109 static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
2111 extern void chan_calc_mat(bPoseChannel *chan);
2112 bActionConstraint *data = con->data;
2114 if (VALID_CONS_TARGET(ct)) {
2115 float tempmat[4][4], vec[3];
2119 /* initialise return matrix */
2120 unit_m4(ct->matrix);
2122 /* get the transform matrix of the target */
2123 constraint_target_to_mat4(cob->scene, ct->tar, ct->subtarget, tempmat, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
2125 /* determine where in transform range target is */
2126 /* data->type is mapped as follows for backwards compatability:
2127 * 00,01,02 - rotation (it used to be like this)
2128 * 10,11,12 - scaling
2129 * 20,21,22 - location
2131 if (data->type < 10) {
2132 /* extract rotation (is in whatever space target should be in) */
2133 mat4_to_eul(vec, tempmat);
2134 vec[0] *= (float)(180.0/M_PI);
2135 vec[1] *= (float)(180.0/M_PI);
2136 vec[2] *= (float)(180.0/M_PI);
2139 else if (data->type < 20) {
2140 /* extract scaling (is in whatever space target should be in) */
2141 mat4_to_size(vec, tempmat);
2142 axis= data->type - 10;
2145 /* extract location */
2146 copy_v3_v3(vec, tempmat[3]);
2147 axis= data->type - 20;
2150 /* Target defines the animation */
2151 s = (vec[axis]-data->min) / (data->max-data->min);
2153 t = (s * (data->end-data->start)) + data->start;
2156 printf("do Action Constraint %s - Ob %s Pchan %s \n", con->name, cob->ob->id.name+2, (cob->pchan)?cob->pchan->name:NULL);
2158 /* Get the appropriate information from the action */
2159 if (cob->type == CONSTRAINT_OBTYPE_BONE) {
2162 bPoseChannel *pchan, *tchan;
2164 /* make a temporary pose and evaluate using that */
2165 pose = MEM_callocN(sizeof(bPose), "pose");
2167 /* make a copy of the bone of interest in the temp pose before evaluating action, so that it can get set
2168 * - we need to manually copy over a few settings, including rotation order, otherwise this fails
2172 tchan= verify_pose_channel(pose, pchan->name);
2173 tchan->rotmode= pchan->rotmode;
2175 /* evaluate action using workob (it will only set the PoseChannel in question) */
2176 what_does_obaction(cob->scene, cob->ob, &workob, pose, data->act, pchan->name, t);
2178 /* convert animation to matrices for use here */
2179 chan_calc_mat(tchan);
2180 copy_m4_m4(ct->matrix, tchan->chan_mat);
2185 else if (cob->type == CONSTRAINT_OBTYPE_OBJECT) {
2188 /* evaluate using workob */
2189 // FIXME: we don't have any consistent standards on limiting effects on object...
2190 what_does_obaction(cob->scene, cob->ob, &workob, NULL, data->act, NULL, t);
2191 object_to_mat4(&workob, ct->matrix);
2194 /* behaviour undefined... */
2195 puts("Error: unknown owner type for Action Constraint");
2200 static void actcon_evaluate (bConstraint *UNUSED(con), bConstraintOb *cob, ListBase *targets)
2202 bConstraintTarget *ct= targets->first;
2204 if (VALID_CONS_TARGET(ct)) {
2207 /* Nice and simple... we just need to multiply the matrices, as the get_target_matrix
2208 * function has already taken care of everything else.
2210 copy_m4_m4(temp, cob->matrix);
2211 mul_m4_m4m4(cob->matrix, ct->matrix, temp);
2215 static bConstraintTypeInfo CTI_ACTION = {
2216 CONSTRAINT_TYPE_ACTION, /* type */
2217 sizeof(bActionConstraint), /* size */
2218 "Action", /* name */
2219 "bActionConstraint", /* struct name */
2220 NULL, /* free data */
2221 actcon_relink, /* relink data */
2222 actcon_id_looper, /* id looper */
2223 NULL, /* copy data */
2224 actcon_new_data, /* new data */
2225 actcon_get_tars, /* get constraint targets */
2226 actcon_flush_tars, /* flush constraint targets */
2227 actcon_get_tarmat, /* get target matrix */
2228 actcon_evaluate /* evaluate */
2231 /* --------- Locked Track ---------- */
2233 static void locktrack_new_data (void *cdata)
2235 bLockTrackConstraint *data= (bLockTrackConstraint *)cdata;
2237 data->trackflag = TRACK_Y;
2238 data->lockflag = LOCK_Z;
2241 static void locktrack_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
2243 bLockTrackConstraint *data= con->data;
2246 func(con, (ID**)&data->tar, userdata);
2249 static int locktrack_get_tars (bConstraint *con, ListBase *list)
2252 bLockTrackConstraint *data= con->data;
2253 bConstraintTarget *ct;
2255 /* the following macro is used for all standard single-target constraints */
2256 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
2264 static void locktrack_flush_tars (bConstraint *con, ListBase *list, short nocopy)
2267 bLockTrackConstraint *data= con->data;
2268 bConstraintTarget *ct= list->first;
2270 /* the following macro is used for all standard single-target constraints */
2271 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
2275 static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
2277 bLockTrackConstraint *data= con->data;
2278 bConstraintTarget *ct= targets->first;
2280 if (VALID_CONS_TARGET(ct)) {
2281 float vec[3],vec2[3];
2288 /* Vector object -> target */
2289 sub_v3_v3v3(vec, ct->matrix[3], cob->matrix[3]);
2290 switch (data->lockflag){
2291 case LOCK_X: /* LOCK X */
2293 switch (data->trackflag) {
2294 case TRACK_Y: /* LOCK X TRACK Y */
2296 /* Projection of Vector on the plane */
2297 project_v3_v3v3(vec2, vec, cob->matrix[0]);
2298 sub_v3_v3v3(totmat[1], vec, vec2);
2299 normalize_v3(totmat[1]);
2301 /* the x axis is fixed */
2302 normalize_v3_v3(totmat[0], cob->matrix[0]);
2304 /* the z axis gets mapped onto a third orthogonal vector */
2305 cross_v3_v3v3(totmat[2], totmat[0], totmat[1]);
2308 case TRACK_Z: /* LOCK X TRACK Z */
2310 /* Projection of Vector on the plane */
2311 project_v3_v3v3(vec2, vec, cob->matrix[0]);
2312 sub_v3_v3v3(totmat[2], vec, vec2);
2313 normalize_v3(totmat[2]);
2315 /* the x axis is fixed */
2316 normalize_v3_v3(totmat[0], cob->matrix[0]);
2318 /* the z axis gets mapped onto a third orthogonal vector */
2319 cross_v3_v3v3(totmat[1], totmat[2], totmat[0]);
2322 case TRACK_nY: /* LOCK X TRACK -Y */
2324 /* Projection of Vector on the plane */
2325 project_v3_v3v3(vec2, vec, cob->matrix[0]);
2326 sub_v3_v3v3(totmat[1], vec, vec2);
2327 normalize_v3(totmat[1]);
2328 negate_v3(totmat[1]);
2330 /* the x axis is fixed */
2331 normalize_v3_v3(totmat[0], cob->matrix[0]);
2333 /* the z axis gets mapped onto a third orthogonal vector */
2334 cross_v3_v3v3(totmat[2], totmat[0], totmat[1]);
2337 case TRACK_nZ: /* LOCK X TRACK -Z */
2339 /* Projection of Vector on the plane */
2340 project_v3_v3v3(vec2, vec, cob->matrix[0]);
2341 sub_v3_v3v3(totmat[2], vec, vec2);
2342 normalize_v3(totmat[2]);
2343 negate_v3(totmat[2]);
2345 /* the x axis is fixed */
2346 normalize_v3_v3(totmat[0], cob->matrix[0]);
2348 /* the z axis gets mapped onto a third orthogonal vector */
2349 cross_v3_v3v3(totmat[1], totmat[2], totmat[0]);
2360 case LOCK_Y: /* LOCK Y */
2362 switch (data->trackflag) {
2363 case TRACK_X: /* LOCK Y TRACK X */
2365 /* Projection of Vector on the plane */
2366 project_v3_v3v3(vec2, vec, cob->matrix[1]);
2367 sub_v3_v3v3(totmat[0], vec, vec2);
2368 normalize_v3(totmat[0]);
2370 /* the y axis is fixed */
2371 normalize_v3_v3(totmat[1], cob->matrix[1]);
2373 /* the z axis gets mapped onto a third orthogonal vector */
2374 cross_v3_v3v3(totmat[2], totmat[0], totmat[1]);
2377 case TRACK_Z: /* LOCK Y TRACK Z */
2379 /* Projection of Vector on the plane */
2380 project_v3_v3v3(vec2, vec, cob->matrix[1]);
2381 sub_v3_v3v3(totmat[2], vec, vec2);
2382 normalize_v3(totmat[2]);
2384 /* the y axis is fixed */
2385 normalize_v3_v3(totmat[1], cob->matrix[1]);
2387 /* the z axis gets mapped onto a third orthogonal vector */
2388 cross_v3_v3v3(totmat[0], totmat[1], totmat[2]);
2391 case TRACK_nX: /* LOCK Y TRACK -X */
2393 /* Projection of Vector on the plane */
2394 project_v3_v3v3(vec2, vec, cob->matrix[1]);
2395 sub_v3_v3v3(totmat[0], vec, vec2);
2396 normalize_v3(totmat[0]);
2397 negate_v3(totmat[0]);
2399 /* the y axis is fixed */
2400 normalize_v3_v3(totmat[1], cob->matrix[1]);
2402 /* the z axis gets mapped onto a third orthogonal vector */
2403 cross_v3_v3v3(totmat[2], totmat[0], totmat[1]);
2406 case TRACK_nZ: /* LOCK Y TRACK -Z */
2408 /* Projection of Vector on the plane */
2409 project_v3_v3v3(vec2, vec, cob->matrix[1]);
2410 sub_v3_v3v3(totmat[2], vec, vec2);
2411 normalize_v3(totmat[2]);
2412 negate_v3(totmat[2]);
2414 /* the y axis is fixed */
2415 normalize_v3_v3(totmat[1], cob->matrix[1]);
2417 /* the z axis gets mapped onto a third orthogonal vector */
2418 cross_v3_v3v3(totmat[0], totmat[1], totmat[2]);
2429 case LOCK_Z: /* LOCK Z */
2431 switch (data->trackflag) {
2432 case TRACK_X: /* LOCK Z TRACK X */
2434 /* Projection of Vector on the plane */
2435 project_v3_v3v3(vec2, vec, cob->matrix[2]);
2436 sub_v3_v3v3(totmat[0], vec, vec2);
2437 normalize_v3(totmat[0]);
2439 /* the z axis is fixed */
2440 normalize_v3_v3(totmat[2], cob->matrix[2]);
2442 /* the x axis gets mapped onto a third orthogonal vector */
2443 cross_v3_v3v3(totmat[1], totmat[2], totmat[0]);
2446 case TRACK_Y: /* LOCK Z TRACK Y */
2448 /* Projection of Vector on the plane */
2449 project_v3_v3v3(vec2, vec, cob->matrix[2]);
2450 sub_v3_v3v3(totmat[1], vec, vec2);
2451 normalize_v3(totmat[1]);
2453 /* the z axis is fixed */
2454 normalize_v3_v3(totmat[2], cob->matrix[2]);
2456 /* the x axis gets mapped onto a third orthogonal vector */
2457 cross_v3_v3v3(totmat[0], totmat[1], totmat[2]);
2460 case TRACK_nX: /* LOCK Z TRACK -X */
2462 /* Projection of Vector on the plane */
2463 project_v3_v3v3(vec2, vec, cob->matrix[2]);
2464 sub_v3_v3v3(totmat[0], vec, vec2);
2465 normalize_v3(totmat[0]);
2466 negate_v3(totmat[0]);
2468 /* the z axis is fixed */
2469 normalize_v3_v3(totmat[2], cob->matrix[2]);
2471 /* the x axis gets mapped onto a third orthogonal vector */
2472 cross_v3_v3v3(totmat[1], totmat[2], totmat[0]);
2475 case TRACK_nY: /* LOCK Z TRACK -Y */
2477 /* Projection of Vector on the plane */
2478 project_v3_v3v3(vec2, vec, cob->matrix[2]);
2479 sub_v3_v3v3(totmat[1], vec, vec2);
2480 normalize_v3(totmat[1]);
2481 negate_v3(totmat[1]);
2483 /* the z axis is fixed */
2484 normalize_v3_v3(totmat[2], cob->matrix[2]);
2486 /* the x axis gets mapped onto a third orthogonal vector */
2487 cross_v3_v3v3(totmat[0], totmat[1], totmat[2]);
2504 /* Block to keep matrix heading */
2505 copy_m3_m4(tmpmat, cob->matrix);
2506 normalize_m3(tmpmat);
2507 invert_m3_m3(invmat, tmpmat);
2508 mul_m3_m3m3(tmpmat, totmat, invmat);
2509 totmat[0][0] = tmpmat[0][0];totmat[0][1] = tmpmat[0][1];totmat[0][2] = tmpmat[0][2];
2510 totmat[1][0] = tmpmat[1][0];totmat[1][1] = tmpmat[1][1];totmat[1][2] = tmpmat[1][2];
2511 totmat[2][0] = tmpmat[2][0];totmat[2][1] = tmpmat[2][1];totmat[2][2] = tmpmat[2][2];
2513 copy_m4_m4(tmat, cob->matrix);
2515 mdet = determinant_m3( totmat[0][0],totmat[0][1],totmat[0][2],
2516 totmat[1][0],totmat[1][1],totmat[1][2],
2517 totmat[2][0],totmat[2][1],totmat[2][2]);
2522 /* apply out transformaton to the object */
2523 mul_m4_m3m4(cob->matrix, totmat, tmat);
2527 static bConstraintTypeInfo CTI_LOCKTRACK = {
2528 CONSTRAINT_TYPE_LOCKTRACK, /* type */
2529 sizeof(bLockTrackConstraint), /* size */
2530 "Locked Track", /* name */
2531 "bLockTrackConstraint", /* struct name */
2532 NULL, /* free data */
2533 NULL, /* relink data */
2534 locktrack_id_looper, /* id looper */
2535 NULL, /* copy data */
2536 locktrack_new_data, /* new data */
2537 locktrack_get_tars, /* get constraint targets */
2538 locktrack_flush_tars, /* flush constraint targets */
2539 default_get_tarmat, /* get target matrix */
2540 locktrack_evaluate /* evaluate */
2543 /* ---------- Limit Distance Constraint ----------- */
2545 static void distlimit_new_data (void *cdata)
2547 bDistLimitConstraint *data= (bDistLimitConstraint *)cdata;
2552 static void distlimit_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
2554 bDistLimitConstraint *data= con->data;
2557 func(con, (ID**)&data->tar, userdata);
2560 static int distlimit_get_tars (bConstraint *con, ListBase *list)
2563 bDistLimitConstraint *data= con->data;
2564 bConstraintTarget *ct;
2566 /* standard target-getting macro for single-target constraints */
2567 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
2575 static void distlimit_flush_tars (bConstraint *con, ListBase *list, short nocopy)
2578 bDistLimitConstraint *data= con->data;
2579 bConstraintTarget *ct= list->first;
2581 /* the following macro is used for all standard single-target constraints */
2582 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
2586 static void distlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
2588 bDistLimitConstraint *data= con->data;
2589 bConstraintTarget *ct= targets->first;
2591 /* only evaluate if there is a target */
2592 if (VALID_CONS_TARGET(ct)) {
2593 float dvec[3], dist=0.0f, sfac=1.0f;
2594 short clamp_surf= 0;
2596 /* calculate our current distance from the target */
2597 dist= len_v3v3(cob->matrix[3], ct->matrix[3]);
2599 /* set distance (flag is only set when user demands it) */
2600 if (data->dist == 0)
2603 /* check if we're which way to clamp from, and calculate interpolation factor (if needed) */
2604 if (data->mode == LIMITDIST_OUTSIDE) {
2605 /* if inside, then move to surface */
2606 if (dist <= data->dist) {
2608 sfac= data->dist / dist;
2610 /* if soft-distance is enabled, start fading once owner is dist+softdist from the target */
2611 else if (data->flag & LIMITDIST_USESOFT) {
2612 if (dist <= (data->dist + data->soft)) {
2617 else if (data->mode == LIMITDIST_INSIDE) {
2618 /* if outside, then move to surface */
2619 if (dist >= data->dist) {
2621 sfac= data->dist / dist;
2623 /* if soft-distance is enabled, start fading once owner is dist-soft from the target */
2624 else if (data->flag & LIMITDIST_USESOFT) {
2625 // FIXME: there's a problem with "jumping" when this kicks in
2626 if (dist >= (data->dist - data->soft)) {
2627 sfac = (float)( data->soft*(1.0 - exp(-(dist - data->dist)/data->soft)) + data->dist );
2635 if (IS_EQ(dist, data->dist)==0) {
2637 sfac= data->dist / dist;
2641 /* clamp to 'surface' (i.e. move owner so that dist == data->dist) */
2643 /* simply interpolate along line formed by target -> owner */
2644 interp_v3_v3v3(dvec, ct->matrix[3], cob->matrix[3], sfac);
2646 /* copy new vector onto owner */
2647 copy_v3_v3(cob->matrix[3], dvec);
2652 static bConstraintTypeInfo CTI_DISTLIMIT = {
2653 CONSTRAINT_TYPE_DISTLIMIT, /* type */
2654 sizeof(bDistLimitConstraint), /* size */
2655 "Limit Distance", /* name */
2656 "bDistLimitConstraint", /* struct name */
2657 NULL, /* free data */
2658 NULL, /* relink data */
2659 distlimit_id_looper, /* id looper */
2660 NULL, /* copy data */
2661 distlimit_new_data, /* new data */
2662 distlimit_get_tars, /* get constraint targets */
2663 distlimit_flush_tars, /* flush constraint targets */
2664 default_get_tarmat, /* get a target matrix */
2665 distlimit_evaluate /* evaluate */
2668 /* ---------- Stretch To ------------ */
2670 static void stretchto_new_data (void *cdata)
2672 bStretchToConstraint *data= (bStretchToConstraint *)cdata;
2676 data->orglength = 0.0;
2680 static void stretchto_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
2682 bStretchToConstraint *data= con->data;
2685 func(con, (ID**)&data->tar, userdata);
2688 static int stretchto_get_tars (bConstraint *con, ListBase *list)
2691 bStretchToConstraint *data= con->data;
2692 bConstraintTarget *ct;
2694 /* standard target-getting macro for single-target constraints */
2695 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
2703 static void stretchto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
2706 bStretchToConstraint *data= con->data;
2707 bConstraintTarget *ct= list->first;
2709 /* the following macro is used for all standard single-target constraints */
2710 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
2714 static void stretchto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
2716 bStretchToConstraint *data= con->data;
2717 bConstraintTarget *ct= targets->first;
2719 /* only evaluate if there is a target */
2720 if (VALID_CONS_TARGET(ct)) {
2721 float size[3], scale[3], vec[3], xx[3], zz[3], orth[3];
2726 /* store scaling before destroying obmat */
2727 mat4_to_size(size, cob->matrix);
2729 /* store X orientation before destroying obmat */
2730 normalize_v3_v3(xx, cob->matrix[0]);
2732 /* store Z orientation before destroying obmat */
2733 normalize_v3_v3(zz, cob->matrix[2]);
2735 sub_v3_v3v3(vec, cob->matrix[3], ct->matrix[3]);
2740 dist = normalize_v3(vec);
2741 //dist = len_v3v3( ob->obmat[3], targetmat[3]);
2743 /* data->orglength==0 occurs on first run, and after 'R' button is clicked */
2744 if (data->orglength == 0)
2745 data->orglength = dist;
2746 if (data->bulge == 0)
2749 scale[1] = dist/data->orglength;
2750 switch (data->volmode) {
2751 /* volume preserving scaling */
2753 scale[0] = 1.0f - (float)sqrt(data->bulge) + (float)sqrt(data->bulge*(data->orglength/dist));
2754 scale[2] = scale[0];
2757 scale[0] = 1.0f + data->bulge * (data->orglength /dist - 1);
2762 scale[2] = 1.0f + data->bulge * (data->orglength /dist - 1);
2764 /* don't care for volume */
2769 default: /* should not happen, but in case*/
2771 } /* switch (data->volmode) */
2773 /* Clear the object's rotation and scale */
2774 cob->matrix[0][0]=size[0]*scale[0];
2775 cob->matrix[0][1]=0;
2776 cob->matrix[0][2]=0;
2777 cob->matrix[1][0]=0;
2778 cob->matrix[1][1]=size[1]*scale[1];
2779 cob->matrix[1][2]=0;
2780 cob->matrix[2][0]=0;
2781 cob->matrix[2][1]=0;
2782 cob->matrix[2][2]=size[2]*scale[2];
2784 sub_v3_v3v3(vec, cob->matrix[3], ct->matrix[3]);
2787 /* new Y aligns object target connection*/
2788 negate_v3_v3(totmat[1], vec);
2789 switch (data->plane) {
2791 /* build new Z vector */
2792 /* othogonal to "new Y" "old X! plane */
2793 cross_v3_v3v3(orth, vec, xx);
2797 copy_v3_v3(totmat[2], orth);
2799 /* we decided to keep X plane*/
2800 cross_v3_v3v3(xx, orth, vec);
2801 normalize_v3_v3(totmat[0], xx);
2804 /* build new X vector */
2805 /* othogonal to "new Y" "old Z! plane */
2806 cross_v3_v3v3(orth, vec, zz);
2810 negate_v3_v3(totmat[0], orth);
2812 /* we decided to keep Z */
2813 cross_v3_v3v3(zz, orth, vec);
2814 normalize_v3_v3(totmat[2], zz);
2816 } /* switch (data->plane) */
2818 copy_m4_m4(tmat, cob->matrix);
2819 mul_m4_m3m4(cob->matrix, totmat, tmat);
2823 static bConstraintTypeInfo CTI_STRETCHTO = {
2824 CONSTRAINT_TYPE_STRETCHTO, /* type */
2825 sizeof(bStretchToConstraint), /* size */
2826 "Stretch To", /* name */
2827 "bStretchToConstraint", /* struct name */
2828 NULL, /* free data */
2829 NULL, /* relink data */
2830 stretchto_id_looper, /* id looper */
2831 NULL, /* copy data */
2832 stretchto_new_data, /* new data */
2833 stretchto_get_tars, /* get constraint targets */
2834 stretchto_flush_tars, /* flush constraint targets */
2835 default_get_tarmat, /* get target matrix */
2836 stretchto_evaluate /* evaluate */
2839 /* ---------- Floor ------------ */
2841 static void minmax_new_data (void *cdata)
2843 bMinMaxConstraint *data= (bMinMaxConstraint *)cdata;
2845 data->minmaxflag = TRACK_Z;
2846 data->offset = 0.0f;
2847 data->cache[0] = data->cache[1] = data->cache[2] = 0.0f;
2851 static void minmax_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
2853 bMinMaxConstraint *data= con->data;
2856 func(con, (ID**)&data->tar, userdata);
2859 static int minmax_get_tars (bConstraint *con, ListBase *list)
2862 bMinMaxConstraint *data= con->data;
2863 bConstraintTarget *ct;
2865 /* standard target-getting macro for single-target constraints */
2866 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
2874 static void minmax_flush_tars (bConstraint *con, ListBase *list, short nocopy)
2877 bMinMaxConstraint *data= con->data;
2878 bConstraintTarget *ct= list->first;
2880 /* the following macro is used for all standard single-target constraints */
2881 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
2885 static void minmax_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
2887 bMinMaxConstraint *data= con->data;