2.5:
[blender.git] / source / blender / blenkernel / intern / constraint.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
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.
10  *
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.
15  *
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.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): 2007, Joshua Leung, major recode
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <stdio.h> 
31 #include <stddef.h>
32 #include <string.h>
33 #include <math.h>
34 #include <float.h>
35
36 #include "MEM_guardedalloc.h"
37
38 #include "BLI_blenlib.h"
39 #include "BLI_arithb.h"
40 #include "BLI_editVert.h"
41
42 #include "DNA_armature_types.h"
43 #include "DNA_constraint_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_action_types.h"
46 #include "DNA_curve_types.h"
47 #include "DNA_mesh_types.h"
48 #include "DNA_meshdata_types.h"
49 #include "DNA_lattice_types.h"
50 #include "DNA_scene_types.h"
51 #include "DNA_text_types.h"
52
53 #include "BKE_utildefines.h"
54 #include "BKE_action.h"
55 #include "BKE_anim.h" /* for the curve calculation part */
56 #include "BKE_armature.h"
57 #include "BKE_blender.h"
58 #include "BKE_constraint.h"
59 #include "BKE_displist.h"
60 #include "BKE_deform.h"
61 #include "BKE_DerivedMesh.h"    /* for geometry targets */
62 #include "BKE_cdderivedmesh.h" /* for geometry targets */
63 #include "BKE_object.h"
64 #include "BKE_ipo.h"
65 #include "BKE_global.h"
66 #include "BKE_library.h"
67 #include "BKE_idprop.h"
68
69 #ifndef DISABLE_PYTHON
70 #include "BPY_extern.h"
71 #endif
72
73 #include "ED_mesh.h"
74
75 #ifdef HAVE_CONFIG_H
76 #include <config.h>
77 #endif
78
79 #ifndef M_PI
80 #define M_PI            3.14159265358979323846
81 #endif
82
83
84
85 /* ************************ Constraints - General Utilities *************************** */
86 /* These functions here don't act on any specific constraints, and are therefore should/will
87  * not require any of the special function-pointers afforded by the relevant constraint 
88  * type-info structs.
89  */
90
91 /* -------------- Naming -------------- */
92
93 /* Find the first available, non-duplicate name for a given constraint */
94 void unique_constraint_name (bConstraint *con, ListBase *list)
95 {
96         BLI_uniquename(list, con, "Const", '.', offsetof(bConstraint, name), 32);
97 }
98
99 /* ----------------- Evaluation Loop Preparation --------------- */
100
101 /* package an object/bone for use in constraint evaluation */
102 /* This function MEM_calloc's a bConstraintOb struct, that will need to be freed after evaluation */
103 bConstraintOb *constraints_make_evalob (Scene *scene, Object *ob, void *subdata, short datatype)
104 {
105         bConstraintOb *cob;
106         
107         /* create regardless of whether we have any data! */
108         cob= MEM_callocN(sizeof(bConstraintOb), "bConstraintOb");
109         
110         /* for system time, part of deglobalization, code nicer later with local time (ton) */
111         cob->scene= scene;
112         
113         /* based on type of available data */
114         switch (datatype) {
115                 case CONSTRAINT_OBTYPE_OBJECT:
116                 {
117                         /* disregard subdata... calloc should set other values right */
118                         if (ob) {
119                                 cob->ob = ob;
120                                 cob->type = datatype;
121                                 Mat4CpyMat4(cob->matrix, ob->obmat);
122                         }
123                         else
124                                 Mat4One(cob->matrix);
125                         
126                         Mat4CpyMat4(cob->startmat, cob->matrix);
127                 }
128                         break;
129                 case CONSTRAINT_OBTYPE_BONE:
130                 {
131                         /* only set if we have valid bone, otherwise default */
132                         if (ob && subdata) {
133                                 cob->ob = ob;
134                                 cob->pchan = (bPoseChannel *)subdata;
135                                 cob->type = datatype;
136                                 
137                                 /* matrix in world-space */
138                                 Mat4MulMat4(cob->matrix, cob->pchan->pose_mat, ob->obmat);
139                         }
140                         else
141                                 Mat4One(cob->matrix);
142                                 
143                         Mat4CpyMat4(cob->startmat, cob->matrix);
144                 }
145                         break;
146                         
147                 default: /* other types not yet handled */
148                         Mat4One(cob->matrix);
149                         Mat4One(cob->startmat);
150                         break;
151         }
152         
153         return cob;
154 }
155
156 /* cleanup after constraint evaluation */
157 void constraints_clear_evalob (bConstraintOb *cob)
158 {
159         float delta[4][4], imat[4][4];
160         
161         /* prevent crashes */
162         if (cob == NULL) 
163                 return;
164         
165         /* calculate delta of constraints evaluation */
166         Mat4Invert(imat, cob->startmat);
167         Mat4MulMat4(delta, imat, cob->matrix);
168         
169         /* copy matrices back to source */
170         switch (cob->type) {
171                 case CONSTRAINT_OBTYPE_OBJECT:
172                 {
173                         /* cob->ob might not exist! */
174                         if (cob->ob) {
175                                 /* copy new ob-matrix back to owner */
176                                 Mat4CpyMat4(cob->ob->obmat, cob->matrix);
177                                 
178                                 /* copy inverse of delta back to owner */
179                                 Mat4Invert(cob->ob->constinv, delta);
180                         }
181                 }
182                         break;
183                 case CONSTRAINT_OBTYPE_BONE:
184                 {
185                         /* cob->ob or cob->pchan might not exist */
186                         if (cob->ob && cob->pchan) {
187                                 /* copy new pose-matrix back to owner */
188                                 Mat4MulMat4(cob->pchan->pose_mat, cob->matrix, cob->ob->imat);
189                                 
190                                 /* copy inverse of delta back to owner */
191                                 Mat4Invert(cob->pchan->constinv, delta);
192                         }
193                 }
194                         break;
195         }
196         
197         /* free tempolary struct */
198         MEM_freeN(cob);
199 }
200
201 /* -------------- Space-Conversion API -------------- */
202
203 /* This function is responsible for the correct transformations/conversions 
204  * of a matrix from one space to another for constraint evaluation.
205  * For now, this is only implemented for Objects and PoseChannels.
206  */
207 void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4], short from, short to)
208 {
209         float tempmat[4][4];
210         float diff_mat[4][4];
211         float imat[4][4];
212         
213         /* prevent crashes in these unlikely events  */
214         if (ob==NULL || mat==NULL) return;
215         /* optimise trick - check if need to do anything */
216         if (from == to) return;
217         
218         /* are we dealing with pose-channels or objects */
219         if (pchan) {
220                 /* pose channels */
221                 switch (from) {
222                         case CONSTRAINT_SPACE_WORLD: /* ---------- FROM WORLDSPACE ---------- */
223                         {
224                                 /* world to pose */
225                                 Mat4Invert(imat, ob->obmat);
226                                 Mat4CpyMat4(tempmat, mat);
227                                 Mat4MulMat4(mat, tempmat, imat);
228                                 
229                                 /* use pose-space as stepping stone for other spaces... */
230                                 if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) {
231                                         /* call self with slightly different values */
232                                         constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
233                                 }
234                         }
235                                 break;
236                         case CONSTRAINT_SPACE_POSE:     /* ---------- FROM POSESPACE ---------- */
237                         {
238                                 /* pose to world */
239                                 if (to == CONSTRAINT_SPACE_WORLD) {
240                                         Mat4CpyMat4(tempmat, mat);
241                                         Mat4MulMat4(mat, tempmat, ob->obmat);
242                                 }
243                                 /* pose to local */
244                                 else if (to == CONSTRAINT_SPACE_LOCAL) {
245                                         if (pchan->bone) {
246                                                 if (pchan->parent) {
247                                                         float offs_bone[4][4];
248                                                                 
249                                                         /* construct offs_bone the same way it is done in armature.c */
250                                                         Mat4CpyMat3(offs_bone, pchan->bone->bone_mat);
251                                                         VECCOPY(offs_bone[3], pchan->bone->head);
252                                                         offs_bone[3][1]+= pchan->bone->parent->length;
253                                                         
254                                                         if (pchan->bone->flag & BONE_HINGE) {
255                                                                 /* pose_mat = par_pose-space_location * chan_mat */
256                                                                 float tmat[4][4];
257                                                                 
258                                                                 /* the rotation of the parent restposition */
259                                                                 Mat4CpyMat4(tmat, pchan->bone->parent->arm_mat);
260                                                                 
261                                                                 /* the location of actual parent transform */
262                                                                 VECCOPY(tmat[3], offs_bone[3]);
263                                                                 offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f;
264                                                                 Mat4MulVecfl(pchan->parent->pose_mat, tmat[3]);
265                                                                 
266                                                                 Mat4MulMat4(diff_mat, offs_bone, tmat);
267                                                                 Mat4Invert(imat, diff_mat);
268                                                         }
269                                                         else {
270                                                                 /* pose_mat = par_pose_mat * bone_mat * chan_mat */
271                                                                 Mat4MulMat4(diff_mat, offs_bone, pchan->parent->pose_mat);
272                                                                 Mat4Invert(imat, diff_mat);
273                                                         }
274                                                 }
275                                                 else {
276                                                         /* pose_mat = chan_mat * arm_mat */
277                                                         Mat4Invert(imat, pchan->bone->arm_mat);
278                                                 }
279                                                 
280                                                 Mat4CpyMat4(tempmat, mat);
281                                                 Mat4MulMat4(mat, tempmat, imat);
282                                         }
283                                 }
284                                 /* pose to local with parent */
285                                 else if (to == CONSTRAINT_SPACE_PARLOCAL) {
286                                         if (pchan->bone) {
287                                                 Mat4Invert(imat, pchan->bone->arm_mat);
288                                                 Mat4CpyMat4(tempmat, mat);
289                                                 Mat4MulMat4(mat, tempmat, imat);
290                                         }
291                                 }
292                         }
293                                 break;
294                         case CONSTRAINT_SPACE_LOCAL: /* ------------ FROM LOCALSPACE --------- */
295                         {
296                                 /* local to pose - do inverse procedure that was done for pose to local */
297                                 if (pchan->bone) {
298                                         /* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */                                         
299                                         if (pchan->parent) {
300                                                 float offs_bone[4][4];
301                                                 
302                                                 /* construct offs_bone the same way it is done in armature.c */
303                                                 Mat4CpyMat3(offs_bone, pchan->bone->bone_mat);
304                                                 VECCOPY(offs_bone[3], pchan->bone->head);
305                                                 offs_bone[3][1]+= pchan->bone->parent->length;
306                                                 
307                                                 if (pchan->bone->flag & BONE_HINGE) {
308                                                         /* pose_mat = par_pose-space_location * chan_mat */
309                                                         float tmat[4][4];
310                                                         
311                                                         /* the rotation of the parent restposition */
312                                                         Mat4CpyMat4(tmat, pchan->bone->parent->arm_mat);
313                                                         
314                                                         /* the location of actual parent transform */
315                                                         VECCOPY(tmat[3], offs_bone[3]);
316                                                         offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f;
317                                                         Mat4MulVecfl(pchan->parent->pose_mat, tmat[3]);
318                                                         
319                                                         Mat4MulMat4(diff_mat, offs_bone, tmat);
320                                                         Mat4CpyMat4(tempmat, mat);
321                                                         Mat4MulMat4(mat, tempmat, diff_mat);
322                                                 }
323                                                 else {
324                                                         /* pose_mat = par_pose_mat * bone_mat * chan_mat */
325                                                         Mat4MulMat4(diff_mat, offs_bone, pchan->parent->pose_mat);
326                                                         Mat4CpyMat4(tempmat, mat);
327                                                         Mat4MulMat4(mat, tempmat, diff_mat);
328                                                 }
329                                         }
330                                         else {
331                                                 Mat4CpyMat4(diff_mat, pchan->bone->arm_mat);
332                                                 
333                                                 Mat4CpyMat4(tempmat, mat);
334                                                 Mat4MulMat4(mat, tempmat, diff_mat);
335                                         }
336                                 }
337                                 
338                                 /* use pose-space as stepping stone for other spaces */
339                                 if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL)) {
340                                         /* call self with slightly different values */
341                                         constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
342                                 }                               
343                         }
344                                 break;
345                         case CONSTRAINT_SPACE_PARLOCAL: /* -------------- FROM LOCAL WITH PARENT ---------- */
346                         {
347                                 /* local + parent to pose */
348                                 if (pchan->bone) {                                      
349                                         Mat4CpyMat4(diff_mat, pchan->bone->arm_mat);
350                                         Mat4CpyMat4(tempmat, mat);
351                                         Mat4MulMat4(mat, diff_mat, tempmat);
352                                 }
353                                 
354                                 /* use pose-space as stepping stone for other spaces */
355                                 if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL)) {
356                                         /* call self with slightly different values */
357                                         constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
358                                 }
359                         }
360                                 break;
361                 }
362         }
363         else {
364                 /* objects */
365                 if (from==CONSTRAINT_SPACE_WORLD && to==CONSTRAINT_SPACE_LOCAL) {
366                         /* check if object has a parent - otherwise this won't work */
367                         if (ob->parent) {
368                                 /* 'subtract' parent's effects from owner */
369                                 Mat4MulMat4(diff_mat, ob->parentinv, ob->parent->obmat);
370                                 Mat4Invert(imat, diff_mat);
371                                 Mat4CpyMat4(tempmat, mat);
372                                 Mat4MulMat4(mat, tempmat, imat);
373                         }
374                 }
375                 else if (from==CONSTRAINT_SPACE_LOCAL && to==CONSTRAINT_SPACE_WORLD) {
376                         /* check that object has a parent - otherwise this won't work */
377                         if (ob->parent) {
378                                 /* 'add' parent's effect back to owner */
379                                 Mat4CpyMat4(tempmat, mat);
380                                 Mat4MulMat4(diff_mat, ob->parentinv, ob->parent->obmat);
381                                 Mat4MulMat4(mat, tempmat, diff_mat);
382                         }
383                 }
384         }
385 }
386
387 /* ------------ General Target Matrix Tools ---------- */
388
389 /* function that sets the given matrix based on given vertex group in mesh */
390 static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4])
391 {
392         DerivedMesh *dm;
393         Mesh *me= ob->data;
394         EditMesh *em = BKE_mesh_get_editmesh(me);
395         float vec[3] = {0.0f, 0.0f, 0.0f}, tvec[3];
396         float normal[3] = {0.0f, 0.0f, 0.0f}, plane[3];
397         float imat[3][3], tmat[3][3];
398         int dgroup;
399         
400         /* initialize target matrix using target matrix */
401         Mat4CpyMat4(mat, ob->obmat);
402         
403         /* get index of vertex group */
404         dgroup = get_named_vertexgroup_num(ob, substring);
405         if (dgroup < 0) return;
406         
407         /* get DerivedMesh */
408         if (em) {
409                 /* target is in editmode, so get a special derived mesh */
410                 dm = CDDM_from_editmesh(em, ob->data);
411         }
412         else {
413                 /* when not in EditMode, this should exist */
414                 dm = (DerivedMesh *)ob->derivedFinal;
415         }
416         
417         /* only continue if there's a valid DerivedMesh */
418         if (dm) {
419                 MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
420                 int *index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
421                 int numVerts = dm->getNumVerts(dm);
422                 int i, j, count = 0;
423                 float co[3], nor[3];
424                 
425                 /* check that dvert and index are valid pointers (just in case) */
426                 if (dvert && index) {
427                         /* get the average of all verts with that are in the vertex-group */
428                         for (i = 0; i < numVerts; i++, index++) {       
429                                 for (j = 0; j < dvert[i].totweight; j++) {
430                                         /* does this vertex belong to nominated vertex group? */
431                                         if (dvert[i].dw[j].def_nr == dgroup) {
432                                                 dm->getVertCo(dm, i, co);
433                                                 dm->getVertNo(dm, i, nor);
434                                                 VecAddf(vec, vec, co);
435                                                 VecAddf(normal, normal, nor);
436                                                 count++;
437                                                 break;
438                                         }
439                                         
440                                 }
441                         }
442                         
443                         
444                         /* calculate averages of normal and coordinates */
445                         if (count > 0) {
446                                 VecMulf(vec, 1.0f / count);
447                                 VecMulf(normal, 1.0f / count);
448                         }
449                         
450                         
451                         /* derive the rotation from the average normal: 
452                          *              - code taken from transform_manipulator.c, 
453                          *                      calc_manipulator_stats, V3D_MANIP_NORMAL case
454                          */
455                         /*      we need the transpose of the inverse for a normal... */
456                         Mat3CpyMat4(imat, ob->obmat);
457                         
458                         Mat3Inv(tmat, imat);
459                         Mat3Transp(tmat);
460                         Mat3MulVecfl(tmat, normal);
461                         
462                         Normalize(normal);
463                         VECCOPY(plane, tmat[1]);
464                         
465                         VECCOPY(tmat[2], normal);
466                         Crossf(tmat[0], normal, plane);
467                         Crossf(tmat[1], tmat[2], tmat[0]);
468                         
469                         Mat4CpyMat3(mat, tmat);
470                         Mat4Ortho(mat);
471                         
472                         
473                         /* apply the average coordinate as the new location */
474                         VecMat4MulVecfl(tvec, ob->obmat, vec);
475                         VECCOPY(mat[3], tvec);
476                 }
477         }
478         
479         /* free temporary DerivedMesh created (in EditMode case) */
480         if (em) {
481                 if (dm) dm->release(dm);
482                 BKE_mesh_end_editmesh(me, em);
483         }
484 }
485
486 /* function that sets the given matrix based on given vertex group in lattice */
487 static void contarget_get_lattice_mat (Object *ob, char *substring, float mat[][4])
488 {
489         Lattice *lt= (Lattice *)ob->data;
490         
491         DispList *dl = find_displist(&ob->disp, DL_VERTS);
492         float *co = dl?dl->verts:NULL;
493         BPoint *bp = lt->def;
494         
495         MDeformVert *dvert = lt->dvert;
496         int tot_verts= lt->pntsu*lt->pntsv*lt->pntsw;
497         float vec[3]= {0.0f, 0.0f, 0.0f}, tvec[3];
498         int dgroup=0, grouped=0;
499         int i, n;
500         
501         /* initialize target matrix using target matrix */
502         Mat4CpyMat4(mat, ob->obmat);
503         
504         /* get index of vertex group */
505         dgroup = get_named_vertexgroup_num(ob, substring);
506         if (dgroup < 0) return;
507         if (dvert == NULL) return;
508         
509         /* 1. Loop through control-points checking if in nominated vertex-group.
510          * 2. If it is, add it to vec to find the average point.
511          */
512         for (i=0; i < tot_verts; i++, dvert++) {
513                 for (n= 0; n < dvert->totweight; n++) {
514                         /* found match - vert is in vgroup */
515                         if (dvert->dw[n].def_nr == dgroup) {
516                                 /* copy coordinates of point to temporary vector, then add to find average */
517                                 if (co)
518                                         memcpy(tvec, co, 3*sizeof(float));
519                                 else
520                                         memcpy(tvec, bp->vec, 3*sizeof(float));
521                                         
522                                 VecAddf(vec, vec, tvec);
523                                 grouped++;
524                                 
525                                 break;
526                         }
527                 }
528                 
529                 /* advance pointer to coordinate data */
530                 if (co) co+= 3;
531                 else bp++;
532         }
533         
534         /* find average location, then multiply by ob->obmat to find world-space location */
535         if (grouped)
536                 VecMulf(vec, 1.0f / grouped);
537         VecMat4MulVecfl(tvec, ob->obmat, vec);
538         
539         /* copy new location to matrix */
540         VECCOPY(mat[3], tvec);
541 }
542
543 /* generic function to get the appropriate matrix for most target cases */
544 /* The cases where the target can be object data have not been implemented */
545 static void constraint_target_to_mat4 (Object *ob, char *substring, float mat[][4], short from, short to, float headtail)
546 {
547         /*      Case OBJECT */
548         if (!strlen(substring)) {
549                 Mat4CpyMat4(mat, ob->obmat);
550                 constraint_mat_convertspace(ob, NULL, mat, from, to);
551         }
552         /*      Case VERTEXGROUP */
553         /* Current method just takes the average location of all the points in the
554          * VertexGroup, and uses that as the location value of the targets. Where 
555          * possible, the orientation will also be calculated, by calculating an
556          * 'average' vertex normal, and deriving the rotaation from that.
557          *
558          * NOTE: EditMode is not currently supported, and will most likely remain that
559          *              way as constraints can only really affect things on object/bone level.
560          */
561         else if (ob->type == OB_MESH) {
562                 contarget_get_mesh_mat(ob, substring, mat);
563                 constraint_mat_convertspace(ob, NULL, mat, from, to);
564         }
565         else if (ob->type == OB_LATTICE) {
566                 contarget_get_lattice_mat(ob, substring, mat);
567                 constraint_mat_convertspace(ob, NULL, mat, from, to);
568         }
569         /*      Case BONE */
570         else {
571                 bPoseChannel *pchan;
572                 
573                 pchan = get_pose_channel(ob->pose, substring);
574                 if (pchan) {
575                         /* Multiply the PoseSpace accumulation/final matrix for this
576                          * PoseChannel by the Armature Object's Matrix to get a worldspace
577                          * matrix.
578                          */
579                         if (headtail < 0.000001) {
580                                 /* skip length interpolation if set to head */
581                                 Mat4MulMat4(mat, pchan->pose_mat, ob->obmat);
582                         }
583                         else {
584                                 float tempmat[4][4], loc[3];
585                                 
586                                 /* interpolate along length of bone */
587                                 VecLerpf(loc, pchan->pose_head, pchan->pose_tail, headtail);    
588                                 
589                                 /* use interpolated distance for subtarget */
590                                 Mat4CpyMat4(tempmat, pchan->pose_mat);  
591                                 VecCopyf(tempmat[3], loc);
592                                 
593                                 Mat4MulMat4(mat, tempmat, ob->obmat);
594                         }
595                 } 
596                 else
597                         Mat4CpyMat4(mat, ob->obmat);
598                         
599                 /* convert matrix space as required */
600                 constraint_mat_convertspace(ob, pchan, mat, from, to);
601         }
602 }
603
604 /* ************************* Specific Constraints ***************************** */
605 /* Each constraint defines a set of functions, which will be called at the appropriate
606  * times. In addition to this, each constraint should have a type-info struct, where
607  * its functions are attached for use. 
608  */
609  
610 /* Template for type-info data:
611  *      - make a copy of this when creating new constraints, and just change the functions
612  *        pointed to as necessary
613  *      - although the naming of functions doesn't matter, it would help for code
614  *        readability, to follow the same naming convention as is presented here
615  *      - any functions that a constraint doesn't need to define, don't define
616  *        for such cases, just use NULL 
617  *      - these should be defined after all the functions have been defined, so that
618  *        forward-definitions/prototypes don't need to be used!
619  *      - keep this copy #if-def'd so that future constraints can get based off this
620  */
621 #if 0
622 static bConstraintTypeInfo CTI_CONSTRNAME = {
623         CONSTRAINT_TYPE_CONSTRNAME, /* type */
624         sizeof(bConstrNameConstraint), /* size */
625         "ConstrName", /* name */
626         "bConstrNameConstraint", /* struct name */
627         constrname_free, /* free data */
628         constrname_relink, /* relink data */
629         constrname_copy, /* copy data */
630         constrname_new_data, /* new data */
631         constrname_get_tars, /* get constraint targets */
632         constrname_flush_tars, /* flush constraint targets */
633         constrname_get_tarmat, /* get target matrix */
634         constrname_evaluate /* evaluate */
635 };
636 #endif
637
638 /* This function should be used for the get_target_matrix member of all 
639  * constraints that are not picky about what happens to their target matrix.
640  */
641 static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
642 {
643         if (VALID_CONS_TARGET(ct))
644                 constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
645         else if (ct)
646                 Mat4One(ct->matrix);
647 }
648
649 /* This following macro should be used for all standard single-target *_get_tars functions 
650  * to save typing and reduce maintainance woes.
651  * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
652  *  really just to help this code easier to read)
653  */
654 #define SINGLETARGET_GET_TARS(con, datatar, datasubtarget, ct, list) \
655         { \
656                 ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \
657                  \
658                 ct->tar= datatar; \
659                 strcpy(ct->subtarget, datasubtarget); \
660                 ct->space= con->tarspace; \
661                 ct->flag= CONSTRAINT_TAR_TEMP; \
662                  \
663                 if (ct->tar) { \
664                         if ((ct->tar->type==OB_ARMATURE) && (ct->subtarget[0])) ct->type = CONSTRAINT_OBTYPE_BONE; \
665                         else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) ct->type = CONSTRAINT_OBTYPE_VERT; \
666                         else ct->type = CONSTRAINT_OBTYPE_OBJECT; \
667                 } \
668                  \
669                 BLI_addtail(list, ct); \
670         }
671         
672 /* This following macro should be used for all standard single-target *_get_tars functions 
673  * to save typing and reduce maintainance woes. It does not do the subtarget related operations
674  * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
675  *  really just to help this code easier to read)
676  */
677 #define SINGLETARGETNS_GET_TARS(con, datatar, ct, list) \
678         { \
679                 ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \
680                  \
681                 ct->tar= datatar; \
682                 ct->space= con->tarspace; \
683                 ct->flag= CONSTRAINT_TAR_TEMP; \
684                  \
685                 if (ct->tar) ct->type = CONSTRAINT_OBTYPE_OBJECT; \
686                  \
687                 BLI_addtail(list, ct); \
688         }
689
690 /* This following macro should be used for all standard single-target *_flush_tars functions
691  * to save typing and reduce maintainance woes.
692  * Note: the pointer to ct will be changed to point to the next in the list (as it gets removed)
693  * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
694  *  really just to help this code easier to read)
695  */
696 #define SINGLETARGET_FLUSH_TARS(con, datatar, datasubtarget, ct, list, nocopy) \
697         { \
698                 if (ct) { \
699                         bConstraintTarget *ctn = ct->next; \
700                         if (nocopy == 0) { \
701                                 datatar= ct->tar; \
702                                 strcpy(datasubtarget, ct->subtarget); \
703                                 con->tarspace= (char)ct->space; \
704                         } \
705                          \
706                         BLI_freelinkN(list, ct); \
707                         ct= ctn; \
708                 } \
709         }
710         
711 /* This following macro should be used for all standard single-target *_flush_tars functions
712  * to save typing and reduce maintainance woes. It does not do the subtarget related operations.
713  * Note: the pointer to ct will be changed to point to the next in the list (as it gets removed)
714  * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
715  *  really just to help this code easier to read)
716  */
717 #define SINGLETARGETNS_FLUSH_TARS(con, datatar, ct, list, nocopy) \
718         { \
719                 if (ct) { \
720                         bConstraintTarget *ctn = ct->next; \
721                         if (nocopy == 0) { \
722                                 datatar= ct->tar; \
723                                 con->tarspace= (char)ct->space; \
724                         } \
725                          \
726                         BLI_freelinkN(list, ct); \
727                         ct= ctn; \
728                 } \
729         }
730  
731 /* --------- ChildOf Constraint ------------ */
732
733 static void childof_new_data (void *cdata)
734 {
735         bChildOfConstraint *data= (bChildOfConstraint *)cdata;
736         
737         data->flag = (CHILDOF_LOCX | CHILDOF_LOCY | CHILDOF_LOCZ |
738                                         CHILDOF_ROTX |CHILDOF_ROTY | CHILDOF_ROTZ |
739                                         CHILDOF_SIZEX | CHILDOF_SIZEY | CHILDOF_SIZEZ);
740         Mat4One(data->invmat);
741 }
742
743 static int childof_get_tars (bConstraint *con, ListBase *list)
744 {
745         if (con && list) {
746                 bChildOfConstraint *data= con->data;
747                 bConstraintTarget *ct;
748                 
749                 /* standard target-getting macro for single-target constraints */
750                 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
751                 
752                 return 1;
753         }
754         
755         return 0;
756 }
757
758 static void childof_flush_tars (bConstraint *con, ListBase *list, short nocopy)
759 {
760         if (con && list) {
761                 bChildOfConstraint *data= con->data;
762                 bConstraintTarget *ct= list->first;
763                 
764                 /* the following macro is used for all standard single-target constraints */
765                 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
766         }
767 }
768
769 static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
770 {
771         bChildOfConstraint *data= con->data;
772         bConstraintTarget *ct= targets->first;
773         
774         /* only evaluate if there is a target */
775         if (VALID_CONS_TARGET(ct)) {
776                 float parmat[4][4], invmat[4][4], tempmat[4][4];
777                 float loc[3], eul[3], size[3];
778                 float loco[3], eulo[3], sizo[3];
779                 
780                 /* get offset (parent-inverse) matrix */
781                 Mat4CpyMat4(invmat, data->invmat);
782                 
783                 /* extract components of both matrices */
784                 VECCOPY(loc, ct->matrix[3]);
785                 Mat4ToEul(ct->matrix, eul);
786                 Mat4ToSize(ct->matrix, size);
787                 
788                 VECCOPY(loco, invmat[3]);
789                 Mat4ToEul(invmat, eulo);
790                 Mat4ToSize(invmat, sizo);
791                 
792                 /* disable channels not enabled */
793                 if (!(data->flag & CHILDOF_LOCX)) loc[0]= loco[0]= 0.0f;
794                 if (!(data->flag & CHILDOF_LOCY)) loc[1]= loco[1]= 0.0f;
795                 if (!(data->flag & CHILDOF_LOCZ)) loc[2]= loco[2]= 0.0f;
796                 if (!(data->flag & CHILDOF_ROTX)) eul[0]= eulo[0]= 0.0f;
797                 if (!(data->flag & CHILDOF_ROTY)) eul[1]= eulo[1]= 0.0f;
798                 if (!(data->flag & CHILDOF_ROTZ)) eul[2]= eulo[2]= 0.0f;
799                 if (!(data->flag & CHILDOF_SIZEX)) size[0]= sizo[0]= 1.0f;
800                 if (!(data->flag & CHILDOF_SIZEY)) size[1]= sizo[1]= 1.0f;
801                 if (!(data->flag & CHILDOF_SIZEZ)) size[2]= sizo[2]= 1.0f;
802                 
803                 /* make new target mat and offset mat */
804                 LocEulSizeToMat4(ct->matrix, loc, eul, size);
805                 LocEulSizeToMat4(invmat, loco, eulo, sizo);
806                 
807                 /* multiply target (parent matrix) by offset (parent inverse) to get 
808                  * the effect of the parent that will be exherted on the owner
809                  */
810                 Mat4MulMat4(parmat, invmat, ct->matrix);
811                 
812                 /* now multiply the parent matrix by the owner matrix to get the 
813                  * the effect of this constraint (i.e.  owner is 'parented' to parent)
814                  */
815                 Mat4CpyMat4(tempmat, cob->matrix);
816                 Mat4MulMat4(cob->matrix, tempmat, parmat); 
817         }
818 }
819
820 static bConstraintTypeInfo CTI_CHILDOF = {
821         CONSTRAINT_TYPE_CHILDOF, /* type */
822         sizeof(bChildOfConstraint), /* size */
823         "ChildOf", /* name */
824         "bChildOfConstraint", /* struct name */
825         NULL, /* free data */
826         NULL, /* relink data */
827         NULL, /* copy data */
828         childof_new_data, /* new data */
829         childof_get_tars, /* get constraint targets */
830         childof_flush_tars, /* flush constraint targets */
831         default_get_tarmat, /* get a target matrix */
832         childof_evaluate /* evaluate */
833 };
834
835 /* -------- TrackTo Constraint ------- */
836
837 static void trackto_new_data (void *cdata)
838 {
839         bTrackToConstraint *data= (bTrackToConstraint *)cdata;
840         
841         data->reserved1 = TRACK_Y;
842         data->reserved2 = UP_Z;
843 }       
844
845 static int trackto_get_tars (bConstraint *con, ListBase *list)
846 {
847         if (con && list) {
848                 bTrackToConstraint *data= con->data;
849                 bConstraintTarget *ct;
850                 
851                 /* standard target-getting macro for single-target constraints */
852                 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
853                 
854                 return 1;
855         }
856         
857         return 0;
858 }
859
860 static void trackto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
861 {
862         if (con && list) {
863                 bTrackToConstraint *data= con->data;
864                 bConstraintTarget *ct= list->first;
865                 
866                 /* the following macro is used for all standard single-target constraints */
867                 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
868         }
869 }
870
871
872 static int basis_cross (int n, int m)
873 {
874         switch (n-m) {
875                 case 1: 
876                 case -2:
877                         return 1;
878                         
879                 case -1: 
880                 case 2:
881                         return -1;
882                         
883                 default:
884                         return 0;
885         }
886 }
887
888 static void vectomat (float *vec, float *target_up, short axis, short upflag, short flags, float m[][3])
889 {
890         float n[3];
891         float u[3]; /* vector specifying the up axis */
892         float proj[3];
893         float right[3];
894         float neg = -1;
895         int right_index;
896         
897         VecCopyf(n, vec);
898         if (Normalize(n) == 0.0) { 
899                 n[0] = 0.0;
900                 n[1] = 0.0;
901                 n[2] = 1.0;
902         }
903         if (axis > 2) axis -= 3;
904         else VecNegf(n);
905
906         /* n specifies the transformation of the track axis */
907         if (flags & TARGET_Z_UP) { 
908                 /* target Z axis is the global up axis */
909                 u[0] = target_up[0];
910                 u[1] = target_up[1];
911                 u[2] = target_up[2];
912         }
913         else { 
914                 /* world Z axis is the global up axis */
915                 u[0] = 0;
916                 u[1] = 0;
917                 u[2] = 1;
918         }
919
920         /* project the up vector onto the plane specified by n */
921         Projf(proj, u, n); /* first u onto n... */
922         VecSubf(proj, u, proj); /* then onto the plane */
923         /* proj specifies the transformation of the up axis */
924
925         if (Normalize(proj) == 0.0) { /* degenerate projection */
926                 proj[0] = 0.0;
927                 proj[1] = 1.0;
928                 proj[2] = 0.0;
929         }
930
931         /* Normalized cross product of n and proj specifies transformation of the right axis */
932         Crossf(right, proj, n);
933         Normalize(right);
934
935         if (axis != upflag) {
936                 right_index = 3 - axis - upflag;
937                 neg = (float)basis_cross(axis, upflag);
938                 
939                 /* account for up direction, track direction */
940                 m[right_index][0] = neg * right[0];
941                 m[right_index][1] = neg * right[1];
942                 m[right_index][2] = neg * right[2];
943                 
944                 m[upflag][0] = proj[0];
945                 m[upflag][1] = proj[1];
946                 m[upflag][2] = proj[2];
947                 
948                 m[axis][0] = n[0];
949                 m[axis][1] = n[1];
950                 m[axis][2] = n[2];
951         }
952         /* identity matrix - don't do anything if the two axes are the same */
953         else {
954                 m[0][0]= m[1][1]= m[2][2]= 1.0;
955                 m[0][1]= m[0][2]= 0.0;
956                 m[1][0]= m[1][2]= 0.0;
957                 m[2][0]= m[2][1]= 0.0;
958         }
959 }
960
961
962 static void trackto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
963 {
964         bTrackToConstraint *data= con->data;
965         bConstraintTarget *ct= targets->first;
966         
967         if (VALID_CONS_TARGET(ct)) {
968                 float size[3], vec[3];
969                 float totmat[3][3];
970                 float tmat[4][4];
971                 
972                 /* Get size property, since ob->size is only the object's own relative size, not its global one */
973                 Mat4ToSize(cob->matrix, size);
974                 
975                 /* Clear the object's rotation */       
976                 cob->matrix[0][0]=size[0];
977                 cob->matrix[0][1]=0;
978                 cob->matrix[0][2]=0;
979                 cob->matrix[1][0]=0;
980                 cob->matrix[1][1]=size[1];
981                 cob->matrix[1][2]=0;
982                 cob->matrix[2][0]=0;
983                 cob->matrix[2][1]=0;
984                 cob->matrix[2][2]=size[2];
985                 
986                 /* targetmat[2] instead of ownermat[2] is passed to vectomat
987                  * for backwards compatability it seems... (Aligorith)
988                  */
989                 VecSubf(vec, cob->matrix[3], ct->matrix[3]);
990                 vectomat(vec, ct->matrix[2], 
991                                 (short)data->reserved1, (short)data->reserved2, 
992                                 data->flags, totmat);
993                 
994                 Mat4CpyMat4(tmat, cob->matrix);
995                 Mat4MulMat34(cob->matrix, totmat, tmat);
996         }
997 }
998
999 static bConstraintTypeInfo CTI_TRACKTO = {
1000         CONSTRAINT_TYPE_TRACKTO, /* type */
1001         sizeof(bTrackToConstraint), /* size */
1002         "TrackTo", /* name */
1003         "bTrackToConstraint", /* struct name */
1004         NULL, /* free data */
1005         NULL, /* relink data */
1006         NULL, /* copy data */
1007         trackto_new_data, /* new data */
1008         trackto_get_tars, /* get constraint targets */
1009         trackto_flush_tars, /* flush constraint targets */
1010         default_get_tarmat, /* get target matrix */
1011         trackto_evaluate /* evaluate */
1012 };
1013
1014 /* --------- Inverse-Kinemetics --------- */
1015
1016 static void kinematic_new_data (void *cdata)
1017 {
1018         bKinematicConstraint *data= (bKinematicConstraint *)cdata;
1019         
1020         data->weight= (float)1.0;
1021         data->orientweight= (float)1.0;
1022         data->iterations = 500;
1023         data->flag= CONSTRAINT_IK_TIP|CONSTRAINT_IK_STRETCH|CONSTRAINT_IK_POS;
1024 }
1025
1026 static int kinematic_get_tars (bConstraint *con, ListBase *list)
1027 {
1028         if (con && list) {
1029                 bKinematicConstraint *data= con->data;
1030                 bConstraintTarget *ct;
1031                 
1032                 /* standard target-getting macro for single-target constraints is used twice here */
1033                 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
1034                 SINGLETARGET_GET_TARS(con, data->poletar, data->polesubtarget, ct, list)
1035                 
1036                 return 2;
1037         }
1038         
1039         return 0;
1040 }
1041
1042 static void kinematic_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1043 {
1044         if (con && list) {
1045                 bKinematicConstraint *data= con->data;
1046                 bConstraintTarget *ct= list->first;
1047                 
1048                 /* the following macro is used for all standard single-target constraints */
1049                 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
1050                 SINGLETARGET_FLUSH_TARS(con, data->poletar, data->polesubtarget, ct, list, nocopy)
1051         }
1052 }
1053
1054 static void kinematic_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
1055 {
1056         bKinematicConstraint *data= con->data;
1057         
1058         if (VALID_CONS_TARGET(ct)) 
1059                 constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
1060         else if (ct) {
1061                 if (data->flag & CONSTRAINT_IK_AUTO) {
1062                         Object *ob= cob->ob;
1063                         
1064                         if (ob == NULL) {
1065                                 Mat4One(ct->matrix);
1066                         }
1067                         else {
1068                                 float vec[3];
1069                                 /* move grabtarget into world space */
1070                                 VECCOPY(vec, data->grabtarget);
1071                                 Mat4MulVecfl(ob->obmat, vec);
1072                                 Mat4CpyMat4(ct->matrix, ob->obmat);
1073                                 VECCOPY(ct->matrix[3], vec);
1074                         }
1075                 }
1076                 else
1077                         Mat4One(ct->matrix);
1078         }
1079 }
1080
1081 static bConstraintTypeInfo CTI_KINEMATIC = {
1082         CONSTRAINT_TYPE_KINEMATIC, /* type */
1083         sizeof(bKinematicConstraint), /* size */
1084         "IK", /* name */
1085         "bKinematicConstraint", /* struct name */
1086         NULL, /* free data */
1087         NULL, /* relink data */
1088         NULL, /* copy data */
1089         kinematic_new_data, /* new data */
1090         kinematic_get_tars, /* get constraint targets */
1091         kinematic_flush_tars, /* flush constraint targets */
1092         kinematic_get_tarmat, /* get target matrix */
1093         NULL /* evaluate - solved as separate loop */
1094 };
1095
1096 /* -------- Follow-Path Constraint ---------- */
1097
1098 static void followpath_new_data (void *cdata)
1099 {
1100         bFollowPathConstraint *data= (bFollowPathConstraint *)cdata;
1101         
1102         data->trackflag = TRACK_Y;
1103         data->upflag = UP_Z;
1104         data->offset = 0;
1105         data->followflag = 0;
1106 }
1107
1108 static int followpath_get_tars (bConstraint *con, ListBase *list)
1109 {
1110         if (con && list) {
1111                 bFollowPathConstraint *data= con->data;
1112                 bConstraintTarget *ct;
1113                 
1114                 /* standard target-getting macro for single-target constraints without subtargets */
1115                 SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
1116                 
1117                 return 1;
1118         }
1119         
1120         return 0;
1121 }
1122
1123 static void followpath_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1124 {
1125         if (con && list) {
1126                 bFollowPathConstraint *data= con->data;
1127                 bConstraintTarget *ct= list->first;
1128                 
1129                 /* the following macro is used for all standard single-target constraints */
1130                 SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy)
1131         }
1132 }
1133
1134 static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
1135 {
1136         bFollowPathConstraint *data= con->data;
1137         
1138         if (VALID_CONS_TARGET(ct)) {
1139                 Curve *cu= ct->tar->data;
1140                 float q[4], vec[4], dir[3], quat[4], x1;
1141                 float totmat[4][4];
1142                 float curvetime;
1143                 
1144                 Mat4One(totmat);
1145                 Mat4One(ct->matrix);
1146                 
1147                 /* note: when creating constraints that follow path, the curve gets the CU_PATH set now,
1148                  *              currently for paths to work it needs to go through the bevlist/displist system (ton) 
1149                  */
1150                 
1151                 /* only happens on reload file, but violates depsgraph still... fix! */
1152                 if (cu->path==NULL || cu->path->data==NULL) 
1153                         makeDispListCurveTypes(cob->scene, ct->tar, 0);
1154                 
1155                 if (cu->path && cu->path->data) {
1156                         curvetime= bsystem_time(cob->scene, ct->tar, (float)ctime, 0.0) - data->offset;
1157                         
1158 #if 0 // XXX old animation system
1159                         if (calc_ipo_spec(cu->ipo, CU_SPEED, &curvetime)==0) {
1160                                 curvetime /= cu->pathlen;
1161                                 CLAMP(curvetime, 0.0, 1.0);
1162                         }
1163 #endif // XXX old animation system
1164                         
1165                         if ( where_on_path(ct->tar, curvetime, vec, dir) ) {
1166                                 if (data->followflag) {
1167                                         vectoquat(dir, (short) data->trackflag, (short) data->upflag, quat);
1168                                         
1169                                         Normalize(dir);
1170                                         q[0]= (float)cos(0.5*vec[3]);
1171                                         x1= (float)sin(0.5*vec[3]);
1172                                         q[1]= -x1*dir[0];
1173                                         q[2]= -x1*dir[1];
1174                                         q[3]= -x1*dir[2];
1175                                         QuatMul(quat, q, quat);
1176                                         
1177                                         QuatToMat4(quat, totmat);
1178                                 }
1179                                 VECCOPY(totmat[3], vec);
1180                                 
1181                                 Mat4MulSerie(ct->matrix, ct->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL);
1182                         }
1183                 }
1184         }
1185         else if (ct)
1186                 Mat4One(ct->matrix);
1187 }
1188
1189 static void followpath_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1190 {
1191         bConstraintTarget *ct= targets->first;
1192         
1193         /* only evaluate if there is a target */
1194         if (VALID_CONS_TARGET(ct)) {
1195                 float obmat[4][4];
1196                 float size[3], obsize[3];
1197                 
1198                 /* get Object local transform (loc/rot/size) to determine transformation from path */
1199                 //object_to_mat4(ob, obmat);
1200                 Mat4CpyMat4(obmat, cob->matrix); // FIXME!!!
1201                 
1202                 /* get scaling of object before applying constraint */
1203                 Mat4ToSize(cob->matrix, size);
1204                 
1205                 /* apply targetmat - containing location on path, and rotation */
1206                 Mat4MulSerie(cob->matrix, ct->matrix, obmat, NULL, NULL, NULL, NULL, NULL, NULL);
1207                 
1208                 /* un-apply scaling caused by path */
1209                 Mat4ToSize(cob->matrix, obsize);
1210                 if (obsize[0])
1211                         VecMulf(cob->matrix[0], size[0] / obsize[0]);
1212                 if (obsize[1])
1213                         VecMulf(cob->matrix[1], size[1] / obsize[1]);
1214                 if (obsize[2])
1215                         VecMulf(cob->matrix[2], size[2] / obsize[2]);
1216         }
1217 }
1218
1219 static bConstraintTypeInfo CTI_FOLLOWPATH = {
1220         CONSTRAINT_TYPE_FOLLOWPATH, /* type */
1221         sizeof(bFollowPathConstraint), /* size */
1222         "Follow Path", /* name */
1223         "bFollowPathConstraint", /* struct name */
1224         NULL, /* free data */
1225         NULL, /* relink data */
1226         NULL, /* copy data */
1227         followpath_new_data, /* new data */
1228         followpath_get_tars, /* get constraint targets */
1229         followpath_flush_tars, /* flush constraint targets */
1230         followpath_get_tarmat, /* get target matrix */
1231         followpath_evaluate /* evaluate */
1232 };
1233
1234 /* --------- Limit Location --------- */
1235
1236
1237 static void loclimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1238 {
1239         bLocLimitConstraint *data = con->data;
1240         
1241         if (data->flag & LIMIT_XMIN) {
1242                 if (cob->matrix[3][0] < data->xmin)
1243                         cob->matrix[3][0] = data->xmin;
1244         }
1245         if (data->flag & LIMIT_XMAX) {
1246                 if (cob->matrix[3][0] > data->xmax)
1247                         cob->matrix[3][0] = data->xmax;
1248         }
1249         if (data->flag & LIMIT_YMIN) {
1250                 if (cob->matrix[3][1] < data->ymin)
1251                         cob->matrix[3][1] = data->ymin;
1252         }
1253         if (data->flag & LIMIT_YMAX) {
1254                 if (cob->matrix[3][1] > data->ymax)
1255                         cob->matrix[3][1] = data->ymax;
1256         }
1257         if (data->flag & LIMIT_ZMIN) {
1258                 if (cob->matrix[3][2] < data->zmin) 
1259                         cob->matrix[3][2] = data->zmin;
1260         }
1261         if (data->flag & LIMIT_ZMAX) {
1262                 if (cob->matrix[3][2] > data->zmax)
1263                         cob->matrix[3][2] = data->zmax;
1264         }
1265 }
1266
1267 static bConstraintTypeInfo CTI_LOCLIMIT = {
1268         CONSTRAINT_TYPE_LOCLIMIT, /* type */
1269         sizeof(bLocLimitConstraint), /* size */
1270         "Limit Location", /* name */
1271         "bLocLimitConstraint", /* struct name */
1272         NULL, /* free data */
1273         NULL, /* relink data */
1274         NULL, /* copy data */
1275         NULL, /* new data */
1276         NULL, /* get constraint targets */
1277         NULL, /* flush constraint targets */
1278         NULL, /* get target matrix */
1279         loclimit_evaluate /* evaluate */
1280 };
1281
1282 /* -------- Limit Rotation --------- */
1283
1284 static void rotlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1285 {
1286         bRotLimitConstraint *data = con->data;
1287         float loc[3];
1288         float eul[3];
1289         float size[3];
1290         
1291         VECCOPY(loc, cob->matrix[3]);
1292         Mat4ToSize(cob->matrix, size);
1293         
1294         Mat4ToEul(cob->matrix, eul);
1295         
1296         /* eulers: radians to degrees! */
1297         eul[0] = (float)(eul[0] / M_PI * 180);
1298         eul[1] = (float)(eul[1] / M_PI * 180);
1299         eul[2] = (float)(eul[2] / M_PI * 180);
1300         
1301         /* limiting of euler values... */
1302         if (data->flag & LIMIT_XROT) {
1303                 if (eul[0] < data->xmin) 
1304                         eul[0] = data->xmin;
1305                         
1306                 if (eul[0] > data->xmax)
1307                         eul[0] = data->xmax;
1308         }
1309         if (data->flag & LIMIT_YROT) {
1310                 if (eul[1] < data->ymin)
1311                         eul[1] = data->ymin;
1312                         
1313                 if (eul[1] > data->ymax)
1314                         eul[1] = data->ymax;
1315         }
1316         if (data->flag & LIMIT_ZROT) {
1317                 if (eul[2] < data->zmin)
1318                         eul[2] = data->zmin;
1319                         
1320                 if (eul[2] > data->zmax)
1321                         eul[2] = data->zmax;
1322         }
1323                 
1324         /* eulers: degrees to radians ! */
1325         eul[0] = (float)(eul[0] / 180 * M_PI); 
1326         eul[1] = (float)(eul[1] / 180 * M_PI);
1327         eul[2] = (float)(eul[2] / 180 * M_PI);
1328         
1329         LocEulSizeToMat4(cob->matrix, loc, eul, size);
1330 }
1331
1332 static bConstraintTypeInfo CTI_ROTLIMIT = {
1333         CONSTRAINT_TYPE_ROTLIMIT, /* type */
1334         sizeof(bRotLimitConstraint), /* size */
1335         "Limit Rotation", /* name */
1336         "bRotLimitConstraint", /* struct name */
1337         NULL, /* free data */
1338         NULL, /* relink data */
1339         NULL, /* copy data */
1340         NULL, /* new data */
1341         NULL, /* get constraint targets */
1342         NULL, /* flush constraint targets */
1343         NULL, /* get target matrix */
1344         rotlimit_evaluate /* evaluate */
1345 };
1346
1347 /* --------- Limit Scaling --------- */
1348
1349
1350 static void sizelimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1351 {
1352         bSizeLimitConstraint *data = con->data;
1353         float obsize[3], size[3];
1354         
1355         Mat4ToSize(cob->matrix, size);
1356         Mat4ToSize(cob->matrix, obsize);
1357         
1358         if (data->flag & LIMIT_XMIN) {
1359                 if (size[0] < data->xmin) 
1360                         size[0] = data->xmin;   
1361         }
1362         if (data->flag & LIMIT_XMAX) {
1363                 if (size[0] > data->xmax) 
1364                         size[0] = data->xmax;
1365         }
1366         if (data->flag & LIMIT_YMIN) {
1367                 if (size[1] < data->ymin) 
1368                         size[1] = data->ymin;   
1369         }
1370         if (data->flag & LIMIT_YMAX) {
1371                 if (size[1] > data->ymax) 
1372                         size[1] = data->ymax;
1373         }
1374         if (data->flag & LIMIT_ZMIN) {
1375                 if (size[2] < data->zmin) 
1376                         size[2] = data->zmin;   
1377         }
1378         if (data->flag & LIMIT_ZMAX) {
1379                 if (size[2] > data->zmax) 
1380                         size[2] = data->zmax;
1381         }
1382         
1383         if (obsize[0]) 
1384                 VecMulf(cob->matrix[0], size[0]/obsize[0]);
1385         if (obsize[1]) 
1386                 VecMulf(cob->matrix[1], size[1]/obsize[1]);
1387         if (obsize[2]) 
1388                 VecMulf(cob->matrix[2], size[2]/obsize[2]);
1389 }
1390
1391 static bConstraintTypeInfo CTI_SIZELIMIT = {
1392         CONSTRAINT_TYPE_SIZELIMIT, /* type */
1393         sizeof(bSizeLimitConstraint), /* size */
1394         "Limit Scaling", /* name */
1395         "bSizeLimitConstraint", /* struct name */
1396         NULL, /* free data */
1397         NULL, /* relink data */
1398         NULL, /* copy data */
1399         NULL, /* new data */
1400         NULL, /* get constraint targets */
1401         NULL, /* flush constraint targets */
1402         NULL, /* get target matrix */
1403         sizelimit_evaluate /* evaluate */
1404 };
1405
1406 /* ----------- Copy Location ------------- */
1407
1408 static void loclike_new_data (void *cdata)
1409 {
1410         bLocateLikeConstraint *data= (bLocateLikeConstraint *)cdata;
1411         
1412         data->flag = LOCLIKE_X|LOCLIKE_Y|LOCLIKE_Z;
1413 }
1414
1415 static int loclike_get_tars (bConstraint *con, ListBase *list)
1416 {
1417         if (con && list) {
1418                 bLocateLikeConstraint *data= con->data;
1419                 bConstraintTarget *ct;
1420                 
1421                 /* standard target-getting macro for single-target constraints */
1422                 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
1423                 
1424                 return 1;
1425         }
1426         
1427         return 0;
1428 }
1429
1430 static void loclike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1431 {
1432         if (con && list) {
1433                 bLocateLikeConstraint *data= con->data;
1434                 bConstraintTarget *ct= list->first;
1435                 
1436                 /* the following macro is used for all standard single-target constraints */
1437                 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
1438         }
1439 }
1440
1441 static void loclike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1442 {
1443         bLocateLikeConstraint *data= con->data;
1444         bConstraintTarget *ct= targets->first;
1445         
1446         if (VALID_CONS_TARGET(ct)) {
1447                 float offset[3] = {0.0f, 0.0f, 0.0f};
1448                 
1449                 if (data->flag & LOCLIKE_OFFSET)
1450                         VECCOPY(offset, cob->matrix[3]);
1451                         
1452                 if (data->flag & LOCLIKE_X) {
1453                         cob->matrix[3][0] = ct->matrix[3][0];
1454                         
1455                         if (data->flag & LOCLIKE_X_INVERT) cob->matrix[3][0] *= -1;
1456                         cob->matrix[3][0] += offset[0];
1457                 }
1458                 if (data->flag & LOCLIKE_Y) {
1459                         cob->matrix[3][1] = ct->matrix[3][1];
1460                         
1461                         if (data->flag & LOCLIKE_Y_INVERT) cob->matrix[3][1] *= -1;
1462                         cob->matrix[3][1] += offset[1];
1463                 }
1464                 if (data->flag & LOCLIKE_Z) {
1465                         cob->matrix[3][2] = ct->matrix[3][2];
1466                         
1467                         if (data->flag & LOCLIKE_Z_INVERT) cob->matrix[3][2] *= -1;
1468                         cob->matrix[3][2] += offset[2];
1469                 }
1470         }
1471 }
1472
1473 static bConstraintTypeInfo CTI_LOCLIKE = {
1474         CONSTRAINT_TYPE_LOCLIKE, /* type */
1475         sizeof(bLocateLikeConstraint), /* size */
1476         "Copy Location", /* name */
1477         "bLocateLikeConstraint", /* struct name */
1478         NULL, /* free data */
1479         NULL, /* relink data */
1480         NULL, /* copy data */
1481         loclike_new_data, /* new data */
1482         loclike_get_tars, /* get constraint targets */
1483         loclike_flush_tars, /* flush constraint targets */
1484         default_get_tarmat, /* get target matrix */
1485         loclike_evaluate /* evaluate */
1486 };
1487
1488 /* ----------- Copy Rotation ------------- */
1489
1490 static void rotlike_new_data (void *cdata)
1491 {
1492         bRotateLikeConstraint *data= (bRotateLikeConstraint *)cdata;
1493         
1494         data->flag = ROTLIKE_X|ROTLIKE_Y|ROTLIKE_Z;
1495 }
1496
1497 static int rotlike_get_tars (bConstraint *con, ListBase *list)
1498 {
1499         if (con && list) {
1500                 bRotateLikeConstraint *data= con->data;
1501                 bConstraintTarget *ct;
1502                 
1503                 /* standard target-getting macro for single-target constraints */
1504                 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
1505                 
1506                 return 1;
1507         }
1508         
1509         return 0;
1510 }
1511
1512 static void rotlike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1513 {
1514         if (con && list) {
1515                 bRotateLikeConstraint *data= con->data;
1516                 bConstraintTarget *ct= list->first;
1517                 
1518                 /* the following macro is used for all standard single-target constraints */
1519                 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
1520         }
1521 }
1522
1523 static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1524 {
1525         bRotateLikeConstraint *data= con->data;
1526         bConstraintTarget *ct= targets->first;
1527         
1528         if (VALID_CONS_TARGET(ct)) {
1529                 float   loc[3];
1530                 float   eul[3], obeul[3];
1531                 float   size[3];
1532                 
1533                 VECCOPY(loc, cob->matrix[3]);
1534                 Mat4ToSize(cob->matrix, size);
1535                 
1536                 Mat4ToEul(ct->matrix, eul);
1537                 Mat4ToEul(cob->matrix, obeul);
1538                 
1539                 if ((data->flag & ROTLIKE_X)==0)
1540                         eul[0] = obeul[0];
1541                 else {
1542                         if (data->flag & ROTLIKE_OFFSET)
1543                                 euler_rot(eul, obeul[0], 'x');
1544                         
1545                         if (data->flag & ROTLIKE_X_INVERT)
1546                                 eul[0] *= -1;
1547                 }
1548                 
1549                 if ((data->flag & ROTLIKE_Y)==0)
1550                         eul[1] = obeul[1];
1551                 else {
1552                         if (data->flag & ROTLIKE_OFFSET)
1553                                 euler_rot(eul, obeul[1], 'y');
1554                         
1555                         if (data->flag & ROTLIKE_Y_INVERT)
1556                                 eul[1] *= -1;
1557                 }
1558                 
1559                 if ((data->flag & ROTLIKE_Z)==0)
1560                         eul[2] = obeul[2];
1561                 else {
1562                         if (data->flag & ROTLIKE_OFFSET)
1563                                 euler_rot(eul, obeul[2], 'z');
1564                         
1565                         if (data->flag & ROTLIKE_Z_INVERT)
1566                                 eul[2] *= -1;
1567                 }
1568                 
1569                 compatible_eul(eul, obeul);
1570                 LocEulSizeToMat4(cob->matrix, loc, eul, size);
1571         }
1572 }
1573
1574 static bConstraintTypeInfo CTI_ROTLIKE = {
1575         CONSTRAINT_TYPE_ROTLIKE, /* type */
1576         sizeof(bRotateLikeConstraint), /* size */
1577         "Copy Rotation", /* name */
1578         "bRotateLikeConstraint", /* struct name */
1579         NULL, /* free data */
1580         NULL, /* relink data */
1581         NULL, /* copy data */
1582         rotlike_new_data, /* new data */
1583         rotlike_get_tars, /* get constraint targets */
1584         rotlike_flush_tars, /* flush constraint targets */
1585         default_get_tarmat, /* get target matrix */
1586         rotlike_evaluate /* evaluate */
1587 };
1588
1589 /* ---------- Copy Scaling ---------- */
1590
1591 static void sizelike_new_data (void *cdata)
1592 {
1593         bSizeLikeConstraint *data= (bSizeLikeConstraint *)cdata;
1594         
1595         data->flag = SIZELIKE_X|SIZELIKE_Y|SIZELIKE_Z;
1596 }
1597
1598 static int sizelike_get_tars (bConstraint *con, ListBase *list)
1599 {
1600         if (con && list) {
1601                 bSizeLikeConstraint *data= con->data;
1602                 bConstraintTarget *ct;
1603                 
1604                 /* standard target-getting macro for single-target constraints */
1605                 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
1606                 
1607                 return 1;
1608         }
1609         
1610         return 0;
1611 }
1612
1613 static void sizelike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1614 {
1615         if (con && list) {
1616                 bSizeLikeConstraint *data= con->data;
1617                 bConstraintTarget *ct= list->first;
1618                 
1619                 /* the following macro is used for all standard single-target constraints */
1620                 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
1621         }
1622 }
1623
1624 static void sizelike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1625 {
1626         bSizeLikeConstraint *data= con->data;
1627         bConstraintTarget *ct= targets->first;
1628         
1629         if (VALID_CONS_TARGET(ct)) {
1630                 float obsize[3], size[3];
1631                 
1632                 Mat4ToSize(ct->matrix, size);
1633                 Mat4ToSize(cob->matrix, obsize);
1634                 
1635                 if ((data->flag & SIZELIKE_X) && (obsize[0] != 0)) {
1636                         if (data->flag & SIZELIKE_OFFSET) {
1637                                 size[0] += (obsize[0] - 1.0f);
1638                                 VecMulf(cob->matrix[0], size[0] / obsize[0]);
1639                         }
1640                         else
1641                                 VecMulf(cob->matrix[0], size[0] / obsize[0]);
1642                 }
1643                 if ((data->flag & SIZELIKE_Y) && (obsize[1] != 0)) {
1644                         if (data->flag & SIZELIKE_OFFSET) {
1645                                 size[1] += (obsize[1] - 1.0f);
1646                                 VecMulf(cob->matrix[1], size[1] / obsize[1]);
1647                         }
1648                         else
1649                                 VecMulf(cob->matrix[1], size[1] / obsize[1]);
1650                 }
1651                 if ((data->flag & SIZELIKE_Z) && (obsize[2] != 0)) {
1652                         if (data->flag & SIZELIKE_OFFSET) {
1653                                 size[2] += (obsize[2] - 1.0f);
1654                                 VecMulf(cob->matrix[2], size[2] / obsize[2]);
1655                         }
1656                         else
1657                                 VecMulf(cob->matrix[2], size[2] / obsize[2]);
1658                 }
1659         }
1660 }
1661
1662 static bConstraintTypeInfo CTI_SIZELIKE = {
1663         CONSTRAINT_TYPE_SIZELIKE, /* type */
1664         sizeof(bSizeLikeConstraint), /* size */
1665         "Copy Scale", /* name */
1666         "bSizeLikeConstraint", /* struct name */
1667         NULL, /* free data */
1668         NULL, /* relink data */
1669         NULL, /* copy data */
1670         sizelike_new_data, /* new data */
1671         sizelike_get_tars, /* get constraint targets */
1672         sizelike_flush_tars, /* flush constraint targets */
1673         default_get_tarmat, /* get target matrix */
1674         sizelike_evaluate /* evaluate */
1675 };
1676
1677
1678 /* ----------- Python Constraint -------------- */
1679
1680 static void pycon_free (bConstraint *con)
1681 {
1682         bPythonConstraint *data= con->data;
1683         
1684         /* id-properties */
1685         IDP_FreeProperty(data->prop);
1686         MEM_freeN(data->prop);
1687         
1688         /* multiple targets */
1689         BLI_freelistN(&data->targets);
1690 }       
1691
1692 static void pycon_relink (bConstraint *con)
1693 {
1694         bPythonConstraint *data= con->data;
1695         
1696         ID_NEW(data->text);
1697 }
1698
1699 static void pycon_copy (bConstraint *con, bConstraint *srccon)
1700 {
1701         bPythonConstraint *pycon = (bPythonConstraint *)con->data;
1702         bPythonConstraint *opycon = (bPythonConstraint *)srccon->data;
1703         
1704         pycon->prop = IDP_CopyProperty(opycon->prop);
1705         BLI_duplicatelist(&pycon->targets, &opycon->targets);
1706 }
1707
1708 static void pycon_new_data (void *cdata)
1709 {
1710         bPythonConstraint *data= (bPythonConstraint *)cdata;
1711         
1712         /* everything should be set correctly by calloc, except for the prop->type constant.*/
1713         data->prop = MEM_callocN(sizeof(IDProperty), "PyConstraintProps");
1714         data->prop->type = IDP_GROUP;
1715 }
1716
1717 static int pycon_get_tars (bConstraint *con, ListBase *list)
1718 {
1719         if (con && list) {
1720                 bPythonConstraint *data= con->data;
1721                 
1722                 list->first = data->targets.first;
1723                 list->last = data->targets.last;
1724                 
1725                 return data->tarnum;
1726         }
1727         
1728         return 0;
1729 }
1730
1731 /* Whether this approach is maintained remains to be seen (aligorith) */
1732 static void pycon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
1733 {
1734         bPythonConstraint *data= con->data;
1735         
1736         if (VALID_CONS_TARGET(ct)) {
1737                 /* special exception for curves - depsgraph issues */
1738                 if (ct->tar->type == OB_CURVE) {
1739                         Curve *cu= ct->tar->data;
1740                         
1741                         /* this check is to make sure curve objects get updated on file load correctly.*/
1742                         if (cu->path==NULL || cu->path->data==NULL) /* only happens on reload file, but violates depsgraph still... fix! */
1743                                 makeDispListCurveTypes(cob->scene, ct->tar, 0);                         
1744                 }
1745                 
1746                 /* firstly calculate the matrix the normal way, then let the py-function override
1747                  * this matrix if it needs to do so
1748                  */
1749                 constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
1750                 
1751                 /* only execute target calculation if allowed */
1752 #ifndef DISABLE_PYTHON
1753                 if (G.f & G_DOSCRIPTLINKS)
1754                         BPY_pyconstraint_target(data, ct);
1755 #endif
1756         }
1757         else if (ct)
1758                 Mat4One(ct->matrix);
1759 }
1760
1761 static void pycon_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1762 {
1763 #ifdef DISABLE_PYTHON
1764         return;
1765 #else
1766         bPythonConstraint *data= con->data;
1767         
1768         /* only evaluate in python if we're allowed to do so */
1769         if ((G.f & G_DOSCRIPTLINKS)==0)  return;
1770         
1771 /* currently removed, until I this can be re-implemented for multiple targets */
1772 #if 0
1773         /* Firstly, run the 'driver' function which has direct access to the objects involved 
1774          * Technically, this is potentially dangerous as users may abuse this and cause dependency-problems,
1775          * but it also allows certain 'clever' rigging hacks to work.
1776          */
1777         BPY_pyconstraint_driver(data, cob, targets);
1778 #endif
1779         
1780         /* Now, run the actual 'constraint' function, which should only access the matrices */
1781         BPY_pyconstraint_eval(data, cob, targets);
1782 #endif /* DISABLE_PYTHON */
1783 }
1784
1785 static bConstraintTypeInfo CTI_PYTHON = {
1786         CONSTRAINT_TYPE_PYTHON, /* type */
1787         sizeof(bPythonConstraint), /* size */
1788         "Script", /* name */
1789         "bPythonConstraint", /* struct name */
1790         pycon_free, /* free data */
1791         pycon_relink, /* relink data */
1792         pycon_copy, /* copy data */
1793         pycon_new_data, /* new data */
1794         pycon_get_tars, /* get constraint targets */
1795         NULL, /* flush constraint targets */
1796         pycon_get_tarmat, /* get target matrix */
1797         pycon_evaluate /* evaluate */
1798 };
1799
1800 /* -------- Action Constraint ----------- */
1801
1802 static void actcon_relink (bConstraint *con)
1803 {
1804         bActionConstraint *data= con->data;
1805         ID_NEW(data->act);
1806 }
1807
1808 static void actcon_new_data (void *cdata)
1809 {
1810         bActionConstraint *data= (bActionConstraint *)cdata;
1811         
1812         /* set type to 20 (Loc X), as 0 is Rot X for backwards compatability */
1813         data->type = 20;
1814 }
1815
1816 static int actcon_get_tars (bConstraint *con, ListBase *list)
1817 {
1818         if (con && list) {
1819                 bActionConstraint *data= con->data;
1820                 bConstraintTarget *ct;
1821                 
1822                 /* standard target-getting macro for single-target constraints */
1823                 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
1824                 
1825                 return 1;
1826         }
1827         
1828         return 0;
1829 }
1830
1831 static void actcon_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1832 {
1833         if (con && list) {
1834                 bActionConstraint *data= con->data;
1835                 bConstraintTarget *ct= list->first;
1836                 
1837                 /* the following macro is used for all standard single-target constraints */
1838                 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
1839         }
1840 }
1841
1842 static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
1843 {
1844         extern void chan_calc_mat(bPoseChannel *chan);
1845         bActionConstraint *data = con->data;
1846         
1847         if (VALID_CONS_TARGET(ct)) {
1848                 float tempmat[4][4], vec[3];
1849                 float s, t;
1850                 short axis;
1851                 
1852                 /* initialise return matrix */
1853                 Mat4One(ct->matrix);
1854                 
1855                 /* get the transform matrix of the target */
1856                 constraint_target_to_mat4(ct->tar, ct->subtarget, tempmat, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
1857                 
1858                 /* determine where in transform range target is */
1859                 /* data->type is mapped as follows for backwards compatability:
1860                  *      00,01,02        - rotation (it used to be like this)
1861                  *      10,11,12        - scaling
1862                  *      20,21,22        - location
1863                  */
1864                 if (data->type < 10) {
1865                         /* extract rotation (is in whatever space target should be in) */
1866                         Mat4ToEul(tempmat, vec);
1867                         vec[0] *= (float)(180.0/M_PI);
1868                         vec[1] *= (float)(180.0/M_PI);
1869                         vec[2] *= (float)(180.0/M_PI);
1870                         axis= data->type;
1871                 }
1872                 else if (data->type < 20) {
1873                         /* extract scaling (is in whatever space target should be in) */
1874                         Mat4ToSize(tempmat, vec);
1875                         axis= data->type - 10;
1876                 }
1877                 else {
1878                         /* extract location */
1879                         VECCOPY(vec, tempmat[3]);
1880                         axis= data->type - 20;
1881                 }
1882                 
1883                 /* Target defines the animation */
1884                 s = (vec[axis]-data->min) / (data->max-data->min);
1885                 CLAMP(s, 0, 1);
1886                 t = ( s * (data->end-data->start)) + data->start;
1887                 
1888                 if (G.f & G_DEBUG)
1889                         printf("do Action Constraint %s - Ob %s Pchan %s \n", con->name, cob->ob->id.name+2, (cob->pchan)?cob->pchan->name:NULL);
1890                 
1891                 /* Get the appropriate information from the action */
1892                 if (cob->type == CONSTRAINT_OBTYPE_BONE) {
1893                         Object workob;
1894                         bPose *pose;
1895                         bPoseChannel *pchan, *tchan;
1896                         
1897                         /* make a temporary pose and evaluate using that */
1898                         pose = MEM_callocN(sizeof(bPose), "pose");
1899                         
1900                         /* make a copy of the bone of interest in the temp pose before evaluating action, so that it can get set */
1901                         pchan = cob->pchan;
1902                         tchan= verify_pose_channel(pose, pchan->name);
1903                         
1904                         /* evaluate action using workob (it will only set the PoseChannel in question) */
1905                         what_does_obaction(cob->scene, cob->ob, &workob, pose, data->act, pchan->name, t);
1906                         
1907                         /* convert animation to matrices for use here */
1908                         chan_calc_mat(tchan);
1909                         Mat4CpyMat4(ct->matrix, tchan->chan_mat);
1910                         
1911                         /* Clean up */
1912                         free_pose(pose);
1913                 }
1914                 else if (cob->type == CONSTRAINT_OBTYPE_OBJECT) {
1915                         Object workob;
1916                         
1917                         /* evaluate using workob */
1918                         // FIXME: we don't have any consistent standards on limiting effects on object...
1919                         what_does_obaction(cob->scene, cob->ob, &workob, NULL, data->act, NULL, t);
1920                         object_to_mat4(&workob, ct->matrix);
1921                 }
1922                 else {
1923                         /* behaviour undefined... */
1924                         puts("Error: unknown owner type for Action Constraint");
1925                 }
1926         }
1927 }
1928
1929 static void actcon_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1930 {
1931         bConstraintTarget *ct= targets->first;
1932         
1933         if (VALID_CONS_TARGET(ct)) {
1934                 float temp[4][4];
1935                 
1936                 /* Nice and simple... we just need to multiply the matrices, as the get_target_matrix
1937                  * function has already taken care of everything else.
1938                  */
1939                 Mat4CpyMat4(temp, cob->matrix);
1940                 Mat4MulMat4(cob->matrix, ct->matrix, temp);
1941         }
1942 }
1943
1944 static bConstraintTypeInfo CTI_ACTION = {
1945         CONSTRAINT_TYPE_ACTION, /* type */
1946         sizeof(bActionConstraint), /* size */
1947         "Action", /* name */
1948         "bActionConstraint", /* struct name */
1949         NULL, /* free data */
1950         actcon_relink, /* relink data */
1951         NULL, /* copy data */
1952         actcon_new_data, /* new data */
1953         actcon_get_tars, /* get constraint targets */
1954         actcon_flush_tars, /* flush constraint targets */
1955         actcon_get_tarmat, /* get target matrix */
1956         actcon_evaluate /* evaluate */
1957 };
1958
1959 /* --------- Locked Track ---------- */
1960
1961 static void locktrack_new_data (void *cdata)
1962 {
1963         bLockTrackConstraint *data= (bLockTrackConstraint *)cdata;
1964         
1965         data->trackflag = TRACK_Y;
1966         data->lockflag = LOCK_Z;
1967 }       
1968
1969 static int locktrack_get_tars (bConstraint *con, ListBase *list)
1970 {
1971         if (con && list) {
1972                 bLockTrackConstraint *data= con->data;
1973                 bConstraintTarget *ct;
1974                 
1975                 /* the following macro is used for all standard single-target constraints */
1976                 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
1977                 
1978                 return 1;
1979         }
1980         
1981         return 0;
1982 }
1983
1984 static void locktrack_flush_tars (bConstraint *con, ListBase *list, short nocopy)
1985 {
1986         if (con && list) {
1987                 bLockTrackConstraint *data= con->data;
1988                 bConstraintTarget *ct= list->first;
1989                 
1990                 /* the following macro is used for all standard single-target constraints */
1991                 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
1992         }
1993 }
1994
1995 static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1996 {
1997         bLockTrackConstraint *data= con->data;
1998         bConstraintTarget *ct= targets->first;
1999         
2000         if (VALID_CONS_TARGET(ct)) {
2001                 float vec[3],vec2[3];
2002                 float totmat[3][3];
2003                 float tmpmat[3][3];
2004                 float invmat[3][3];
2005                 float tmat[4][4];
2006                 float mdet;
2007                 
2008                 /* Vector object -> target */
2009                 VecSubf(vec, ct->matrix[3], cob->matrix[3]);
2010                 switch (data->lockflag){
2011                 case LOCK_X: /* LOCK X */
2012                 {
2013                         switch (data->trackflag) {
2014                                 case TRACK_Y: /* LOCK X TRACK Y */
2015                                 {
2016                                         /* Projection of Vector on the plane */
2017                                         Projf(vec2, vec, cob->matrix[0]);
2018                                         VecSubf(totmat[1], vec, vec2);
2019                                         Normalize(totmat[1]);
2020                                         
2021                                         /* the x axis is fixed */
2022                                         totmat[0][0] = cob->matrix[0][0];
2023                                         totmat[0][1] = cob->matrix[0][1];
2024                                         totmat[0][2] = cob->matrix[0][2];
2025                                         Normalize(totmat[0]);
2026                                         
2027                                         /* the z axis gets mapped onto a third orthogonal vector */
2028                                         Crossf(totmat[2], totmat[0], totmat[1]);
2029                                 }
2030                                         break;
2031                                 case TRACK_Z: /* LOCK X TRACK Z */
2032                                 {
2033                                         /* Projection of Vector on the plane */
2034                                         Projf(vec2, vec, cob->matrix[0]);
2035                                         VecSubf(totmat[2], vec, vec2);
2036                                         Normalize(totmat[2]);
2037                                         
2038                                         /* the x axis is fixed */
2039                                         totmat[0][0] = cob->matrix[0][0];
2040                                         totmat[0][1] = cob->matrix[0][1];
2041                                         totmat[0][2] = cob->matrix[0][2];
2042                                         Normalize(totmat[0]);
2043                                         
2044                                         /* the z axis gets mapped onto a third orthogonal vector */
2045                                         Crossf(totmat[1], totmat[2], totmat[0]);
2046                                 }
2047                                         break;
2048                                 case TRACK_nY: /* LOCK X TRACK -Y */
2049                                 {
2050                                         /* Projection of Vector on the plane */
2051                                         Projf(vec2, vec, cob->matrix[0]);
2052                                         VecSubf(totmat[1], vec, vec2);
2053                                         Normalize(totmat[1]);
2054                                         VecNegf(totmat[1]);
2055                                         
2056                                         /* the x axis is fixed */
2057                                         totmat[0][0] = cob->matrix[0][0];
2058                                         totmat[0][1] = cob->matrix[0][1];
2059                                         totmat[0][2] = cob->matrix[0][2];
2060                                         Normalize(totmat[0]);
2061                                         
2062                                         /* the z axis gets mapped onto a third orthogonal vector */
2063                                         Crossf(totmat[2], totmat[0], totmat[1]);
2064                                 }
2065                                         break;
2066                                 case TRACK_nZ: /* LOCK X TRACK -Z */
2067                                 {
2068                                         /* Projection of Vector on the plane */
2069                                         Projf(vec2, vec, cob->matrix[0]);
2070                                         VecSubf(totmat[2], vec, vec2);
2071                                         Normalize(totmat[2]);
2072                                         VecNegf(totmat[2]);
2073                                                 
2074                                         /* the x axis is fixed */
2075                                         totmat[0][0] = cob->matrix[0][0];
2076                                         totmat[0][1] = cob->matrix[0][1];
2077                                         totmat[0][2] = cob->matrix[0][2];
2078                                         Normalize(totmat[0]);
2079                                                 
2080                                         /* the z axis gets mapped onto a third orthogonal vector */
2081                                         Crossf(totmat[1], totmat[2], totmat[0]);
2082                                 }
2083                                         break;
2084                                 default:
2085                                 {
2086                                         totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
2087                                         totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
2088                                         totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
2089                                 }
2090                                         break;
2091                         }
2092                 }
2093                         break;
2094                 case LOCK_Y: /* LOCK Y */
2095                 {
2096                         switch (data->trackflag) {
2097                                 case TRACK_X: /* LOCK Y TRACK X */
2098                                 {
2099                                         /* Projection of Vector on the plane */
2100                                         Projf(vec2, vec, cob->matrix[1]);
2101                                         VecSubf(totmat[0], vec, vec2);
2102                                         Normalize(totmat[0]);
2103                                         
2104                                         /* the y axis is fixed */
2105                                         totmat[1][0] = cob->matrix[1][0];
2106                                         totmat[1][1] = cob->matrix[1][1];
2107                                         totmat[1][2] = cob->matrix[1][2];
2108                                         Normalize(totmat[1]);
2109                                         
2110                                         /* the z axis gets mapped onto a third orthogonal vector */
2111                                         Crossf(totmat[2], totmat[0], totmat[1]);
2112                                 }
2113                                         break;
2114                                 case TRACK_Z: /* LOCK Y TRACK Z */
2115                                 {
2116                                         /* Projection of Vector on the plane */
2117                                         Projf(vec2, vec, cob->matrix[1]);
2118                                         VecSubf(totmat[2], vec, vec2);
2119                                         Normalize(totmat[2]);
2120
2121                                         /* the y axis is fixed */
2122                                         totmat[1][0] = cob->matrix[1][0];
2123                                         totmat[1][1] = cob->matrix[1][1];
2124                                         totmat[1][2] = cob->matrix[1][2];
2125                                         Normalize(totmat[1]);
2126                                         
2127                                         /* the z axis gets mapped onto a third orthogonal vector */
2128                                         Crossf(totmat[0], totmat[1], totmat[2]);
2129                                 }
2130                                         break;
2131                                 case TRACK_nX: /* LOCK Y TRACK -X */
2132                                 {
2133                                         /* Projection of Vector on the plane */
2134                                         Projf(vec2, vec, cob->matrix[1]);
2135                                         VecSubf(totmat[0], vec, vec2);
2136                                         Normalize(totmat[0]);
2137                                         VecNegf(totmat[0]);
2138                                         
2139                                         /* the y axis is fixed */
2140                                         totmat[1][0] = cob->matrix[1][0];
2141                                         totmat[1][1] = cob->matrix[1][1];
2142                                         totmat[1][2] = cob->matrix[1][2];
2143                                         Normalize(totmat[1]);
2144                                         
2145                                         /* the z axis gets mapped onto a third orthogonal vector */
2146                                         Crossf(totmat[2], totmat[0], totmat[1]);
2147                                 }
2148                                         break;
2149                                 case TRACK_nZ: /* LOCK Y TRACK -Z */
2150                                 {
2151                                         /* Projection of Vector on the plane */
2152                                         Projf(vec2, vec, cob->matrix[1]);
2153                                         VecSubf(totmat[2], vec, vec2);
2154                                         Normalize(totmat[2]);
2155                                         VecNegf(totmat[2]);
2156                                         
2157                                         /* the y axis is fixed */
2158                                         totmat[1][0] = cob->matrix[1][0];
2159                                         totmat[1][1] = cob->matrix[1][1];
2160                                         totmat[1][2] = cob->matrix[1][2];
2161                                         Normalize(totmat[1]);
2162                                         
2163                                         /* the z axis gets mapped onto a third orthogonal vector */
2164                                         Crossf(totmat[0], totmat[1], totmat[2]);
2165                                 }
2166                                         break;
2167                                 default:
2168                                 {
2169                                         totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
2170                                         totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
2171                                         totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
2172                                 }
2173                                         break;
2174                         }
2175                 }
2176                         break;
2177                 case LOCK_Z: /* LOCK Z */
2178                 {
2179                         switch (data->trackflag) {
2180                                 case TRACK_X: /* LOCK Z TRACK X */
2181                                 {
2182                                         /* Projection of Vector on the plane */
2183                                         Projf(vec2, vec, cob->matrix[2]);
2184                                         VecSubf(totmat[0], vec, vec2);
2185                                         Normalize(totmat[0]);
2186                                         
2187                                         /* the z axis is fixed */
2188                                         totmat[2][0] = cob->matrix[2][0];
2189                                         totmat[2][1] = cob->matrix[2][1];
2190                                         totmat[2][2] = cob->matrix[2][2];
2191                                         Normalize(totmat[2]);
2192                                         
2193                                         /* the x axis gets mapped onto a third orthogonal vector */
2194                                         Crossf(totmat[1], totmat[2], totmat[0]);
2195                                 }
2196                                         break;
2197                                 case TRACK_Y: /* LOCK Z TRACK Y */
2198                                 {
2199                                         /* Projection of Vector on the plane */
2200                                         Projf(vec2, vec, cob->matrix[2]);
2201                                         VecSubf(totmat[1], vec, vec2);
2202                                         Normalize(totmat[1]);
2203                                         
2204                                         /* the z axis is fixed */
2205                                         totmat[2][0] = cob->matrix[2][0];
2206                                         totmat[2][1] = cob->matrix[2][1];
2207                                         totmat[2][2] = cob->matrix[2][2];
2208                                         Normalize(totmat[2]);
2209                                                 
2210                                         /* the x axis gets mapped onto a third orthogonal vector */
2211                                         Crossf(totmat[0], totmat[1], totmat[2]);
2212                                 }
2213                                         break;
2214                                 case TRACK_nX: /* LOCK Z TRACK -X */
2215                                 {
2216                                         /* Projection of Vector on the plane */
2217                                         Projf(vec2, vec, cob->matrix[2]);
2218                                         VecSubf(totmat[0], vec, vec2);
2219                                         Normalize(totmat[0]);
2220                                         VecNegf(totmat[0]);
2221                                         
2222                                         /* the z axis is fixed */
2223                                         totmat[2][0] = cob->matrix[2][0];
2224                                         totmat[2][1] = cob->matrix[2][1];
2225                                         totmat[2][2] = cob->matrix[2][2];
2226                                         Normalize(totmat[2]);
2227                                         
2228                                         /* the x axis gets mapped onto a third orthogonal vector */
2229                                         Crossf(totmat[1], totmat[2], totmat[0]);
2230                                 }
2231                                         break;
2232                                 case TRACK_nY: /* LOCK Z TRACK -Y */
2233                                 {
2234                                         /* Projection of Vector on the plane */
2235                                         Projf(vec2, vec, cob->matrix[2]);
2236                                         VecSubf(totmat[1], vec, vec2);
2237                                         Normalize(totmat[1]);
2238                                         VecNegf(totmat[1]);
2239                                         
2240                                         /* the z axis is fixed */
2241                                         totmat[2][0] = cob->matrix[2][0];
2242                                         totmat[2][1] = cob->matrix[2][1];
2243                                         totmat[2][2] = cob->matrix[2][2];
2244                                         Normalize(totmat[2]);
2245                                                 
2246                                         /* the x axis gets mapped onto a third orthogonal vector */
2247                                         Crossf(totmat[0], totmat[1], totmat[2]);
2248                                 }
2249                                         break;
2250                                 default:
2251                                 {
2252                                                 totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
2253                                                 totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
2254                                                 totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
2255                                 }
2256                                         break;
2257                         }
2258                 }
2259                         break;
2260                 default:
2261                         {
2262                                 totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
2263                                 totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
2264                                 totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
2265                         }
2266                         break;
2267                 }
2268                 /* Block to keep matrix heading */
2269                 tmpmat[0][0] = cob->matrix[0][0];tmpmat[0][1] = cob->matrix[0][1];tmpmat[0][2] = cob->matrix[0][2];
2270                 tmpmat[1][0] = cob->matrix[1][0];tmpmat[1][1] = cob->matrix[1][1];tmpmat[1][2] = cob->matrix[1][2];
2271                 tmpmat[2][0] = cob->matrix[2][0];tmpmat[2][1] = cob->matrix[2][1];tmpmat[2][2] = cob->matrix[2][2];
2272                 Normalize(tmpmat[0]);
2273                 Normalize(tmpmat[1]);
2274                 Normalize(tmpmat[2]);
2275                 Mat3Inv(invmat, tmpmat);
2276                 Mat3MulMat3(tmpmat, totmat, invmat);
2277                 totmat[0][0] = tmpmat[0][0];totmat[0][1] = tmpmat[0][1];totmat[0][2] = tmpmat[0][2];
2278                 totmat[1][0] = tmpmat[1][0];totmat[1][1] = tmpmat[1][1];totmat[1][2] = tmpmat[1][2];
2279                 totmat[2][0] = tmpmat[2][0];totmat[2][1] = tmpmat[2][1];totmat[2][2] = tmpmat[2][2];
2280                 
2281                 Mat4CpyMat4(tmat, cob->matrix);
2282                 
2283                 mdet = Det3x3(  totmat[0][0],totmat[0][1],totmat[0][2],
2284                                                 totmat[1][0],totmat[1][1],totmat[1][2],
2285                                                 totmat[2][0],totmat[2][1],totmat[2][2]);
2286                 if (mdet==0) {
2287                         totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
2288                         totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
2289                         totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
2290                 }
2291                 
2292                 /* apply out transformaton to the object */
2293                 Mat4MulMat34(cob->matrix, totmat, tmat);
2294         }
2295 }
2296
2297 static bConstraintTypeInfo CTI_LOCKTRACK = {
2298         CONSTRAINT_TYPE_LOCKTRACK, /* type */
2299         sizeof(bLockTrackConstraint), /* size */
2300         "Locked Track", /* name */
2301         "bLockTrackConstraint", /* struct name */
2302         NULL, /* free data */
2303         NULL, /* relink data */
2304         NULL, /* copy data */
2305         locktrack_new_data, /* new data */
2306         locktrack_get_tars, /* get constraint targets */
2307         locktrack_flush_tars, /* flush constraint targets */
2308         default_get_tarmat, /* get target matrix */
2309         locktrack_evaluate /* evaluate */
2310 };
2311
2312 /* ---------- Limit Distance Constraint ----------- */
2313
2314 static void distlimit_new_data (void *cdata)
2315 {
2316         bDistLimitConstraint *data= (bDistLimitConstraint *)cdata;
2317         
2318         data->dist= 0.0;
2319 }
2320
2321 static int distlimit_get_tars (bConstraint *con, ListBase *list)
2322 {
2323         if (con && list) {
2324                 bDistLimitConstraint *data= con->data;
2325                 bConstraintTarget *ct;
2326                 
2327                 /* standard target-getting macro for single-target constraints */
2328                 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
2329                 
2330                 return 1;
2331         }
2332         
2333         return 0;
2334 }
2335
2336 static void distlimit_flush_tars (bConstraint *con, ListBase *list, short nocopy)
2337 {
2338         if (con && list) {
2339                 bDistLimitConstraint *data= con->data;
2340                 bConstraintTarget *ct= list->first;
2341                 
2342                 /* the following macro is used for all standard single-target constraints */
2343                 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
2344         }
2345 }
2346
2347 static void distlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
2348 {
2349         bDistLimitConstraint *data= con->data;
2350         bConstraintTarget *ct= targets->first;
2351         
2352         /* only evaluate if there is a target */
2353         if (VALID_CONS_TARGET(ct)) {
2354                 float dvec[3], dist=0.0f, sfac=1.0f;
2355                 short clamp_surf= 0;
2356                 
2357                 /* calculate our current distance from the target */
2358                 dist= VecLenf(cob->matrix[3], ct->matrix[3]);
2359                 
2360                 /* set distance (flag is only set when user demands it) */
2361                 if (data->dist == 0)
2362                         data->dist= dist;
2363                 
2364                 /* check if we're which way to clamp from, and calculate interpolation factor (if needed) */
2365                 if (data->mode == LIMITDIST_OUTSIDE) {
2366                         /* if inside, then move to surface */
2367                         if (dist <= data->dist) {
2368                                 clamp_surf= 1;
2369                                 sfac= data->dist / dist;
2370                         }
2371                         /* if soft-distance is enabled, start fading once owner is dist+softdist from the target */
2372                         else if (data->flag & LIMITDIST_USESOFT) {
2373                                 if (dist <= (data->dist + data->soft)) {
2374                                         
2375                                 }
2376                         }
2377                 }
2378                 else if (data->mode == LIMITDIST_INSIDE) {
2379                         /* if outside, then move to surface */
2380                         if (dist >= data->dist) {
2381                                 clamp_surf= 1;
2382                                 sfac= data->dist / dist;
2383                         }
2384                         /* if soft-distance is enabled, start fading once owner is dist-soft from the target */
2385                         else if (data->flag & LIMITDIST_USESOFT) {
2386                                 // FIXME: there's a problem with "jumping" when this kicks in
2387                                 if (dist >= (data->dist - data->soft)) {
2388                                         sfac = (float)( data->soft*(1.0 - exp(-(dist - data->dist)/data->soft)) + data->dist );
2389                                         sfac /= dist;
2390                                         
2391                                         clamp_surf= 1;
2392                                 }
2393                         }
2394                 }
2395                 else {
2396                         if (IS_EQ(dist, data->dist)==0) {
2397                                 clamp_surf= 1;
2398                                 sfac= data->dist / dist;
2399                         }
2400                 }
2401                 
2402                 /* clamp to 'surface' (i.e. move owner so that dist == data->dist) */
2403                 if (clamp_surf) {
2404                         /* simply interpolate along line formed by target -> owner */
2405                         VecLerpf(dvec, ct->matrix[3], cob->matrix[3], sfac);
2406                         
2407                         /* copy new vector onto owner */
2408                         VECCOPY(cob->matrix[3], dvec);
2409                 }
2410         }
2411 }
2412
2413 static bConstraintTypeInfo CTI_DISTLIMIT = {
2414         CONSTRAINT_TYPE_DISTLIMIT, /* type */
2415         sizeof(bDistLimitConstraint), /* size */
2416         "Limit Distance", /* name */
2417         "bDistLimitConstraint", /* struct name */
2418         NULL, /* free data */
2419         NULL, /* relink data */
2420         NULL, /* copy data */
2421         distlimit_new_data, /* new data */
2422         distlimit_get_tars, /* get constraint targets */
2423         distlimit_flush_tars, /* flush constraint targets */
2424         default_get_tarmat, /* get a target matrix */
2425         distlimit_evaluate /* evaluate */
2426 };
2427
2428 /* ---------- Stretch To ------------ */
2429
2430 static void stretchto_new_data (void *cdata)
2431 {
2432         bStretchToConstraint *data= (bStretchToConstraint *)cdata;
2433         
2434         data->volmode = 0;
2435         data->plane = 0;
2436         data->orglength = 0.0; 
2437         data->bulge = 1.0;
2438 }
2439
2440 static int stretchto_get_tars (bConstraint *con, ListBase *list)
2441 {
2442         if (con && list) {
2443                 bStretchToConstraint *data= con->data;
2444                 bConstraintTarget *ct;
2445                 
2446                 /* standard target-getting macro for single-target constraints */
2447                 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
2448                 
2449                 return 1;
2450         }
2451         
2452         return 0;
2453 }
2454
2455 static void stretchto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
2456 {
2457         if (con && list) {
2458                 bStretchToConstraint *data= con->data;
2459                 bConstraintTarget *ct= list->first;
2460                 
2461                 /* the following macro is used for all standard single-target constraints */
2462                 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
2463         }
2464 }
2465
2466 static void stretchto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
2467 {
2468         bStretchToConstraint *data= con->data;
2469         bConstraintTarget *ct= targets->first;
2470         
2471         /* only evaluate if there is a target */
2472         if (VALID_CONS_TARGET(ct)) {
2473                 float size[3], scale[3], vec[3], xx[3], zz[3], orth[3];
2474                 float totmat[3][3];
2475                 float tmat[4][4];
2476                 float dist;
2477                 
2478                 /* store scaling before destroying obmat */
2479                 Mat4ToSize(cob->matrix, size);
2480                 
2481                 /* store X orientation before destroying obmat */
2482                 xx[0] = cob->matrix[0][0];
2483                 xx[1] = cob->matrix[0][1];
2484                 xx[2] = cob->matrix[0][2];
2485                 Normalize(xx);
2486                 
2487                 /* store Z orientation before destroying obmat */
2488                 zz[0] = cob->matrix[2][0];
2489                 zz[1] = cob->matrix[2][1];
2490                 zz[2] = cob->matrix[2][2];
2491                 Normalize(zz);
2492                 
2493                 VecSubf(vec, cob->matrix[3], ct->matrix[3]);
2494                 vec[0] /= size[0];
2495                 vec[1] /= size[1];
2496                 vec[2] /= size[2];
2497                 
2498                 dist = Normalize(vec);
2499                 //dist = VecLenf( ob->obmat[3], targetmat[3]);
2500                 
2501                 /* data->orglength==0 occurs on first run, and after 'R' button is clicked */
2502                 if (data->orglength == 0)  
2503                         data->orglength = dist;
2504                 if (data->bulge == 0) 
2505                         data->bulge = 1.0;
2506                 
2507                 scale[1] = dist/data->orglength;
2508                 switch (data->volmode) {
2509                 /* volume preserving scaling */
2510                 case VOLUME_XZ :
2511                         scale[0] = 1.0f - (float)sqrt(data->bulge) + (float)sqrt(data->bulge*(data->orglength/dist));
2512                         scale[2] = scale[0];
2513                         break;
2514                 case VOLUME_X:
2515                         scale[0] = 1.0f + data->bulge * (data->orglength /dist - 1);
2516                         scale[2] = 1.0;
2517                         break;
2518                 case VOLUME_Z:
2519                         scale[0] = 1.0;
2520                         scale[2] = 1.0f + data->bulge * (data->orglength /dist - 1);
2521                         break;
2522                         /* don't care for volume */
2523                 case NO_VOLUME:
2524                         scale[0] = 1.0;
2525                         scale[2] = 1.0;
2526                         break;
2527                 default: /* should not happen, but in case*/
2528                         return;    
2529                 } /* switch (data->volmode) */
2530
2531                 /* Clear the object's rotation and scale */
2532                 cob->matrix[0][0]=size[0]*scale[0];
2533                 cob->matrix[0][1]=0;
2534                 cob->matrix[0][2]=0;
2535                 cob->matrix[1][0]=0;
2536                 cob->matrix[1][1]=size[1]*scale[1];
2537                 cob->matrix[1][2]=0;
2538                 cob->matrix[2][0]=0;
2539                 cob->matrix[2][1]=0;
2540                 cob->matrix[2][2]=size[2]*scale[2];
2541                 
2542                 VecSubf(vec, cob->matrix[3], ct->matrix[3]);
2543                 Normalize(vec);
2544                 
2545                 /* new Y aligns  object target connection*/
2546                 totmat[1][0] = -vec[0];
2547                 totmat[1][1] = -vec[1];
2548                 totmat[1][2] = -vec[2];
2549                 switch (data->plane) {
2550                 case PLANE_X:
2551                         /* build new Z vector */
2552                         /* othogonal to "new Y" "old X! plane */
2553                         Crossf(orth, vec, xx);
2554                         Normalize(orth);
2555                         
2556                         /* new Z*/
2557                         totmat[2][0] = orth[0];
2558                         totmat[2][1] = orth[1];
2559                         totmat[2][2] = orth[2];
2560                         
2561                         /* we decided to keep X plane*/
2562                         Crossf(xx, orth, vec);
2563                         Normalize(xx);
2564                         totmat[0][0] = xx[0];
2565                         totmat[0][1] = xx[1];
2566                         totmat[0][2] = xx[2];
2567                         break;
2568                 case PLANE_Z:
2569                         /* build new X vector */
2570                         /* othogonal to "new Y" "old Z! plane */
2571                         Crossf(orth, vec, zz);
2572                         Normalize(orth);
2573                         
2574                         /* new X */
2575                         totmat[0][0] = -orth[0];
2576                         totmat[0][1] = -orth[1];
2577                         totmat[0][2] = -orth[2];
2578                         
2579                         /* we decided to keep Z */
2580                         Crossf(zz, orth, vec);
2581                         Normalize(zz);
2582                         totmat[2][0] = zz[0];
2583                         totmat[2][1] = zz[1];
2584                         totmat[2][2] = zz[2];
2585                         break;
2586                 } /* switch (data->plane) */
2587                 
2588                 Mat4CpyMat4(tmat, cob->matrix);
2589                 Mat4MulMat34(cob->matrix, totmat, tmat);
2590         }
2591 }
2592
2593 static bConstraintTypeInfo CTI_STRETCHTO = {
2594         CONSTRAINT_TYPE_STRETCHTO, /* type */
2595         sizeof(bStretchToConstraint), /* size */
2596         "Stretch To", /* name */
2597         "bStretchToConstraint", /* struct name */
2598         NULL, /* free data */
2599         NULL, /* relink data */
2600         NULL, /* copy data */
2601         stretchto_new_data, /* new data */
2602         stretchto_get_tars, /* get constraint targets */
2603         stretchto_flush_tars, /* flush constraint targets */
2604         default_get_tarmat, /* get target matrix */
2605         stretchto_evaluate /* evaluate */
2606 };
2607
2608 /* ---------- Floor ------------ */
2609
2610 static void minmax_new_data (void *cdata)
2611 {
2612         bMinMaxConstraint *data= (bMinMaxConstraint *)cdata;
2613         
2614         data->minmaxflag = TRACK_Z;
2615         data->offset = 0.0f;
2616         data->cache[0] = data->cache[1] = data->cache[2] = 0.0f;
2617         data->flag = 0;
2618 }
2619
2620 static int minmax_get_tars (bConstraint *con, ListBase *list)
2621 {
2622         if (con && list) {
2623                 bMinMaxConstraint *data= con->data;
2624                 bConstraintTarget *ct;
2625                 
2626                 /* standard target-getting macro for single-target constraints */
2627                 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
2628                 
2629                 return 1;
2630         }
2631         
2632         return 0;
2633 }
2634
2635 static void minmax_flush_tars (bConstraint *con, ListBase *list, short nocopy)
2636 {
2637         if (con && list) {
2638                 bMinMaxConstraint *data= con->data;
2639                 bConstraintTarget *ct= list->first;
2640                 
2641                 /* the following macro is used for all standard single-target constraints */
2642                 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
2643         }
2644 }
2645
2646 static void minmax_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
2647 {
2648         bMinMaxConstraint *data= con->data;
2649         bConstraintTarget *ct= targets->first;
2650         
2651         /* only evaluate if there is a target */
2652         if (VALID_CONS_TARGET(ct)) {
2653                 float obmat[4][4], imat[4][4], tarmat[4][4], tmat[4][4];
2654                 float val1, val2;
2655                 int index;
2656                 
2657                 Mat4CpyMat4(obmat, cob->matrix);
2658                 Mat4CpyMat4(tarmat, ct->matrix);
2659                 
2660                 if (data->flag & MINMAX_USEROT) {
2661                         /* take rotation of target into account by doing the transaction in target's localspace */
2662                         Mat4Invert(imat, tarmat);
2663                         Mat4MulMat4(tmat, obmat, imat);
2664                         Mat4CpyMat4(obmat, tmat);
2665                         Mat4One(tarmat);
2666                 }
2667                 
2668                 switch (data->minmaxflag) {
2669                 case TRACK_Z:
2670                         val1 = tarmat[3][2];
2671                         val2 = obmat[3][2]-data->offset;
2672                         index = 2;
2673                         break;
2674                 case TRACK_Y:
2675                         val1 = tarmat[3][1];
2676                         val2 = obmat[3][1]-data->offset;
2677                         index = 1;
2678                         break;
2679                 case TRACK_X:
2680                         val1 = tarmat[3][0];
2681                         val2 = obmat[3][0]-data->offset;
2682                         index = 0;
2683                         break;
2684                 case TRACK_nZ:
2685                         val2 = tarmat[3][2];
2686                         val1 = obmat[3][2]-data->offset;
2687                         index = 2;
2688                         break;
2689                 case TRACK_nY:
2690                         val2 = tarmat[3][1];
2691                         val1 = obmat[3][1]-data->offset;
2692                         index = 1;
2693                         break;
2694                 case TRACK_nX:
2695                         val2 = tarmat[3][0];
2696                         val1 = obmat[3][0]-data->offset;
2697                         index = 0;
2698                         break;
2699                 default:
2700                         return;
2701                 }
2702                 
2703                 if (val1 > val2) {
2704                         obmat[3][index] = tarmat[3][index] + data->offset;
2705                         if (data->flag & MINMAX_STICKY) {
2706                                 if (data->flag & MINMAX_STUCK) {
2707                                         VECCOPY(obmat[3], data->cache);
2708                                 } 
2709                                 else {
2710                                         VECCOPY(data->cache, obmat[3]);
2711                                         data->flag |= MINMAX_STUCK;
2712                                 }
2713                         }
2714                         if (data->flag & MINMAX_USEROT) {
2715                                 /* get out of localspace */
2716                                 Mat4MulMat4(tmat, obmat, ct->matrix);
2717                                 Mat4CpyMat4(cob->matrix, tmat);
2718                         } 
2719                         else {                  
2720                                 VECCOPY(cob->matrix[3], obmat[3]);
2721                         }
2722                 } 
2723                 else {
2724                         data->flag &= ~MINMAX_STUCK;
2725                 }
2726         }
2727 }
2728
2729 static bConstraintTypeInfo CTI_MINMAX = {
2730         CONSTRAINT_TYPE_MINMAX, /* type */
2731         sizeof(bMinMaxConstraint), /* size */
2732         "Floor", /* name */
2733         "bMinMaxConstraint", /* struct name */
2734         NULL, /* free data */
2735         NULL, /* relink data */
2736         NULL, /* copy data */
2737         minmax_new_data, /* new data */
2738         minmax_get_tars, /* get constraint targets */
2739         minmax_flush_tars, /* flush constraint targets */
2740         default_get_tarmat, /* get target matrix */
2741         minmax_evaluate /* evaluate */
2742 };
2743
2744 /* ------- RigidBody Joint ---------- */
2745
2746 static void rbj_new_data (void *cdata)
2747 {
2748         bRigidBodyJointConstraint *data= (bRigidBodyJointConstraint *)cdata;
2749         
2750         // removed code which set target of this constraint  
2751     data->type=1;
2752 }
2753
2754 static int rbj_get_tars (bConstraint *con, ListBase *list)
2755 {
2756         if (con && list) {
2757                 bRigidBodyJointConstraint *data= con->data;
2758                 bConstraintTarget *ct;
2759                 
2760                 /* standard target-getting macro for single-target constraints without subtargets */
2761                 SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
2762                 
2763                 return 1;
2764         }
2765         
2766         return 0;
2767 }
2768
2769 static void rbj_flush_tars (bConstraint *con, ListBase *list, short nocopy)
2770 {
2771         if (con && list) {
2772                 bRigidBodyJointConstraint *data= con->data;
2773                 bConstraintTarget *ct= list->first;
2774                 
2775                 /* the following macro is used for all standard single-target constraints */
2776                 SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy)
2777         }
2778 }
2779
2780 static bConstraintTypeInfo CTI_RIGIDBODYJOINT = {
2781         CONSTRAINT_TYPE_RIGIDBODYJOINT, /* type */
2782         sizeof(bRigidBodyJointConstraint), /* size */
2783         "RigidBody Joint", /* name */
2784         "bRigidBodyJointConstraint", /* struct name */
2785         NULL, /* free data */
2786         NULL, /* relink data */
2787         NULL, /* copy data */
2788         rbj_new_data, /* new data */
2789         rbj_get_tars, /* get constraint targets */
2790         rbj_flush_tars, /* flush constraint targets */
2791         default_get_tarmat, /* get target matrix */
2792         NULL /* evaluate - this is not solved here... is just an interface for game-engine */
2793 };
2794
2795 /* -------- Clamp To ---------- */
2796
2797 static int clampto_get_tars (bConstraint *con, ListBase *list)
2798 {
2799         if (con && list) {
2800                 bClampToConstraint *data= con->data;
2801                 bConstraintTarget *ct;
2802                 
2803                 /* standard target-getting macro for single-target constraints without subtargets */
2804                 SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
2805                 
2806                 return 1;
2807         }
2808         
2809         return 0;
2810 }
2811
2812 static void clampto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
2813 {
2814         if (con && list) {
2815                 bClampToConstraint *data= con->data;
2816                 bConstraintTarget *ct= list->first;
2817                 
2818                 /* the following macro is used for all standard single-target constraints */
2819                 SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy)
2820         }
2821 }
2822
2823 static void clampto_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
2824 {
2825         if (VALID_CONS_TARGET(ct)) {
2826                 Curve *cu= ct->tar->data;
2827                 
2828                 /* note: when creating constraints that follow path, the curve gets the CU_PATH set now,
2829                  *              currently for paths to work it needs to go through the bevlist/displist system (ton) 
2830                  */
2831                 
2832                 /* only happens on reload file, but violates depsgraph still... fix! */
2833                 if (cu->path==NULL || cu->path->data==NULL) 
2834                         makeDispListCurveTypes(cob->scene, ct->tar, 0);
2835         }
2836         
2837         /* technically, this isn't really needed for evaluation, but we don't know what else
2838          * might end up calling this...
2839          */
2840         if (ct)
2841                 Mat4One(ct->matrix);
2842 }
2843
2844 static void clampto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
2845 {
2846         bClampToConstraint *data= con->data;
2847         bConstraintTarget *ct= targets->first;
2848         
2849         /* only evaluate if there is a target and it is a curve */
2850         if (VALID_CONS_TARGET(ct) && (ct->tar->type == OB_CURVE)) {
2851                 Curve *cu= data->tar->data;
2852                 float obmat[4][4], targetMatrix[4][4], ownLoc[3];
2853                 float curveMin[3], curveMax[3];
2854                 
2855                 Mat4CpyMat4(obmat, cob->matrix);
2856                 Mat4One(targetMatrix);
2857                 VECCOPY(ownLoc, obmat[3]);
2858                 
2859                 INIT_MINMAX(curveMin, curveMax)
2860                 minmax_object(ct->tar, curveMin, curveMax);
2861                 
2862                 /* get targetmatrix */
2863                 if (cu->path && cu->path->data) {
2864                         float vec[4], dir[3], totmat[4][4];
2865                         float curvetime;
2866                         short clamp_axis;
2867                         
2868                         /* find best position on curve */
2869                         /* 1. determine which axis to sample on? */
2870                         if (data->flag == CLAMPTO_AUTO) {
2871                                 float size[3];
2872                                 VecSubf(size, curveMax, curveMin);
2873                                 
2874                                 /* find axis along which the bounding box has the greatest
2875                                  * extent. Otherwise, default to the x-axis, as that is quite
2876                                  * frequently used.
2877                                  */
2878                                 if ((size[2]>size[0]) && (size[2]>size[1]))
2879                                         clamp_axis= CLAMPTO_Z - 1;
2880                                 else if ((size[1]>size[0]) && (size[1]>size[2]))
2881                                         clamp_axis= CLAMPTO_Y - 1;
2882                                 else
2883                                         clamp_axis = CLAMPTO_X - 1;
2884                         }
2885                         else 
2886                                 clamp_axis= data->flag - 1;
2887                                 
2888                         /* 2. determine position relative to curve on a 0-1 scale based on bounding box */
2889                         if (data->flag2 & CLAMPTO_CYCLIC) {
2890                                 /* cyclic, so offset within relative bounding box is used */
2891                                 float len= (curveMax[clamp_axis] - curveMin[clamp_axis]);
2892                                 float offset;
2893                                 
2894                                 /* check to make sure len is not so close to zero that it'll cause errors */
2895                                 if (IS_EQ(len, 0) == 0) {
2896                                         /* find bounding-box range where target is located */
2897                                         if (ownLoc[clamp_axis] < curveMin[clamp_axis]) {
2898                                                 /* bounding-box range is before */
2899                                                 offset= curveMin[clamp_axis];
2900                                                 
2901                                                 while (ownLoc[clamp_axis] < offset)
2902                                                         offset -= len;
2903                                                 
2904                                                 /* now, we calculate as per normal, except using offset instead of curveMin[clamp_axis] */
2905                                                 curvetime = (ownLoc[clamp_axis] - offset) / (len);
2906                     &