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