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