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