Blender V2.61 - r43446

constraint.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): 2007, Joshua Leung, major recode
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include <stdio.h> 
00034 #include <stddef.h>
00035 #include <string.h>
00036 #include <math.h>
00037 #include <float.h>
00038 
00039 #include "MEM_guardedalloc.h"
00040 
00041 #include "BLI_blenlib.h"
00042 #include "BLI_math.h"
00043 #include "BLI_editVert.h"
00044 #include "BLI_kdopbvh.h"
00045 #include "BLI_utildefines.h"
00046 
00047 #include "DNA_armature_types.h"
00048 #include "DNA_camera_types.h"
00049 #include "DNA_constraint_types.h"
00050 #include "DNA_modifier_types.h"
00051 #include "DNA_object_types.h"
00052 #include "DNA_action_types.h"
00053 #include "DNA_curve_types.h"
00054 #include "DNA_mesh_types.h"
00055 #include "DNA_meshdata_types.h"
00056 
00057 #include "DNA_lattice_types.h"
00058 #include "DNA_scene_types.h"
00059 #include "DNA_text_types.h"
00060 #include "DNA_tracking_types.h"
00061 #include "DNA_movieclip_types.h"
00062 
00063 
00064 #include "BKE_action.h"
00065 #include "BKE_anim.h" /* for the curve calculation part */
00066 #include "BKE_armature.h"
00067 #include "BKE_blender.h"
00068 #include "BKE_bvhutils.h"
00069 #include "BKE_camera.h"
00070 #include "BKE_constraint.h"
00071 #include "BKE_displist.h"
00072 #include "BKE_deform.h"
00073 #include "BKE_DerivedMesh.h"    /* for geometry targets */
00074 #include "BKE_cdderivedmesh.h" /* for geometry targets */
00075 #include "BKE_object.h"
00076 #include "BKE_ipo.h"
00077 #include "BKE_global.h"
00078 #include "BKE_library.h"
00079 #include "BKE_idprop.h"
00080 #include "BKE_shrinkwrap.h"
00081 #include "BKE_mesh.h"
00082 #include "BKE_tracking.h"
00083 #include "BKE_movieclip.h"
00084 
00085 #ifdef WITH_PYTHON
00086 #include "BPY_extern.h"
00087 #endif
00088 
00089 #ifndef M_PI
00090 #define M_PI        3.14159265358979323846
00091 #endif
00092 
00093 
00094 
00095 /* ************************ Constraints - General Utilities *************************** */
00096 /* These functions here don't act on any specific constraints, and are therefore should/will
00097  * not require any of the special function-pointers afforded by the relevant constraint 
00098  * type-info structs.
00099  */
00100 
00101 /* -------------- Naming -------------- */
00102 
00103 /* Find the first available, non-duplicate name for a given constraint */
00104 void unique_constraint_name (bConstraint *con, ListBase *list)
00105 {
00106     BLI_uniquename(list, con, "Const", '.', offsetof(bConstraint, name), sizeof(con->name));
00107 }
00108 
00109 /* ----------------- Evaluation Loop Preparation --------------- */
00110 
00111 /* package an object/bone for use in constraint evaluation */
00112 /* This function MEM_calloc's a bConstraintOb struct, that will need to be freed after evaluation */
00113 bConstraintOb *constraints_make_evalob (Scene *scene, Object *ob, void *subdata, short datatype)
00114 {
00115     bConstraintOb *cob;
00116     
00117     /* create regardless of whether we have any data! */
00118     cob= MEM_callocN(sizeof(bConstraintOb), "bConstraintOb");
00119     
00120     /* for system time, part of deglobalization, code nicer later with local time (ton) */
00121     cob->scene= scene;
00122     
00123     /* based on type of available data */
00124     switch (datatype) {
00125         case CONSTRAINT_OBTYPE_OBJECT:
00126         {
00127             /* disregard subdata... calloc should set other values right */
00128             if (ob) {
00129                 cob->ob = ob;
00130                 cob->type = datatype;
00131                 cob->rotOrder = EULER_ORDER_DEFAULT; // TODO: when objects have rotation order too, use that
00132                 copy_m4_m4(cob->matrix, ob->obmat);
00133             }
00134             else
00135                 unit_m4(cob->matrix);
00136             
00137             copy_m4_m4(cob->startmat, cob->matrix);
00138         }
00139             break;
00140         case CONSTRAINT_OBTYPE_BONE:
00141         {
00142             /* only set if we have valid bone, otherwise default */
00143             if (ob && subdata) {
00144                 cob->ob = ob;
00145                 cob->pchan = (bPoseChannel *)subdata;
00146                 cob->type = datatype;
00147                 
00148                 if (cob->pchan->rotmode > 0) {
00149                     /* should be some type of Euler order */
00150                     cob->rotOrder= cob->pchan->rotmode; 
00151                 }
00152                 else {
00153                     /* Quats, so eulers should just use default order */
00154                     cob->rotOrder= EULER_ORDER_DEFAULT;
00155                 }
00156                 
00157                 /* matrix in world-space */
00158                 mult_m4_m4m4(cob->matrix, ob->obmat, cob->pchan->pose_mat);
00159             }
00160             else
00161                 unit_m4(cob->matrix);
00162                 
00163             copy_m4_m4(cob->startmat, cob->matrix);
00164         }
00165             break;
00166             
00167         default: /* other types not yet handled */
00168             unit_m4(cob->matrix);
00169             unit_m4(cob->startmat);
00170             break;
00171     }
00172     
00173     return cob;
00174 }
00175 
00176 /* cleanup after constraint evaluation */
00177 void constraints_clear_evalob (bConstraintOb *cob)
00178 {
00179     float delta[4][4], imat[4][4];
00180     
00181     /* prevent crashes */
00182     if (cob == NULL) 
00183         return;
00184     
00185     /* calculate delta of constraints evaluation */
00186     invert_m4_m4(imat, cob->startmat);
00187     mult_m4_m4m4(delta, cob->matrix, imat);
00188     
00189     /* copy matrices back to source */
00190     switch (cob->type) {
00191         case CONSTRAINT_OBTYPE_OBJECT:
00192         {
00193             /* cob->ob might not exist! */
00194             if (cob->ob) {
00195                 /* copy new ob-matrix back to owner */
00196                 copy_m4_m4(cob->ob->obmat, cob->matrix);
00197                 
00198                 /* copy inverse of delta back to owner */
00199                 invert_m4_m4(cob->ob->constinv, delta);
00200             }
00201         }
00202             break;
00203         case CONSTRAINT_OBTYPE_BONE:
00204         {
00205             /* cob->ob or cob->pchan might not exist */
00206             if (cob->ob && cob->pchan) {
00207                 /* copy new pose-matrix back to owner */
00208                 mult_m4_m4m4(cob->pchan->pose_mat, cob->ob->imat, cob->matrix);
00209                 
00210                 /* copy inverse of delta back to owner */
00211                 invert_m4_m4(cob->pchan->constinv, delta);
00212             }
00213         }
00214             break;
00215     }
00216     
00217     /* free tempolary struct */
00218     MEM_freeN(cob);
00219 }
00220 
00221 /* -------------- Space-Conversion API -------------- */
00222 
00223 /* This function is responsible for the correct transformations/conversions 
00224  * of a matrix from one space to another for constraint evaluation.
00225  * For now, this is only implemented for Objects and PoseChannels.
00226  */
00227 void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4], short from, short to)
00228 {
00229     float tempmat[4][4];
00230     float diff_mat[4][4];
00231     float imat[4][4];
00232     
00233     /* prevent crashes in these unlikely events  */
00234     if (ob==NULL || mat==NULL) return;
00235     /* optimise trick - check if need to do anything */
00236     if (from == to) return;
00237     
00238     /* are we dealing with pose-channels or objects */
00239     if (pchan) {
00240         /* pose channels */
00241         switch (from) {
00242             case CONSTRAINT_SPACE_WORLD: /* ---------- FROM WORLDSPACE ---------- */
00243             {
00244                 /* world to pose */
00245                 invert_m4_m4(imat, ob->obmat);
00246                 copy_m4_m4(tempmat, mat);
00247                 mult_m4_m4m4(mat, imat, tempmat);
00248                 
00249                 /* use pose-space as stepping stone for other spaces... */
00250                 if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) {
00251                     /* call self with slightly different values */
00252                     constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
00253                 }
00254             }
00255                 break;
00256             case CONSTRAINT_SPACE_POSE: /* ---------- FROM POSESPACE ---------- */
00257             {
00258                 /* pose to world */
00259                 if (to == CONSTRAINT_SPACE_WORLD) {
00260                     copy_m4_m4(tempmat, mat);
00261                     mult_m4_m4m4(mat, ob->obmat, tempmat);
00262                 }
00263                 /* pose to local */
00264                 else if (to == CONSTRAINT_SPACE_LOCAL) {
00265                     if (pchan->bone) {
00266                         if (pchan->parent) {
00267                             float offs_bone[4][4];
00268                                 
00269                             /* construct offs_bone the same way it is done in armature.c */
00270                             copy_m4_m3(offs_bone, pchan->bone->bone_mat);
00271                             copy_v3_v3(offs_bone[3], pchan->bone->head);
00272                             offs_bone[3][1]+= pchan->bone->parent->length;
00273                             
00274                             if (pchan->bone->flag & BONE_HINGE) {
00275                                 /* pose_mat = par_pose-space_location * chan_mat */
00276                                 float tmat[4][4];
00277                                 
00278                                 /* the rotation of the parent restposition */
00279                                 copy_m4_m4(tmat, pchan->bone->parent->arm_mat);
00280                                 
00281                                 /* the location of actual parent transform */
00282                                 copy_v3_v3(tmat[3], offs_bone[3]);
00283                                 offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f;
00284                                 mul_m4_v3(pchan->parent->pose_mat, tmat[3]);
00285                                 
00286                                 mult_m4_m4m4(diff_mat, tmat, offs_bone);
00287                                 invert_m4_m4(imat, diff_mat);
00288                             }
00289                             else {
00290                                 /* pose_mat = par_pose_mat * bone_mat * chan_mat */
00291                                 mult_m4_m4m4(diff_mat, pchan->parent->pose_mat, offs_bone);
00292                                 invert_m4_m4(imat, diff_mat);
00293                             }
00294                         }
00295                         else {
00296                             /* pose_mat = chan_mat * arm_mat */
00297                             invert_m4_m4(imat, pchan->bone->arm_mat);
00298                         }
00299                         
00300                         copy_m4_m4(tempmat, mat);
00301                         mult_m4_m4m4(mat, imat, tempmat);
00302                     }
00303                 }
00304                 /* pose to local with parent */
00305                 else if (to == CONSTRAINT_SPACE_PARLOCAL) {
00306                     if (pchan->bone) {
00307                         invert_m4_m4(imat, pchan->bone->arm_mat);
00308                         copy_m4_m4(tempmat, mat);
00309                         mult_m4_m4m4(mat, imat, tempmat);
00310                     }
00311                 }
00312             }
00313                 break;
00314             case CONSTRAINT_SPACE_LOCAL: /* ------------ FROM LOCALSPACE --------- */
00315             {
00316                 /* local to pose - do inverse procedure that was done for pose to local */
00317                 if (pchan->bone) {
00318                     /* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */                     
00319                     if (pchan->parent) {
00320                         float offs_bone[4][4];
00321                         
00322                         /* construct offs_bone the same way it is done in armature.c */
00323                         copy_m4_m3(offs_bone, pchan->bone->bone_mat);
00324                         copy_v3_v3(offs_bone[3], pchan->bone->head);
00325                         offs_bone[3][1]+= pchan->bone->parent->length;
00326                         
00327                         if (pchan->bone->flag & BONE_HINGE) {
00328                             /* pose_mat = par_pose-space_location * chan_mat */
00329                             float tmat[4][4];
00330                             
00331                             /* the rotation of the parent restposition */
00332                             copy_m4_m4(tmat, pchan->bone->parent->arm_mat);
00333                             
00334                             /* the location of actual parent transform */
00335                             copy_v3_v3(tmat[3], offs_bone[3]);
00336                             zero_v3(offs_bone[3]);
00337                             mul_m4_v3(pchan->parent->pose_mat, tmat[3]);
00338                             
00339                             mult_m4_m4m4(diff_mat, tmat, offs_bone);
00340                             copy_m4_m4(tempmat, mat);
00341                             mult_m4_m4m4(mat, diff_mat, tempmat);
00342                         }
00343                         else {
00344                             /* pose_mat = par_pose_mat * bone_mat * chan_mat */
00345                             mult_m4_m4m4(diff_mat, pchan->parent->pose_mat, offs_bone);
00346                             copy_m4_m4(tempmat, mat);
00347                             mult_m4_m4m4(mat, diff_mat, tempmat);
00348                         }
00349                     }
00350                     else {
00351                         copy_m4_m4(diff_mat, pchan->bone->arm_mat);
00352                         
00353                         copy_m4_m4(tempmat, mat);
00354                         mult_m4_m4m4(mat, diff_mat, tempmat);
00355                     }
00356                 }
00357                 
00358                 /* use pose-space as stepping stone for other spaces */
00359                 if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL)) {
00360                     /* call self with slightly different values */
00361                     constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
00362                 }               
00363             }
00364                 break;
00365             case CONSTRAINT_SPACE_PARLOCAL: /* -------------- FROM LOCAL WITH PARENT ---------- */
00366             {
00367                 /* local + parent to pose */
00368                 if (pchan->bone) {                  
00369                     copy_m4_m4(diff_mat, pchan->bone->arm_mat);
00370                     copy_m4_m4(tempmat, mat);
00371                     mult_m4_m4m4(mat, tempmat, diff_mat);
00372                 }
00373                 
00374                 /* use pose-space as stepping stone for other spaces */
00375                 if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL)) {
00376                     /* call self with slightly different values */
00377                     constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
00378                 }
00379             }
00380                 break;
00381         }
00382     }
00383     else {
00384         /* objects */
00385         if (from==CONSTRAINT_SPACE_WORLD && to==CONSTRAINT_SPACE_LOCAL) {
00386             /* check if object has a parent */
00387             if (ob->parent) {
00388                 /* 'subtract' parent's effects from owner */
00389                 mult_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv);
00390                 invert_m4_m4(imat, diff_mat);
00391                 copy_m4_m4(tempmat, mat);
00392                 mult_m4_m4m4(mat, imat, tempmat);
00393             }
00394             else {
00395                 /* Local space in this case will have to be defined as local to the owner's 
00396                  * transform-property-rotated axes. So subtract this rotation component.
00397                  */
00398                 object_to_mat4(ob, diff_mat);
00399                 normalize_m4(diff_mat);
00400                 zero_v3(diff_mat[3]);
00401                 
00402                 invert_m4_m4(imat, diff_mat);
00403                 copy_m4_m4(tempmat, mat);
00404                 mult_m4_m4m4(mat, imat, tempmat);
00405             }
00406         }
00407         else if (from==CONSTRAINT_SPACE_LOCAL && to==CONSTRAINT_SPACE_WORLD) {
00408             /* check that object has a parent - otherwise this won't work */
00409             if (ob->parent) {
00410                 /* 'add' parent's effect back to owner */
00411                 copy_m4_m4(tempmat, mat);
00412                 mult_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv);
00413                 mult_m4_m4m4(mat, diff_mat, tempmat);
00414             }
00415             else {
00416                 /* Local space in this case will have to be defined as local to the owner's 
00417                  * transform-property-rotated axes. So add back this rotation component.
00418                  */
00419                 object_to_mat4(ob, diff_mat);
00420                 normalize_m4(diff_mat);
00421                 zero_v3(diff_mat[3]);
00422                 
00423                 copy_m4_m4(tempmat, mat);
00424                 mult_m4_m4m4(mat, diff_mat, tempmat);
00425             }
00426         }
00427     }
00428 }
00429 
00430 /* ------------ General Target Matrix Tools ---------- */
00431 
00432 /* function that sets the given matrix based on given vertex group in mesh */
00433 static void contarget_get_mesh_mat (Object *ob, const char *substring, float mat[][4])
00434 {
00435     DerivedMesh *dm = NULL;
00436     Mesh *me= ob->data;
00437     EditMesh *em = BKE_mesh_get_editmesh(me);
00438     float vec[3] = {0.0f, 0.0f, 0.0f};
00439     float normal[3] = {0.0f, 0.0f, 0.0f}, plane[3];
00440     float imat[3][3], tmat[3][3];
00441     const int defgroup= defgroup_name_index(ob, substring);
00442     short freeDM = 0;
00443     
00444     /* initialize target matrix using target matrix */
00445     copy_m4_m4(mat, ob->obmat);
00446     
00447     /* get index of vertex group */
00448     if (defgroup == -1) return;
00449 
00450     /* get DerivedMesh */
00451     if (em) {
00452         /* target is in editmode, so get a special derived mesh */
00453         dm = CDDM_from_editmesh(em, ob->data);
00454         freeDM= 1;
00455     }
00456     else {
00457         /* when not in EditMode, use the 'final' derived mesh, depsgraph
00458          * ensures we build with CD_MDEFORMVERT layer 
00459          */
00460         dm = (DerivedMesh *)ob->derivedFinal;
00461     }
00462     
00463     /* only continue if there's a valid DerivedMesh */
00464     if (dm) {
00465         MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
00466         int numVerts = dm->getNumVerts(dm);
00467         int i, count = 0;
00468         float co[3], nor[3];
00469         
00470         /* check that dvert is a valid pointers (just in case) */
00471         if (dvert) {
00472             MDeformVert *dv= dvert;
00473             /* get the average of all verts with that are in the vertex-group */
00474             for (i = 0; i < numVerts; i++, dv++) {
00475                 MDeformWeight *dw= defvert_find_index(dv, defgroup);
00476                 if (dw && dw->weight != 0.0f) {
00477                     dm->getVertCo(dm, i, co);
00478                     dm->getVertNo(dm, i, nor);
00479                     add_v3_v3(vec, co);
00480                     add_v3_v3(normal, nor);
00481                     count++;
00482                     
00483                 }
00484             }
00485 
00486             /* calculate averages of normal and coordinates */
00487             if (count > 0) {
00488                 mul_v3_fl(vec, 1.0f / count);
00489                 mul_v3_fl(normal, 1.0f / count);
00490             }
00491             
00492             
00493             /* derive the rotation from the average normal: 
00494              *      - code taken from transform_manipulator.c, 
00495              *          calc_manipulator_stats, V3D_MANIP_NORMAL case
00496              */
00497             /*  we need the transpose of the inverse for a normal... */
00498             copy_m3_m4(imat, ob->obmat);
00499             
00500             invert_m3_m3(tmat, imat);
00501             transpose_m3(tmat);
00502             mul_m3_v3(tmat, normal);
00503             
00504             normalize_v3(normal);
00505             copy_v3_v3(plane, tmat[1]);
00506             
00507             copy_v3_v3(tmat[2], normal);
00508             cross_v3_v3v3(tmat[0], normal, plane);
00509             cross_v3_v3v3(tmat[1], tmat[2], tmat[0]);
00510             
00511             copy_m4_m3(mat, tmat);
00512             normalize_m4(mat);
00513             
00514             
00515             /* apply the average coordinate as the new location */
00516             mul_v3_m4v3(mat[3], ob->obmat, vec);
00517         }
00518     }
00519     
00520     /* free temporary DerivedMesh created (in EditMode case) */
00521     if (dm && freeDM)
00522         dm->release(dm);
00523     if (em)
00524         BKE_mesh_end_editmesh(me, em);
00525 }
00526 
00527 /* function that sets the given matrix based on given vertex group in lattice */
00528 static void contarget_get_lattice_mat (Object *ob, const char *substring, float mat[][4])
00529 {
00530     Lattice *lt= (Lattice *)ob->data;
00531     
00532     DispList *dl = find_displist(&ob->disp, DL_VERTS);
00533     float *co = dl?dl->verts:NULL;
00534     BPoint *bp = lt->def;
00535     
00536     MDeformVert *dv = lt->dvert;
00537     int tot_verts= lt->pntsu*lt->pntsv*lt->pntsw;
00538     float vec[3]= {0.0f, 0.0f, 0.0f}, tvec[3];
00539     int grouped=0;
00540     int i, n;
00541     const int defgroup= defgroup_name_index(ob, substring);
00542     
00543     /* initialize target matrix using target matrix */
00544     copy_m4_m4(mat, ob->obmat);
00545 
00546     /* get index of vertex group */
00547     if (defgroup == -1) return;
00548     if (dv == NULL) return;
00549     
00550     /* 1. Loop through control-points checking if in nominated vertex-group.
00551      * 2. If it is, add it to vec to find the average point.
00552      */
00553     for (i=0; i < tot_verts; i++, dv++) {
00554         for (n= 0; n < dv->totweight; n++) {
00555             MDeformWeight *dw= defvert_find_index(dv, defgroup);
00556             if (dw && dw->weight > 0.0f) {
00557                 /* copy coordinates of point to temporary vector, then add to find average */
00558                 memcpy(tvec, co ? co : bp->vec, 3 * sizeof(float));
00559 
00560                 add_v3_v3(vec, tvec);
00561                 grouped++;
00562             }
00563         }
00564         
00565         /* advance pointer to coordinate data */
00566         if (co) co += 3;
00567         else    bp++;
00568     }
00569     
00570     /* find average location, then multiply by ob->obmat to find world-space location */
00571     if (grouped)
00572         mul_v3_fl(vec, 1.0f / grouped);
00573     mul_v3_m4v3(tvec, ob->obmat, vec);
00574     
00575     /* copy new location to matrix */
00576     copy_v3_v3(mat[3], tvec);
00577 }
00578 
00579 /* generic function to get the appropriate matrix for most target cases */
00580 /* The cases where the target can be object data have not been implemented */
00581 static void constraint_target_to_mat4 (Object *ob, const char *substring, float mat[][4], short from, short to, float headtail)
00582 {
00583     /*  Case OBJECT */
00584     if (!strlen(substring)) {
00585         copy_m4_m4(mat, ob->obmat);
00586         constraint_mat_convertspace(ob, NULL, mat, from, to);
00587     }
00588     /*  Case VERTEXGROUP */
00589     /* Current method just takes the average location of all the points in the
00590      * VertexGroup, and uses that as the location value of the targets. Where 
00591      * possible, the orientation will also be calculated, by calculating an
00592      * 'average' vertex normal, and deriving the rotaation from that.
00593      *
00594      * NOTE: EditMode is not currently supported, and will most likely remain that
00595      *      way as constraints can only really affect things on object/bone level.
00596      */
00597     else if (ob->type == OB_MESH) {
00598         contarget_get_mesh_mat(ob, substring, mat);
00599         constraint_mat_convertspace(ob, NULL, mat, from, to);
00600     }
00601     else if (ob->type == OB_LATTICE) {
00602         contarget_get_lattice_mat(ob, substring, mat);
00603         constraint_mat_convertspace(ob, NULL, mat, from, to);
00604     }
00605     /*  Case BONE */
00606     else {
00607         bPoseChannel *pchan;
00608         
00609         pchan = get_pose_channel(ob->pose, substring);
00610         if (pchan) {
00611             /* Multiply the PoseSpace accumulation/final matrix for this
00612              * PoseChannel by the Armature Object's Matrix to get a worldspace
00613              * matrix.
00614              */
00615             if (headtail < 0.000001f) {
00616                 /* skip length interpolation if set to head */
00617                 mult_m4_m4m4(mat, ob->obmat, pchan->pose_mat);
00618             }
00619             else {
00620                 float tempmat[4][4], loc[3];
00621                 
00622                 /* interpolate along length of bone */
00623                 interp_v3_v3v3(loc, pchan->pose_head, pchan->pose_tail, headtail);  
00624                 
00625                 /* use interpolated distance for subtarget */
00626                 copy_m4_m4(tempmat, pchan->pose_mat);   
00627                 copy_v3_v3(tempmat[3], loc);
00628                 
00629                 mult_m4_m4m4(mat, ob->obmat, tempmat);
00630             }
00631         } 
00632         else
00633             copy_m4_m4(mat, ob->obmat);
00634             
00635         /* convert matrix space as required */
00636         constraint_mat_convertspace(ob, pchan, mat, from, to);
00637     }
00638 }
00639 
00640 /* ************************* Specific Constraints ***************************** */
00641 /* Each constraint defines a set of functions, which will be called at the appropriate
00642  * times. In addition to this, each constraint should have a type-info struct, where
00643  * its functions are attached for use. 
00644  */
00645  
00646 /* Template for type-info data:
00647  *  - make a copy of this when creating new constraints, and just change the functions
00648  *    pointed to as necessary
00649  *  - although the naming of functions doesn't matter, it would help for code
00650  *    readability, to follow the same naming convention as is presented here
00651  *  - any functions that a constraint doesn't need to define, don't define
00652  *    for such cases, just use NULL 
00653  *  - these should be defined after all the functions have been defined, so that
00654  *    forward-definitions/prototypes don't need to be used!
00655  *  - keep this copy #if-def'd so that future constraints can get based off this
00656  */
00657 #if 0
00658 static bConstraintTypeInfo CTI_CONSTRNAME = {
00659     CONSTRAINT_TYPE_CONSTRNAME, /* type */
00660     sizeof(bConstrNameConstraint), /* size */
00661     "ConstrName", /* name */
00662     "bConstrNameConstraint", /* struct name */
00663     constrname_free, /* free data */
00664     constrname_relink, /* relink data */
00665     constrname_id_looper, /* id looper */
00666     constrname_copy, /* copy data */
00667     constrname_new_data, /* new data */
00668     constrname_get_tars, /* get constraint targets */
00669     constrname_flush_tars, /* flush constraint targets */
00670     constrname_get_tarmat, /* get target matrix */
00671     constrname_evaluate /* evaluate */
00672 };
00673 #endif
00674 
00675 /* This function should be used for the get_target_matrix member of all 
00676  * constraints that are not picky about what happens to their target matrix.
00677  */
00678 static void default_get_tarmat (bConstraint *con, bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime))
00679 {
00680     if (VALID_CONS_TARGET(ct))
00681         constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
00682     else if (ct)
00683         unit_m4(ct->matrix);
00684 }
00685 
00686 /* This following macro should be used for all standard single-target *_get_tars functions 
00687  * to save typing and reduce maintainance woes.
00688  * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
00689  *  really just to help this code easier to read)
00690  */
00691 // TODO: cope with getting rotation order...
00692 #define SINGLETARGET_GET_TARS(con, datatar, datasubtarget, ct, list) \
00693     { \
00694         ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \
00695          \
00696         ct->tar= datatar; \
00697         BLI_strncpy(ct->subtarget, datasubtarget, sizeof(ct->subtarget)); \
00698         ct->space= con->tarspace; \
00699         ct->flag= CONSTRAINT_TAR_TEMP; \
00700          \
00701         if (ct->tar) { \
00702             if ((ct->tar->type==OB_ARMATURE) && (ct->subtarget[0])) { \
00703                 bPoseChannel *pchan= get_pose_channel(ct->tar->pose, ct->subtarget); \
00704                 ct->type = CONSTRAINT_OBTYPE_BONE; \
00705                 ct->rotOrder= (pchan) ? (pchan->rotmode) : EULER_ORDER_DEFAULT; \
00706             }\
00707             else if (OB_TYPE_SUPPORT_VGROUP(ct->tar->type) && (ct->subtarget[0])) { \
00708                 ct->type = CONSTRAINT_OBTYPE_VERT; \
00709                 ct->rotOrder = EULER_ORDER_DEFAULT; \
00710             } \
00711             else {\
00712                 ct->type = CONSTRAINT_OBTYPE_OBJECT; \
00713                 ct->rotOrder= ct->tar->rotmode; \
00714             } \
00715         } \
00716          \
00717         BLI_addtail(list, ct); \
00718     }
00719     
00720 /* This following macro should be used for all standard single-target *_get_tars functions 
00721  * to save typing and reduce maintainance woes. It does not do the subtarget related operations
00722  * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
00723  *  really just to help this code easier to read)
00724  */
00725 // TODO: cope with getting rotation order...
00726 #define SINGLETARGETNS_GET_TARS(con, datatar, ct, list) \
00727     { \
00728         ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \
00729          \
00730         ct->tar= datatar; \
00731         ct->space= con->tarspace; \
00732         ct->flag= CONSTRAINT_TAR_TEMP; \
00733          \
00734         if (ct->tar) ct->type = CONSTRAINT_OBTYPE_OBJECT; \
00735          \
00736         BLI_addtail(list, ct); \
00737     }
00738 
00739 /* This following macro should be used for all standard single-target *_flush_tars functions
00740  * to save typing and reduce maintainance woes.
00741  * Note: the pointer to ct will be changed to point to the next in the list (as it gets removed)
00742  * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
00743  *  really just to help this code easier to read)
00744  */
00745 #define SINGLETARGET_FLUSH_TARS(con, datatar, datasubtarget, ct, list, nocopy) \
00746     { \
00747         if (ct) { \
00748             bConstraintTarget *ctn = ct->next; \
00749             if (nocopy == 0) { \
00750                 datatar= ct->tar; \
00751                 BLI_strncpy(datasubtarget, ct->subtarget, sizeof(datasubtarget)); \
00752                 con->tarspace= (char)ct->space; \
00753             } \
00754              \
00755             BLI_freelinkN(list, ct); \
00756             ct= ctn; \
00757         } \
00758     }
00759     
00760 /* This following macro should be used for all standard single-target *_flush_tars functions
00761  * to save typing and reduce maintainance woes. It does not do the subtarget related operations.
00762  * Note: the pointer to ct will be changed to point to the next in the list (as it gets removed)
00763  * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
00764  *  really just to help this code easier to read)
00765  */
00766 #define SINGLETARGETNS_FLUSH_TARS(con, datatar, ct, list, nocopy) \
00767     { \
00768         if (ct) { \
00769             bConstraintTarget *ctn = ct->next; \
00770             if (nocopy == 0) { \
00771                 datatar= ct->tar; \
00772                 con->tarspace= (char)ct->space; \
00773             } \
00774              \
00775             BLI_freelinkN(list, ct); \
00776             ct= ctn; \
00777         } \
00778     }
00779  
00780 /* --------- ChildOf Constraint ------------ */
00781 
00782 static void childof_new_data (void *cdata)
00783 {
00784     bChildOfConstraint *data= (bChildOfConstraint *)cdata;
00785     
00786     data->flag = (CHILDOF_LOCX | CHILDOF_LOCY | CHILDOF_LOCZ |
00787                     CHILDOF_ROTX |CHILDOF_ROTY | CHILDOF_ROTZ |
00788                     CHILDOF_SIZEX | CHILDOF_SIZEY | CHILDOF_SIZEZ);
00789     unit_m4(data->invmat);
00790 }
00791 
00792 static void childof_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
00793 {
00794     bChildOfConstraint *data= con->data;
00795     
00796     /* target only */
00797     func(con, (ID**)&data->tar, userdata);
00798 }
00799 
00800 static int childof_get_tars (bConstraint *con, ListBase *list)
00801 {
00802     if (con && list) {
00803         bChildOfConstraint *data= con->data;
00804         bConstraintTarget *ct;
00805         
00806         /* standard target-getting macro for single-target constraints */
00807         SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
00808         
00809         return 1;
00810     }
00811     
00812     return 0;
00813 }
00814 
00815 static void childof_flush_tars (bConstraint *con, ListBase *list, short nocopy)
00816 {
00817     if (con && list) {
00818         bChildOfConstraint *data= con->data;
00819         bConstraintTarget *ct= list->first;
00820         
00821         /* the following macro is used for all standard single-target constraints */
00822         SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
00823     }
00824 }
00825 
00826 static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
00827 {
00828     bChildOfConstraint *data= con->data;
00829     bConstraintTarget *ct= targets->first;
00830 
00831     /* only evaluate if there is a target */
00832     if (VALID_CONS_TARGET(ct)) {
00833         float parmat[4][4];
00834         
00835         /* simple matrix parenting */
00836         if(data->flag == CHILDOF_ALL) {
00837             
00838             /* multiply target (parent matrix) by offset (parent inverse) to get 
00839              * the effect of the parent that will be exherted on the owner
00840              */
00841             mult_m4_m4m4(parmat, ct->matrix, data->invmat);
00842             
00843             /* now multiply the parent matrix by the owner matrix to get the 
00844              * the effect of this constraint (i.e.  owner is 'parented' to parent)
00845              */
00846             mult_m4_m4m4(cob->matrix, parmat, cob->matrix);
00847         }
00848         else {
00849             float invmat[4][4], tempmat[4][4];
00850             float loc[3], eul[3], size[3];
00851             float loco[3], eulo[3], sizo[3];
00852             
00853             /* get offset (parent-inverse) matrix */
00854             copy_m4_m4(invmat, data->invmat);
00855             
00856             /* extract components of both matrices */
00857             copy_v3_v3(loc, ct->matrix[3]);
00858             mat4_to_eulO(eul, ct->rotOrder, ct->matrix);
00859             mat4_to_size(size, ct->matrix);
00860             
00861             copy_v3_v3(loco, invmat[3]);
00862             mat4_to_eulO(eulo, cob->rotOrder, invmat);
00863             mat4_to_size(sizo, invmat);
00864             
00865             /* disable channels not enabled */
00866             if (!(data->flag & CHILDOF_LOCX)) loc[0]= loco[0]= 0.0f;
00867             if (!(data->flag & CHILDOF_LOCY)) loc[1]= loco[1]= 0.0f;
00868             if (!(data->flag & CHILDOF_LOCZ)) loc[2]= loco[2]= 0.0f;
00869             if (!(data->flag & CHILDOF_ROTX)) eul[0]= eulo[0]= 0.0f;
00870             if (!(data->flag & CHILDOF_ROTY)) eul[1]= eulo[1]= 0.0f;
00871             if (!(data->flag & CHILDOF_ROTZ)) eul[2]= eulo[2]= 0.0f;
00872             if (!(data->flag & CHILDOF_SIZEX)) size[0]= sizo[0]= 1.0f;
00873             if (!(data->flag & CHILDOF_SIZEY)) size[1]= sizo[1]= 1.0f;
00874             if (!(data->flag & CHILDOF_SIZEZ)) size[2]= sizo[2]= 1.0f;
00875             
00876             /* make new target mat and offset mat */
00877             loc_eulO_size_to_mat4(ct->matrix, loc, eul, size, ct->rotOrder);
00878             loc_eulO_size_to_mat4(invmat, loco, eulo, sizo, cob->rotOrder);
00879             
00880             /* multiply target (parent matrix) by offset (parent inverse) to get 
00881              * the effect of the parent that will be exherted on the owner
00882              */
00883             mult_m4_m4m4(parmat, ct->matrix, invmat);
00884             
00885             /* now multiply the parent matrix by the owner matrix to get the 
00886              * the effect of this constraint (i.e.  owner is 'parented' to parent)
00887              */
00888             copy_m4_m4(tempmat, cob->matrix);
00889             mult_m4_m4m4(cob->matrix, parmat, tempmat);
00890 
00891             /* without this, changes to scale and rotation can change location
00892              * of a parentless bone or a disconnected bone. Even though its set
00893              * to zero above. */
00894             if (!(data->flag & CHILDOF_LOCX)) cob->matrix[3][0]= tempmat[3][0];
00895             if (!(data->flag & CHILDOF_LOCY)) cob->matrix[3][1]= tempmat[3][1];
00896             if (!(data->flag & CHILDOF_LOCZ)) cob->matrix[3][2]= tempmat[3][2]; 
00897         }
00898     }
00899 }
00900 
00901 /* XXX note, con->flag should be CONSTRAINT_SPACEONCE for bone-childof, patched in readfile.c */
00902 static bConstraintTypeInfo CTI_CHILDOF = {
00903     CONSTRAINT_TYPE_CHILDOF, /* type */
00904     sizeof(bChildOfConstraint), /* size */
00905     "ChildOf", /* name */
00906     "bChildOfConstraint", /* struct name */
00907     NULL, /* free data */
00908     NULL, /* relink data */
00909     childof_id_looper, /* id looper */
00910     NULL, /* copy data */
00911     childof_new_data, /* new data */
00912     childof_get_tars, /* get constraint targets */
00913     childof_flush_tars, /* flush constraint targets */
00914     default_get_tarmat, /* get a target matrix */
00915     childof_evaluate /* evaluate */
00916 };
00917 
00918 /* -------- TrackTo Constraint ------- */
00919 
00920 static void trackto_new_data (void *cdata)
00921 {
00922     bTrackToConstraint *data= (bTrackToConstraint *)cdata;
00923     
00924     data->reserved1 = TRACK_Y;
00925     data->reserved2 = UP_Z;
00926 }   
00927 
00928 static void trackto_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
00929 {
00930     bTrackToConstraint *data= con->data;
00931     
00932     /* target only */
00933     func(con, (ID**)&data->tar, userdata);
00934 }
00935 
00936 static int trackto_get_tars (bConstraint *con, ListBase *list)
00937 {
00938     if (con && list) {
00939         bTrackToConstraint *data= con->data;
00940         bConstraintTarget *ct;
00941         
00942         /* standard target-getting macro for single-target constraints */
00943         SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
00944         
00945         return 1;
00946     }
00947     
00948     return 0;
00949 }
00950 
00951 static void trackto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
00952 {
00953     if (con && list) {
00954         bTrackToConstraint *data= con->data;
00955         bConstraintTarget *ct= list->first;
00956         
00957         /* the following macro is used for all standard single-target constraints */
00958         SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
00959     }
00960 }
00961 
00962 
00963 static int basis_cross (int n, int m)
00964 {
00965     switch (n-m) {
00966         case 1: 
00967         case -2:
00968             return 1;
00969             
00970         case -1: 
00971         case 2:
00972             return -1;
00973             
00974         default:
00975             return 0;
00976     }
00977 }
00978 
00979 static void vectomat (float *vec, float *target_up, short axis, short upflag, short flags, float m[][3])
00980 {
00981     float n[3];
00982     float u[3]; /* vector specifying the up axis */
00983     float proj[3];
00984     float right[3];
00985     float neg = -1;
00986     int right_index;
00987 
00988     if (normalize_v3_v3(n, vec) == 0.0f) {
00989         n[0] = 0.0f;
00990         n[1] = 0.0f;
00991         n[2] = 1.0f;
00992     }
00993     if (axis > 2) axis -= 3;
00994     else negate_v3(n);
00995 
00996     /* n specifies the transformation of the track axis */
00997     if (flags & TARGET_Z_UP) { 
00998         /* target Z axis is the global up axis */
00999         copy_v3_v3(u, target_up);
01000     }
01001     else { 
01002         /* world Z axis is the global up axis */
01003         u[0] = 0;
01004         u[1] = 0;
01005         u[2] = 1;
01006     }
01007 
01008     /* project the up vector onto the plane specified by n */
01009     project_v3_v3v3(proj, u, n); /* first u onto n... */
01010     sub_v3_v3v3(proj, u, proj); /* then onto the plane */
01011     /* proj specifies the transformation of the up axis */
01012 
01013     if (normalize_v3(proj) == 0.0f) { /* degenerate projection */
01014         proj[0] = 0.0f;
01015         proj[1] = 1.0f;
01016         proj[2] = 0.0f;
01017     }
01018 
01019     /* Normalized cross product of n and proj specifies transformation of the right axis */
01020     cross_v3_v3v3(right, proj, n);
01021     normalize_v3(right);
01022 
01023     if (axis != upflag) {
01024         right_index = 3 - axis - upflag;
01025         neg = (float)basis_cross(axis, upflag);
01026         
01027         /* account for up direction, track direction */
01028         m[right_index][0] = neg * right[0];
01029         m[right_index][1] = neg * right[1];
01030         m[right_index][2] = neg * right[2];
01031         
01032         copy_v3_v3(m[upflag], proj);
01033         
01034         copy_v3_v3(m[axis], n);
01035     }
01036     /* identity matrix - don't do anything if the two axes are the same */
01037     else {
01038         unit_m3(m);
01039     }
01040 }
01041 
01042 
01043 static void trackto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
01044 {
01045     bTrackToConstraint *data= con->data;
01046     bConstraintTarget *ct= targets->first;
01047     
01048     if (VALID_CONS_TARGET(ct)) {
01049         float size[3], vec[3];
01050         float totmat[3][3];
01051         float tmat[4][4];
01052         
01053         /* Get size property, since ob->size is only the object's own relative size, not its global one */
01054         mat4_to_size(size, cob->matrix);
01055         
01056         /* Clear the object's rotation */   
01057         cob->matrix[0][0]=size[0];
01058         cob->matrix[0][1]=0;
01059         cob->matrix[0][2]=0;
01060         cob->matrix[1][0]=0;
01061         cob->matrix[1][1]=size[1];
01062         cob->matrix[1][2]=0;
01063         cob->matrix[2][0]=0;
01064         cob->matrix[2][1]=0;
01065         cob->matrix[2][2]=size[2];
01066         
01067         /* targetmat[2] instead of ownermat[2] is passed to vectomat
01068          * for backwards compatibility it seems... (Aligorith)
01069          */
01070         sub_v3_v3v3(vec, cob->matrix[3], ct->matrix[3]);
01071         vectomat(vec, ct->matrix[2], 
01072                 (short)data->reserved1, (short)data->reserved2, 
01073                 data->flags, totmat);
01074         
01075         copy_m4_m4(tmat, cob->matrix);
01076         mul_m4_m3m4(cob->matrix, totmat, tmat);
01077     }
01078 }
01079 
01080 static bConstraintTypeInfo CTI_TRACKTO = {
01081     CONSTRAINT_TYPE_TRACKTO, /* type */
01082     sizeof(bTrackToConstraint), /* size */
01083     "TrackTo", /* name */
01084     "bTrackToConstraint", /* struct name */
01085     NULL, /* free data */
01086     NULL, /* relink data */
01087     trackto_id_looper, /* id looper */
01088     NULL, /* copy data */
01089     trackto_new_data, /* new data */
01090     trackto_get_tars, /* get constraint targets */
01091     trackto_flush_tars, /* flush constraint targets */
01092     default_get_tarmat, /* get target matrix */
01093     trackto_evaluate /* evaluate */
01094 };
01095 
01096 /* --------- Inverse-Kinemetics --------- */
01097 
01098 static void kinematic_new_data (void *cdata)
01099 {
01100     bKinematicConstraint *data= (bKinematicConstraint *)cdata;
01101     
01102     data->weight= 1.0f;
01103     data->orientweight= 1.0f;
01104     data->iterations = 500;
01105     data->dist= 1.0f;
01106     data->flag= CONSTRAINT_IK_TIP|CONSTRAINT_IK_STRETCH|CONSTRAINT_IK_POS;
01107 }
01108 
01109 static void kinematic_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
01110 {
01111     bKinematicConstraint *data= con->data;
01112     
01113     /* chain target */
01114     func(con, (ID**)&data->tar, userdata);
01115     
01116     /* poletarget */
01117     func(con, (ID**)&data->poletar, userdata);
01118 }
01119 
01120 static int kinematic_get_tars (bConstraint *con, ListBase *list)
01121 {
01122     if (con && list) {
01123         bKinematicConstraint *data= con->data;
01124         bConstraintTarget *ct;
01125         
01126         /* standard target-getting macro for single-target constraints is used twice here */
01127         SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
01128         SINGLETARGET_GET_TARS(con, data->poletar, data->polesubtarget, ct, list)
01129         
01130         return 2;
01131     }
01132     
01133     return 0;
01134 }
01135 
01136 static void kinematic_flush_tars (bConstraint *con, ListBase *list, short nocopy)
01137 {
01138     if (con && list) {
01139         bKinematicConstraint *data= con->data;
01140         bConstraintTarget *ct= list->first;
01141         
01142         /* the following macro is used for all standard single-target constraints */
01143         SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
01144         SINGLETARGET_FLUSH_TARS(con, data->poletar, data->polesubtarget, ct, list, nocopy)
01145     }
01146 }
01147 
01148 static void kinematic_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
01149 {
01150     bKinematicConstraint *data= con->data;
01151     
01152     if (VALID_CONS_TARGET(ct)) 
01153         constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
01154     else if (ct) {
01155         if (data->flag & CONSTRAINT_IK_AUTO) {
01156             Object *ob= cob->ob;
01157             
01158             if (ob == NULL) {
01159                 unit_m4(ct->matrix);
01160             }
01161             else {
01162                 float vec[3];
01163                 /* move grabtarget into world space */
01164                 mul_v3_m4v3(vec, ob->obmat, data->grabtarget);
01165                 copy_m4_m4(ct->matrix, ob->obmat);
01166                 copy_v3_v3(ct->matrix[3], vec);
01167             }
01168         }
01169         else
01170             unit_m4(ct->matrix);
01171     }
01172 }
01173 
01174 static bConstraintTypeInfo CTI_KINEMATIC = {
01175     CONSTRAINT_TYPE_KINEMATIC, /* type */
01176     sizeof(bKinematicConstraint), /* size */
01177     "IK", /* name */
01178     "bKinematicConstraint", /* struct name */
01179     NULL, /* free data */
01180     NULL, /* relink data */
01181     kinematic_id_looper, /* id looper */
01182     NULL, /* copy data */
01183     kinematic_new_data, /* new data */
01184     kinematic_get_tars, /* get constraint targets */
01185     kinematic_flush_tars, /* flush constraint targets */
01186     kinematic_get_tarmat, /* get target matrix */
01187     NULL /* evaluate - solved as separate loop */
01188 };
01189 
01190 /* -------- Follow-Path Constraint ---------- */
01191 
01192 static void followpath_new_data (void *cdata)
01193 {
01194     bFollowPathConstraint *data= (bFollowPathConstraint *)cdata;
01195     
01196     data->trackflag = TRACK_Y;
01197     data->upflag = UP_Z;
01198     data->offset = 0;
01199     data->followflag = 0;
01200 }
01201 
01202 static void followpath_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
01203 {
01204     bFollowPathConstraint *data= con->data;
01205     
01206     /* target only */
01207     func(con, (ID**)&data->tar, userdata);
01208 }
01209 
01210 static int followpath_get_tars (bConstraint *con, ListBase *list)
01211 {
01212     if (con && list) {
01213         bFollowPathConstraint *data= con->data;
01214         bConstraintTarget *ct;
01215         
01216         /* standard target-getting macro for single-target constraints without subtargets */
01217         SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
01218         
01219         return 1;
01220     }
01221     
01222     return 0;
01223 }
01224 
01225 static void followpath_flush_tars (bConstraint *con, ListBase *list, short nocopy)
01226 {
01227     if (con && list) {
01228         bFollowPathConstraint *data= con->data;
01229         bConstraintTarget *ct= list->first;
01230         
01231         /* the following macro is used for all standard single-target constraints */
01232         SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy)
01233     }
01234 }
01235 
01236 static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
01237 {
01238     bFollowPathConstraint *data= con->data;
01239     
01240     if (VALID_CONS_TARGET(ct)) {
01241         Curve *cu= ct->tar->data;
01242         float vec[4], dir[3], radius;
01243         float totmat[4][4]= MAT4_UNITY;
01244         float curvetime;
01245 
01246         unit_m4(ct->matrix);
01247 
01248         /* note: when creating constraints that follow path, the curve gets the CU_PATH set now,
01249          *      currently for paths to work it needs to go through the bevlist/displist system (ton) 
01250          */
01251         
01252         /* only happens on reload file, but violates depsgraph still... fix! */
01253         if (cu->path==NULL || cu->path->data==NULL)
01254             makeDispListCurveTypes(cob->scene, ct->tar, 0);
01255         
01256         if (cu->path && cu->path->data) {
01257             float quat[4];
01258             if ((data->followflag & FOLLOWPATH_STATIC) == 0) {
01259                 /* animated position along curve depending on time */
01260                 Nurb *nu = cu->nurb.first;
01261                 curvetime= cu->ctime - data->offset;
01262                 
01263                 /* ctime is now a proper var setting of Curve which gets set by Animato like any other var that's animated,
01264                  * but this will only work if it actually is animated... 
01265                  *
01266                  * we divide the curvetime calculated in the previous step by the length of the path, to get a time
01267                  * factor, which then gets clamped to lie within 0.0 - 1.0 range
01268                  */
01269                 curvetime /= cu->pathlen;
01270 
01271                 if (nu && nu->flagu & CU_NURB_CYCLIC) {
01272                     /* If the curve is cyclic, enable looping around if the time is
01273                      * outside the bounds 0..1 */
01274                     if ((curvetime < 0.0f) || (curvetime > 1.0f)) {
01275                         curvetime -= floor(curvetime);
01276                     }
01277                 }
01278                 else {
01279                     /* The curve is not cyclic, so clamp to the begin/end points. */
01280                     CLAMP(curvetime, 0.0f, 1.0f);
01281                 }
01282             }
01283             else {
01284                 /* fixed position along curve */
01285                 curvetime= data->offset_fac;
01286             }
01287             
01288             if ( where_on_path(ct->tar, curvetime, vec, dir, (data->followflag & FOLLOWPATH_FOLLOW) ? quat : NULL, &radius, NULL) ) { /* quat_pt is quat or NULL*/
01289                 if (data->followflag & FOLLOWPATH_FOLLOW) {
01290 #if 0
01291                     float x1, q[4];
01292                     vec_to_quat(quat, dir, (short)data->trackflag, (short)data->upflag);
01293                     
01294                     normalize_v3(dir);
01295                     q[0]= (float)cos(0.5*vec[3]);
01296                     x1= (float)sin(0.5*vec[3]);
01297                     q[1]= -x1*dir[0];
01298                     q[2]= -x1*dir[1];
01299                     q[3]= -x1*dir[2];
01300                     mul_qt_qtqt(quat, q, quat);
01301 #else
01302                     quat_apply_track(quat, data->trackflag, data->upflag);
01303 #endif
01304 
01305                     quat_to_mat4(totmat, quat);
01306                 }
01307 
01308                 if (data->followflag & FOLLOWPATH_RADIUS) {
01309                     float tmat[4][4], rmat[4][4];
01310                     scale_m4_fl(tmat, radius);
01311                     mult_m4_m4m4(rmat, tmat, totmat);
01312                     copy_m4_m4(totmat, rmat);
01313                 }
01314                 
01315                 copy_v3_v3(totmat[3], vec);
01316                 
01317                 mul_serie_m4(ct->matrix, ct->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL);
01318             }
01319         }
01320     }
01321     else if (ct)
01322         unit_m4(ct->matrix);
01323 }
01324 
01325 static void followpath_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
01326 {
01327     bConstraintTarget *ct= targets->first;
01328     
01329     /* only evaluate if there is a target */
01330     if (VALID_CONS_TARGET(ct)) {
01331         float obmat[4][4];
01332         float size[3];
01333         bFollowPathConstraint *data= con->data;
01334         
01335         /* get Object transform (loc/rot/size) to determine transformation from path */
01336         // TODO: this used to be local at one point, but is probably more useful as-is
01337         copy_m4_m4(obmat, cob->matrix);
01338         
01339         /* get scaling of object before applying constraint */
01340         mat4_to_size(size, cob->matrix);
01341         
01342         /* apply targetmat - containing location on path, and rotation */
01343         mul_serie_m4(cob->matrix, ct->matrix, obmat, NULL, NULL, NULL, NULL, NULL, NULL);
01344         
01345         /* un-apply scaling caused by path */
01346         if ((data->followflag & FOLLOWPATH_RADIUS)==0) { /* XXX - assume that scale correction means that radius will have some scale error in it - Campbell */
01347             float obsize[3];
01348             
01349             mat4_to_size( obsize,cob->matrix);
01350             if (obsize[0])
01351                 mul_v3_fl(cob->matrix[0], size[0] / obsize[0]);
01352             if (obsize[1])
01353                 mul_v3_fl(cob->matrix[1], size[1] / obsize[1]);
01354             if (obsize[2])
01355                 mul_v3_fl(cob->matrix[2], size[2] / obsize[2]);
01356         }
01357     }
01358 }
01359 
01360 static bConstraintTypeInfo CTI_FOLLOWPATH = {
01361     CONSTRAINT_TYPE_FOLLOWPATH, /* type */
01362     sizeof(bFollowPathConstraint), /* size */
01363     "Follow Path", /* name */
01364     "bFollowPathConstraint", /* struct name */
01365     NULL, /* free data */
01366     NULL, /* relink data */
01367     followpath_id_looper, /* id looper */
01368     NULL, /* copy data */
01369     followpath_new_data, /* new data */
01370     followpath_get_tars, /* get constraint targets */
01371     followpath_flush_tars, /* flush constraint targets */
01372     followpath_get_tarmat, /* get target matrix */
01373     followpath_evaluate /* evaluate */
01374 };
01375 
01376 /* --------- Limit Location --------- */
01377 
01378 
01379 static void loclimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
01380 {
01381     bLocLimitConstraint *data = con->data;
01382     
01383     if (data->flag & LIMIT_XMIN) {
01384         if (cob->matrix[3][0] < data->xmin)
01385             cob->matrix[3][0] = data->xmin;
01386     }
01387     if (data->flag & LIMIT_XMAX) {
01388         if (cob->matrix[3][0] > data->xmax)
01389             cob->matrix[3][0] = data->xmax;
01390     }
01391     if (data->flag & LIMIT_YMIN) {
01392         if (cob->matrix[3][1] < data->ymin)
01393             cob->matrix[3][1] = data->ymin;
01394     }
01395     if (data->flag & LIMIT_YMAX) {
01396         if (cob->matrix[3][1] > data->ymax)
01397             cob->matrix[3][1] = data->ymax;
01398     }
01399     if (data->flag & LIMIT_ZMIN) {
01400         if (cob->matrix[3][2] < data->zmin) 
01401             cob->matrix[3][2] = data->zmin;
01402     }
01403     if (data->flag & LIMIT_ZMAX) {
01404         if (cob->matrix[3][2] > data->zmax)
01405             cob->matrix[3][2] = data->zmax;
01406     }
01407 }
01408 
01409 static bConstraintTypeInfo CTI_LOCLIMIT = {
01410     CONSTRAINT_TYPE_LOCLIMIT, /* type */
01411     sizeof(bLocLimitConstraint), /* size */
01412     "Limit Location", /* name */
01413     "bLocLimitConstraint", /* struct name */
01414     NULL, /* free data */
01415     NULL, /* relink data */
01416     NULL, /* id looper */
01417     NULL, /* copy data */
01418     NULL, /* new data */
01419     NULL, /* get constraint targets */
01420     NULL, /* flush constraint targets */
01421     NULL, /* get target matrix */
01422     loclimit_evaluate /* evaluate */
01423 };
01424 
01425 /* -------- Limit Rotation --------- */
01426 
01427 static void rotlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
01428 {
01429     bRotLimitConstraint *data = con->data;
01430     float loc[3];
01431     float eul[3];
01432     float size[3];
01433     
01434     copy_v3_v3(loc, cob->matrix[3]);
01435     mat4_to_size(size, cob->matrix);
01436 
01437     mat4_to_eulO(eul, cob->rotOrder, cob->matrix);
01438 
01439     /* constraint data uses radians internally */
01440     
01441     /* limiting of euler values... */
01442     if (data->flag & LIMIT_XROT) {
01443         if (eul[0] < data->xmin) 
01444             eul[0] = data->xmin;
01445             
01446         if (eul[0] > data->xmax)
01447             eul[0] = data->xmax;
01448     }
01449     if (data->flag & LIMIT_YROT) {
01450         if (eul[1] < data->ymin)
01451             eul[1] = data->ymin;
01452             
01453         if (eul[1] > data->ymax)
01454             eul[1] = data->ymax;
01455     }
01456     if (data->flag & LIMIT_ZROT) {
01457         if (eul[2] < data->zmin)
01458             eul[2] = data->zmin;
01459             
01460         if (eul[2] > data->zmax)
01461             eul[2] = data->zmax;
01462     }
01463         
01464     loc_eulO_size_to_mat4(cob->matrix, loc, eul, size, cob->rotOrder);
01465 }
01466 
01467 static bConstraintTypeInfo CTI_ROTLIMIT = {
01468     CONSTRAINT_TYPE_ROTLIMIT, /* type */
01469     sizeof(bRotLimitConstraint), /* size */
01470     "Limit Rotation", /* name */
01471     "bRotLimitConstraint", /* struct name */
01472     NULL, /* free data */
01473     NULL, /* relink data */
01474     NULL, /* id looper */
01475     NULL, /* copy data */
01476     NULL, /* new data */
01477     NULL, /* get constraint targets */
01478     NULL, /* flush constraint targets */
01479     NULL, /* get target matrix */
01480     rotlimit_evaluate /* evaluate */
01481 };
01482 
01483 /* --------- Limit Scaling --------- */
01484 
01485 
01486 static void sizelimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
01487 {
01488     bSizeLimitConstraint *data = con->data;
01489     float obsize[3], size[3];
01490     
01491     mat4_to_size( size,cob->matrix);
01492     mat4_to_size( obsize,cob->matrix);
01493     
01494     if (data->flag & LIMIT_XMIN) {
01495         if (size[0] < data->xmin) 
01496             size[0] = data->xmin;   
01497     }
01498     if (data->flag & LIMIT_XMAX) {
01499         if (size[0] > data->xmax) 
01500             size[0] = data->xmax;
01501     }
01502     if (data->flag & LIMIT_YMIN) {
01503         if (size[1] < data->ymin) 
01504             size[1] = data->ymin;   
01505     }
01506     if (data->flag & LIMIT_YMAX) {
01507         if (size[1] > data->ymax) 
01508             size[1] = data->ymax;
01509     }
01510     if (data->flag & LIMIT_ZMIN) {
01511         if (size[2] < data->zmin) 
01512             size[2] = data->zmin;   
01513     }
01514     if (data->flag & LIMIT_ZMAX) {
01515         if (size[2] > data->zmax) 
01516             size[2] = data->zmax;
01517     }
01518     
01519     if (obsize[0]) 
01520         mul_v3_fl(cob->matrix[0], size[0]/obsize[0]);
01521     if (obsize[1]) 
01522         mul_v3_fl(cob->matrix[1], size[1]/obsize[1]);
01523     if (obsize[2]) 
01524         mul_v3_fl(cob->matrix[2], size[2]/obsize[2]);
01525 }
01526 
01527 static bConstraintTypeInfo CTI_SIZELIMIT = {
01528     CONSTRAINT_TYPE_SIZELIMIT, /* type */
01529     sizeof(bSizeLimitConstraint), /* size */
01530     "Limit Scaling", /* name */
01531     "bSizeLimitConstraint", /* struct name */
01532     NULL, /* free data */
01533     NULL, /* relink data */
01534     NULL, /* id looper */
01535     NULL, /* copy data */
01536     NULL, /* new data */
01537     NULL, /* get constraint targets */
01538     NULL, /* flush constraint targets */
01539     NULL, /* get target matrix */
01540     sizelimit_evaluate /* evaluate */
01541 };
01542 
01543 /* ----------- Copy Location ------------- */
01544 
01545 static void loclike_new_data (void *cdata)
01546 {
01547     bLocateLikeConstraint *data= (bLocateLikeConstraint *)cdata;
01548     
01549     data->flag = LOCLIKE_X|LOCLIKE_Y|LOCLIKE_Z;
01550 }
01551 
01552 static void loclike_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
01553 {
01554     bLocateLikeConstraint *data= con->data;
01555     
01556     /* target only */
01557     func(con, (ID**)&data->tar, userdata);
01558 }
01559 
01560 static int loclike_get_tars (bConstraint *con, ListBase *list)
01561 {
01562     if (con && list) {
01563         bLocateLikeConstraint *data= con->data;
01564         bConstraintTarget *ct;
01565         
01566         /* standard target-getting macro for single-target constraints */
01567         SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
01568         
01569         return 1;
01570     }
01571     
01572     return 0;
01573 }
01574 
01575 static void loclike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
01576 {
01577     if (con && list) {
01578         bLocateLikeConstraint *data= con->data;
01579         bConstraintTarget *ct= list->first;
01580         
01581         /* the following macro is used for all standard single-target constraints */
01582         SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
01583     }
01584 }
01585 
01586 static void loclike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
01587 {
01588     bLocateLikeConstraint *data= con->data;
01589     bConstraintTarget *ct= targets->first;
01590     
01591     if (VALID_CONS_TARGET(ct)) {
01592         float offset[3] = {0.0f, 0.0f, 0.0f};
01593         
01594         if (data->flag & LOCLIKE_OFFSET)
01595             copy_v3_v3(offset, cob->matrix[3]);
01596             
01597         if (data->flag & LOCLIKE_X) {
01598             cob->matrix[3][0] = ct->matrix[3][0];
01599             
01600             if (data->flag & LOCLIKE_X_INVERT) cob->matrix[3][0] *= -1;
01601             cob->matrix[3][0] += offset[0];
01602         }
01603         if (data->flag & LOCLIKE_Y) {
01604             cob->matrix[3][1] = ct->matrix[3][1];
01605             
01606             if (data->flag & LOCLIKE_Y_INVERT) cob->matrix[3][1] *= -1;
01607             cob->matrix[3][1] += offset[1];
01608         }
01609         if (data->flag & LOCLIKE_Z) {
01610             cob->matrix[3][2] = ct->matrix[3][2];
01611             
01612             if (data->flag & LOCLIKE_Z_INVERT) cob->matrix[3][2] *= -1;
01613             cob->matrix[3][2] += offset[2];
01614         }
01615     }
01616 }
01617 
01618 static bConstraintTypeInfo CTI_LOCLIKE = {
01619     CONSTRAINT_TYPE_LOCLIKE, /* type */
01620     sizeof(bLocateLikeConstraint), /* size */
01621     "Copy Location", /* name */
01622     "bLocateLikeConstraint", /* struct name */
01623     NULL, /* free data */
01624     NULL, /* relink data */
01625     loclike_id_looper, /* id looper */
01626     NULL, /* copy data */
01627     loclike_new_data, /* new data */
01628     loclike_get_tars, /* get constraint targets */
01629     loclike_flush_tars, /* flush constraint targets */
01630     default_get_tarmat, /* get target matrix */
01631     loclike_evaluate /* evaluate */
01632 };
01633 
01634 /* ----------- Copy Rotation ------------- */
01635 
01636 static void rotlike_new_data (void *cdata)
01637 {
01638     bRotateLikeConstraint *data= (bRotateLikeConstraint *)cdata;
01639     
01640     data->flag = ROTLIKE_X|ROTLIKE_Y|ROTLIKE_Z;
01641 }
01642 
01643 static void rotlike_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
01644 {
01645     bChildOfConstraint *data= con->data;
01646     
01647     /* target only */
01648     func(con, (ID**)&data->tar, userdata);
01649 }
01650 
01651 static int rotlike_get_tars (bConstraint *con, ListBase *list)
01652 {
01653     if (con && list) {
01654         bRotateLikeConstraint *data= con->data;
01655         bConstraintTarget *ct;
01656         
01657         /* standard target-getting macro for single-target constraints */
01658         SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
01659         
01660         return 1;
01661     }
01662     
01663     return 0;
01664 }
01665 
01666 static void rotlike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
01667 {
01668     if (con && list) {
01669         bRotateLikeConstraint *data= con->data;
01670         bConstraintTarget *ct= list->first;
01671         
01672         /* the following macro is used for all standard single-target constraints */
01673         SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
01674     }
01675 }
01676 
01677 static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
01678 {
01679     bRotateLikeConstraint *data= con->data;
01680     bConstraintTarget *ct= targets->first;
01681     
01682     if (VALID_CONS_TARGET(ct)) {
01683         float   loc[3];
01684         float   eul[3], obeul[3];
01685         float   size[3];
01686         
01687         copy_v3_v3(loc, cob->matrix[3]);
01688         mat4_to_size(size, cob->matrix);
01689         
01690         /* to allow compatible rotations, must get both rotations in the order of the owner... */
01691         mat4_to_eulO(obeul, cob->rotOrder, cob->matrix);
01692         /* we must get compatible eulers from the beginning because some of them can be modified below (see bug #21875) */
01693         mat4_to_compatible_eulO(eul, obeul, cob->rotOrder, ct->matrix);
01694         
01695         if ((data->flag & ROTLIKE_X)==0)
01696             eul[0] = obeul[0];
01697         else {
01698             if (data->flag & ROTLIKE_OFFSET)
01699                 rotate_eulO(eul, cob->rotOrder, 'X', obeul[0]);
01700             
01701             if (data->flag & ROTLIKE_X_INVERT)
01702                 eul[0] *= -1;
01703         }
01704         
01705         if ((data->flag & ROTLIKE_Y)==0)
01706             eul[1] = obeul[1];
01707         else {
01708             if (data->flag & ROTLIKE_OFFSET)
01709                 rotate_eulO(eul, cob->rotOrder, 'Y', obeul[1]);
01710             
01711             if (data->flag & ROTLIKE_Y_INVERT)
01712                 eul[1] *= -1;
01713         }
01714         
01715         if ((data->flag & ROTLIKE_Z)==0)
01716             eul[2] = obeul[2];
01717         else {
01718             if (data->flag & ROTLIKE_OFFSET)
01719                 rotate_eulO(eul, cob->rotOrder, 'Z', obeul[2]);
01720             
01721             if (data->flag & ROTLIKE_Z_INVERT)
01722                 eul[2] *= -1;
01723         }
01724         
01725         /* good to make eulers compatible again, since we don't know how much they were changed above */
01726         compatible_eul(eul, obeul);
01727         loc_eulO_size_to_mat4(cob->matrix, loc, eul, size, cob->rotOrder);
01728     }
01729 }
01730 
01731 static bConstraintTypeInfo CTI_ROTLIKE = {
01732     CONSTRAINT_TYPE_ROTLIKE, /* type */
01733     sizeof(bRotateLikeConstraint), /* size */
01734     "Copy Rotation", /* name */
01735     "bRotateLikeConstraint", /* struct name */
01736     NULL, /* free data */
01737     NULL, /* relink data */
01738     rotlike_id_looper, /* id looper */
01739     NULL, /* copy data */
01740     rotlike_new_data, /* new data */
01741     rotlike_get_tars, /* get constraint targets */
01742     rotlike_flush_tars, /* flush constraint targets */
01743     default_get_tarmat, /* get target matrix */
01744     rotlike_evaluate /* evaluate */
01745 };
01746 
01747 /* ---------- Copy Scaling ---------- */
01748 
01749 static void sizelike_new_data (void *cdata)
01750 {
01751     bSizeLikeConstraint *data= (bSizeLikeConstraint *)cdata;
01752     
01753     data->flag = SIZELIKE_X|SIZELIKE_Y|SIZELIKE_Z;
01754 }
01755 
01756 static void sizelike_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
01757 {
01758     bSizeLikeConstraint *data= con->data;
01759     
01760     /* target only */
01761     func(con, (ID**)&data->tar, userdata);
01762 }
01763 
01764 static int sizelike_get_tars (bConstraint *con, ListBase *list)
01765 {
01766     if (con && list) {
01767         bSizeLikeConstraint *data= con->data;
01768         bConstraintTarget *ct;
01769         
01770         /* standard target-getting macro for single-target constraints */
01771         SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
01772         
01773         return 1;
01774     }
01775     
01776     return 0;
01777 }
01778 
01779 static void sizelike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
01780 {
01781     if (con && list) {
01782         bSizeLikeConstraint *data= con->data;
01783         bConstraintTarget *ct= list->first;
01784         
01785         /* the following macro is used for all standard single-target constraints */
01786         SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
01787     }
01788 }
01789 
01790 static void sizelike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
01791 {
01792     bSizeLikeConstraint *data= con->data;
01793     bConstraintTarget *ct= targets->first;
01794     
01795     if (VALID_CONS_TARGET(ct)) {
01796         float obsize[3], size[3];
01797         
01798         mat4_to_size(size, ct->matrix);
01799         mat4_to_size(obsize, cob->matrix);
01800         
01801         if ((data->flag & SIZELIKE_X) && (obsize[0] != 0)) {
01802             if (data->flag & SIZELIKE_OFFSET) {
01803                 size[0] += (obsize[0] - 1.0f);
01804                 mul_v3_fl(cob->matrix[0], size[0] / obsize[0]);
01805             }
01806             else
01807                 mul_v3_fl(cob->matrix[0], size[0] / obsize[0]);
01808         }
01809         if ((data->flag & SIZELIKE_Y) && (obsize[1] != 0)) {
01810             if (data->flag & SIZELIKE_OFFSET) {
01811                 size[1] += (obsize[1] - 1.0f);
01812                 mul_v3_fl(cob->matrix[1], size[1] / obsize[1]);
01813             }
01814             else
01815                 mul_v3_fl(cob->matrix[1], size[1] / obsize[1]);
01816         }
01817         if ((data->flag & SIZELIKE_Z) && (obsize[2] != 0)) {
01818             if (data->flag & SIZELIKE_OFFSET) {
01819                 size[2] += (obsize[2] - 1.0f);
01820                 mul_v3_fl(cob->matrix[2], size[2] / obsize[2]);
01821             }
01822             else
01823                 mul_v3_fl(cob->matrix[2], size[2] / obsize[2]);
01824         }
01825     }
01826 }
01827 
01828 static bConstraintTypeInfo CTI_SIZELIKE = {
01829     CONSTRAINT_TYPE_SIZELIKE, /* type */
01830     sizeof(bSizeLikeConstraint), /* size */
01831     "Copy Scale", /* name */
01832     "bSizeLikeConstraint", /* struct name */
01833     NULL, /* free data */
01834     NULL, /* relink data */
01835     sizelike_id_looper, /* id looper */
01836     NULL, /* copy data */
01837     sizelike_new_data, /* new data */
01838     sizelike_get_tars, /* get constraint targets */
01839     sizelike_flush_tars, /* flush constraint targets */
01840     default_get_tarmat, /* get target matrix */
01841     sizelike_evaluate /* evaluate */
01842 };
01843 
01844 /* ----------- Copy Transforms ------------- */
01845 
01846 static void translike_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
01847 {
01848     bTransLikeConstraint *data= con->data;
01849     
01850     /* target only */
01851     func(con, (ID**)&data->tar, userdata);
01852 }
01853 
01854 static int translike_get_tars (bConstraint *con, ListBase *list)
01855 {
01856     if (con && list) {
01857         bTransLikeConstraint *data= con->data;
01858         bConstraintTarget *ct;
01859         
01860         /* standard target-getting macro for single-target constraints */
01861         SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
01862         
01863         return 1;
01864     }
01865     
01866     return 0;
01867 }
01868 
01869 static void translike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
01870 {
01871     if (con && list) {
01872         bTransLikeConstraint *data= con->data;
01873         bConstraintTarget *ct= list->first;
01874         
01875         /* the following macro is used for all standard single-target constraints */
01876         SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
01877     }
01878 }
01879 
01880 static void translike_evaluate (bConstraint *UNUSED(con), bConstraintOb *cob, ListBase *targets)
01881 {
01882     bConstraintTarget *ct= targets->first;
01883     
01884     if (VALID_CONS_TARGET(ct)) {
01885         /* just copy the entire transform matrix of the target */
01886         copy_m4_m4(cob->matrix, ct->matrix);
01887     }
01888 }
01889 
01890 static bConstraintTypeInfo CTI_TRANSLIKE = {
01891     CONSTRAINT_TYPE_TRANSLIKE, /* type */
01892     sizeof(bTransLikeConstraint), /* size */
01893     "Copy Transforms", /* name */
01894     "bTransLikeConstraint", /* struct name */
01895     NULL, /* free data */
01896     NULL, /* relink data */
01897     translike_id_looper, /* id looper */
01898     NULL, /* copy data */
01899     NULL, /* new data */
01900     translike_get_tars, /* get constraint targets */
01901     translike_flush_tars, /* flush constraint targets */
01902     default_get_tarmat, /* get target matrix */
01903     translike_evaluate /* evaluate */
01904 };
01905 
01906 /* ---------- Maintain Volume ---------- */
01907 
01908 static void samevolume_new_data (void *cdata)
01909 {
01910     bSameVolumeConstraint *data= (bSameVolumeConstraint *)cdata;
01911 
01912     data->flag = SAMEVOL_Y;
01913     data->volume = 1.0f;
01914 }
01915 
01916 static void samevolume_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
01917 {
01918     bSameVolumeConstraint *data= con->data;
01919 
01920     float volume = data->volume;
01921     float fac = 1.0f;
01922     float obsize[3];
01923 
01924     mat4_to_size(obsize, cob->matrix);
01925     
01926     /* calculate normalising scale factor for non-essential values */
01927     if (obsize[data->flag] != 0) 
01928         fac = sqrtf(volume / obsize[data->flag]) / obsize[data->flag];
01929     
01930     /* apply scaling factor to the channels not being kept */
01931     switch (data->flag) {
01932         case SAMEVOL_X:
01933             mul_v3_fl(cob->matrix[1], fac);
01934             mul_v3_fl(cob->matrix[2], fac);
01935             break;
01936         case SAMEVOL_Y:
01937             mul_v3_fl(cob->matrix[0], fac);
01938             mul_v3_fl(cob->matrix[2], fac);
01939             break;
01940         case SAMEVOL_Z:
01941             mul_v3_fl(cob->matrix[0], fac);
01942             mul_v3_fl(cob->matrix[1], fac);
01943             break;
01944     }
01945 }
01946 
01947 static bConstraintTypeInfo CTI_SAMEVOL = {
01948     CONSTRAINT_TYPE_SAMEVOL, /* type */
01949     sizeof(bSameVolumeConstraint), /* size */
01950     "Maintain Volume", /* name */
01951     "bSameVolumeConstraint", /* struct name */
01952     NULL, /* free data */
01953     NULL, /* relink data */
01954     NULL, /* id looper */
01955     NULL, /* copy data */
01956     samevolume_new_data, /* new data */
01957     NULL, /* get constraint targets */
01958     NULL, /* flush constraint targets */
01959     NULL, /* get target matrix */
01960     samevolume_evaluate /* evaluate */
01961 };
01962 
01963 /* ----------- Python Constraint -------------- */
01964 
01965 static void pycon_free (bConstraint *con)
01966 {
01967     bPythonConstraint *data= con->data;
01968     
01969     /* id-properties */
01970     IDP_FreeProperty(data->prop);
01971     MEM_freeN(data->prop);
01972     
01973     /* multiple targets */
01974     BLI_freelistN(&data->targets);
01975 }   
01976 
01977 static void pycon_relink (bConstraint *con)
01978 {
01979     bPythonConstraint *data= con->data;
01980     
01981     ID_NEW(data->text);
01982 }
01983 
01984 static void pycon_copy (bConstraint *con, bConstraint *srccon)
01985 {
01986     bPythonConstraint *pycon = (bPythonConstraint *)con->data;
01987     bPythonConstraint *opycon = (bPythonConstraint *)srccon->data;
01988     
01989     pycon->prop = IDP_CopyProperty(opycon->prop);
01990     BLI_duplicatelist(&pycon->targets, &opycon->targets);
01991 }
01992 
01993 static void pycon_new_data (void *cdata)
01994 {
01995     bPythonConstraint *data= (bPythonConstraint *)cdata;
01996     
01997     /* everything should be set correctly by calloc, except for the prop->type constant.*/
01998     data->prop = MEM_callocN(sizeof(IDProperty), "PyConstraintProps");
01999     data->prop->type = IDP_GROUP;
02000 }
02001 
02002 static int pycon_get_tars (bConstraint *con, ListBase *list)
02003 {
02004     if (con && list) {
02005         bPythonConstraint *data= con->data;
02006         
02007         list->first = data->targets.first;
02008         list->last = data->targets.last;
02009         
02010         return data->tarnum;
02011     }
02012     
02013     return 0;
02014 }
02015 
02016 static void pycon_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
02017 {
02018     bPythonConstraint *data= con->data;
02019     bConstraintTarget *ct;
02020     
02021     /* targets */
02022     for (ct= data->targets.first; ct; ct= ct->next)
02023         func(con, (ID**)&ct->tar, userdata);
02024         
02025     /* script */
02026     func(con, (ID**)&data->text, userdata);
02027 }
02028 
02029 /* Whether this approach is maintained remains to be seen (aligorith) */
02030 static void pycon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
02031 {
02032 #ifdef WITH_PYTHON
02033     bPythonConstraint *data= con->data;
02034 #endif
02035 
02036     if (VALID_CONS_TARGET(ct)) {
02037         /* special exception for curves - depsgraph issues */
02038         if (ct->tar->type == OB_CURVE) {
02039             Curve *cu= ct->tar->data;
02040             
02041             /* this check is to make sure curve objects get updated on file load correctly.*/
02042             if (cu->path==NULL || cu->path->data==NULL) /* only happens on reload file, but violates depsgraph still... fix! */
02043                 makeDispListCurveTypes(cob->scene, ct->tar, 0);             
02044         }
02045         
02046         /* firstly calculate the matrix the normal way, then let the py-function override
02047          * this matrix if it needs to do so
02048          */
02049         constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
02050         
02051         /* only execute target calculation if allowed */
02052 #ifdef WITH_PYTHON
02053         if (G.f & G_SCRIPT_AUTOEXEC)
02054             BPY_pyconstraint_target(data, ct);
02055 #endif
02056     }
02057     else if (ct)
02058         unit_m4(ct->matrix);
02059 }
02060 
02061 static void pycon_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
02062 {
02063 #ifndef WITH_PYTHON
02064     (void)con; (void)cob; (void)targets; /* unused */
02065     return;
02066 #else
02067     bPythonConstraint *data= con->data;
02068     
02069     /* only evaluate in python if we're allowed to do so */
02070     if ((G.f & G_SCRIPT_AUTOEXEC)==0)  return;
02071     
02072 /* currently removed, until I this can be re-implemented for multiple targets */
02073 #if 0
02074     /* Firstly, run the 'driver' function which has direct access to the objects involved 
02075      * Technically, this is potentially dangerous as users may abuse this and cause dependency-problems,
02076      * but it also allows certain 'clever' rigging hacks to work.
02077      */
02078     BPY_pyconstraint_driver(data, cob, targets);
02079 #endif
02080     
02081     /* Now, run the actual 'constraint' function, which should only access the matrices */
02082     BPY_pyconstraint_exec(data, cob, targets);
02083 #endif /* WITH_PYTHON */
02084 }
02085 
02086 static bConstraintTypeInfo CTI_PYTHON = {
02087     CONSTRAINT_TYPE_PYTHON, /* type */
02088     sizeof(bPythonConstraint), /* size */
02089     "Script", /* name */
02090     "bPythonConstraint", /* struct name */
02091     pycon_free, /* free data */
02092     pycon_relink, /* relink data */
02093     pycon_id_looper, /* id looper */
02094     pycon_copy, /* copy data */
02095     pycon_new_data, /* new data */
02096     pycon_get_tars, /* get constraint targets */
02097     NULL, /* flush constraint targets */
02098     pycon_get_tarmat, /* get target matrix */
02099     pycon_evaluate /* evaluate */
02100 };
02101 
02102 /* -------- Action Constraint ----------- */
02103 
02104 static void actcon_relink (bConstraint *con)
02105 {
02106     bActionConstraint *data= con->data;
02107     ID_NEW(data->act);
02108 }
02109 
02110 static void actcon_new_data (void *cdata)
02111 {
02112     bActionConstraint *data= (bActionConstraint *)cdata;
02113     
02114     /* set type to 20 (Loc X), as 0 is Rot X for backwards compatibility */
02115     data->type = 20;
02116 }
02117 
02118 static void actcon_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
02119 {
02120     bActionConstraint *data= con->data;
02121     
02122     /* target */
02123     func(con, (ID**)&data->tar, userdata);
02124     
02125     /* action */
02126     func(con, (ID**)&data->act, userdata);
02127 }
02128 
02129 static int actcon_get_tars (bConstraint *con, ListBase *list)
02130 {
02131     if (con && list) {
02132         bActionConstraint *data= con->data;
02133         bConstraintTarget *ct;
02134         
02135         /* standard target-getting macro for single-target constraints */
02136         SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
02137         
02138         return 1;
02139     }
02140     
02141     return 0;
02142 }
02143 
02144 static void actcon_flush_tars (bConstraint *con, ListBase *list, short nocopy)
02145 {
02146     if (con && list) {
02147         bActionConstraint *data= con->data;
02148         bConstraintTarget *ct= list->first;
02149         
02150         /* the following macro is used for all standard single-target constraints */
02151         SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
02152     }
02153 }
02154 
02155 static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
02156 {
02157     bActionConstraint *data = con->data;
02158     
02159     if (VALID_CONS_TARGET(ct)) {
02160         float tempmat[4][4], vec[3];
02161         float s, t;
02162         short axis;
02163         
02164         /* initialise return matrix */
02165         unit_m4(ct->matrix);
02166         
02167         /* get the transform matrix of the target */
02168         constraint_target_to_mat4(ct->tar, ct->subtarget, tempmat, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
02169         
02170         /* determine where in transform range target is */
02171         /* data->type is mapped as follows for backwards compatibility:
02172          *  00,01,02    - rotation (it used to be like this)
02173          *  10,11,12    - scaling
02174          *  20,21,22    - location
02175          */
02176         if (data->type < 10) {
02177             /* extract rotation (is in whatever space target should be in) */
02178             mat4_to_eul(vec, tempmat);
02179             mul_v3_fl(vec, RAD2DEGF(1.0f)); /* rad -> deg */
02180             axis= data->type;
02181         }
02182         else if (data->type < 20) {
02183             /* extract scaling (is in whatever space target should be in) */
02184             mat4_to_size(vec, tempmat);
02185             axis= data->type - 10;
02186         }
02187         else {
02188             /* extract location */
02189             copy_v3_v3(vec, tempmat[3]);
02190             axis= data->type - 20;
02191         }
02192         
02193         /* Target defines the animation */
02194         s = (vec[axis]-data->min) / (data->max-data->min);
02195         CLAMP(s, 0, 1);
02196         t = (s * (data->end-data->start)) + data->start;
02197         
02198         if (G.f & G_DEBUG)
02199             printf("do Action Constraint %s - Ob %s Pchan %s \n", con->name, cob->ob->id.name+2, (cob->pchan)?cob->pchan->name:NULL);
02200         
02201         /* Get the appropriate information from the action */
02202         if (cob->type == CONSTRAINT_OBTYPE_BONE) {
02203             Object workob;
02204             bPose *pose;
02205             bPoseChannel *pchan, *tchan;
02206             
02207             /* make a temporary pose and evaluate using that */
02208             pose = MEM_callocN(sizeof(bPose), "pose");
02209             
02210             /* make a copy of the bone of interest in the temp pose before evaluating action, so that it can get set 
02211              *  - we need to manually copy over a few settings, including rotation order, otherwise this fails
02212              */
02213             pchan = cob->pchan;
02214             
02215             tchan= verify_pose_channel(pose, pchan->name);
02216             tchan->rotmode= pchan->rotmode;
02217             
02218             /* evaluate action using workob (it will only set the PoseChannel in question) */
02219             what_does_obaction(cob->ob, &workob, pose, data->act, pchan->name, t);
02220             
02221             /* convert animation to matrices for use here */
02222             pchan_calc_mat(tchan);
02223             copy_m4_m4(ct->matrix, tchan->chan_mat);
02224             
02225             /* Clean up */
02226             free_pose(pose);
02227         }
02228         else if (cob->type == CONSTRAINT_OBTYPE_OBJECT) {
02229             Object workob;
02230             
02231             /* evaluate using workob */
02232             // FIXME: we don't have any consistent standards on limiting effects on object...
02233             what_does_obaction(cob->ob, &workob, NULL, data->act, NULL, t);
02234             object_to_mat4(&workob, ct->matrix);
02235         }
02236         else {
02237             /* behaviour undefined... */
02238             puts("Error: unknown owner type for Action Constraint");
02239         }
02240     }
02241 }
02242 
02243 static void actcon_evaluate (bConstraint *UNUSED(con), bConstraintOb *cob, ListBase *targets)
02244 {
02245     bConstraintTarget *ct= targets->first;
02246     
02247     if (VALID_CONS_TARGET(ct)) {
02248         float temp[4][4];
02249         
02250         /* Nice and simple... we just need to multiply the matrices, as the get_target_matrix
02251          * function has already taken care of everything else.
02252          */
02253         copy_m4_m4(temp, cob->matrix);
02254         mult_m4_m4m4(cob->matrix, temp, ct->matrix);
02255     }
02256 }
02257 
02258 static bConstraintTypeInfo CTI_ACTION = {
02259     CONSTRAINT_TYPE_ACTION, /* type */
02260     sizeof(bActionConstraint), /* size */
02261     "Action", /* name */
02262     "bActionConstraint", /* struct name */
02263     NULL, /* free data */
02264     actcon_relink, /* relink data */
02265     actcon_id_looper, /* id looper */
02266     NULL, /* copy data */
02267     actcon_new_data, /* new data */
02268     actcon_get_tars, /* get constraint targets */
02269     actcon_flush_tars, /* flush constraint targets */
02270     actcon_get_tarmat, /* get target matrix */
02271     actcon_evaluate /* evaluate */
02272 };
02273 
02274 /* --------- Locked Track ---------- */
02275 
02276 static void locktrack_new_data (void *cdata)
02277 {
02278     bLockTrackConstraint *data= (bLockTrackConstraint *)cdata;
02279     
02280     data->trackflag = TRACK_Y;
02281     data->lockflag = LOCK_Z;
02282 }   
02283 
02284 static void locktrack_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
02285 {
02286     bLockTrackConstraint *data= con->data;
02287     
02288     /* target only */
02289     func(con, (ID**)&data->tar, userdata);
02290 }
02291 
02292 static int locktrack_get_tars (bConstraint *con, ListBase *list)
02293 {
02294     if (con && list) {
02295         bLockTrackConstraint *data= con->data;
02296         bConstraintTarget *ct;
02297         
02298         /* the following macro is used for all standard single-target constraints */
02299         SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
02300         
02301         return 1;
02302     }
02303     
02304     return 0;
02305 }
02306 
02307 static void locktrack_flush_tars (bConstraint *con, ListBase *list, short nocopy)
02308 {
02309     if (con && list) {
02310         bLockTrackConstraint *data= con->data;
02311         bConstraintTarget *ct= list->first;
02312         
02313         /* the following macro is used for all standard single-target constraints */
02314         SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
02315     }
02316 }
02317 
02318 static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
02319 {
02320     bLockTrackConstraint *data= con->data;
02321     bConstraintTarget *ct= targets->first;
02322     
02323     if (VALID_CONS_TARGET(ct)) {
02324         float vec[3],vec2[3];
02325         float totmat[3][3];
02326         float tmpmat[3][3];
02327         float invmat[3][3];
02328         float tmat[4][4];
02329         float mdet;
02330         
02331         /* Vector object -> target */
02332         sub_v3_v3v3(vec, ct->matrix[3], cob->matrix[3]);
02333         switch (data->lockflag){
02334         case LOCK_X: /* LOCK X */
02335         {
02336             switch (data->trackflag) {
02337                 case TRACK_Y: /* LOCK X TRACK Y */
02338                 {
02339                     /* Projection of Vector on the plane */
02340                     project_v3_v3v3(vec2, vec, cob->matrix[0]);
02341                     sub_v3_v3v3(totmat[1], vec, vec2);
02342                     normalize_v3(totmat[1]);
02343                     
02344                     /* the x axis is fixed */
02345                     normalize_v3_v3(totmat[0], cob->matrix[0]);
02346                     
02347                     /* the z axis gets mapped onto a third orthogonal vector */
02348                     cross_v3_v3v3(totmat[2], totmat[0], totmat[1]);
02349                 }
02350                     break;
02351                 case TRACK_Z: /* LOCK X TRACK Z */
02352                 {
02353                     /* Projection of Vector on the plane */
02354                     project_v3_v3v3(vec2, vec, cob->matrix[0]);
02355                     sub_v3_v3v3(totmat[2], vec, vec2);
02356                     normalize_v3(totmat[2]);
02357                     
02358                     /* the x axis is fixed */
02359                     normalize_v3_v3(totmat[0], cob->matrix[0]);
02360                     
02361                     /* the z axis gets mapped onto a third orthogonal vector */
02362                     cross_v3_v3v3(totmat[1], totmat[2], totmat[0]);
02363                 }
02364                     break;
02365                 case TRACK_nY: /* LOCK X TRACK -Y */
02366                 {
02367                     /* Projection of Vector on the plane */
02368                     project_v3_v3v3(vec2, vec, cob->matrix[0]);
02369                     sub_v3_v3v3(totmat[1], vec, vec2);
02370                     normalize_v3(totmat[1]);
02371                     negate_v3(totmat[1]);
02372                     
02373                     /* the x axis is fixed */
02374                     normalize_v3_v3(totmat[0], cob->matrix[0]);
02375                     
02376                     /* the z axis gets mapped onto a third orthogonal vector */
02377                     cross_v3_v3v3(totmat[2], totmat[0], totmat[1]);
02378                 }
02379                     break;
02380                 case TRACK_nZ: /* LOCK X TRACK -Z */
02381                 {
02382                     /* Projection of Vector on the plane */
02383                     project_v3_v3v3(vec2, vec, cob->matrix[0]);
02384                     sub_v3_v3v3(totmat[2], vec, vec2);
02385                     normalize_v3(totmat[2]);
02386                     negate_v3(totmat[2]);
02387                         
02388                     /* the x axis is fixed */
02389                     normalize_v3_v3(totmat[0], cob->matrix[0]);
02390                         
02391                     /* the z axis gets mapped onto a third orthogonal vector */
02392                     cross_v3_v3v3(totmat[1], totmat[2], totmat[0]);
02393                 }
02394                     break;
02395                 default:
02396                 {
02397                     unit_m3(totmat);
02398                 }
02399                     break;
02400             }
02401         }
02402             break;
02403         case LOCK_Y: /* LOCK Y */
02404         {
02405             switch (data->trackflag) {
02406                 case TRACK_X: /* LOCK Y TRACK X */
02407                 {
02408                     /* Projection of Vector on the plane */
02409                     project_v3_v3v3(vec2, vec, cob->matrix[1]);
02410                     sub_v3_v3v3(totmat[0], vec, vec2);
02411                     normalize_v3(totmat[0]);
02412                     
02413                     /* the y axis is fixed */
02414                     normalize_v3_v3(totmat[1], cob->matrix[1]);
02415 
02416                     /* the z axis gets mapped onto a third orthogonal vector */
02417                     cross_v3_v3v3(totmat[2], totmat[0], totmat[1]);
02418                 }
02419                     break;
02420                 case TRACK_Z: /* LOCK Y TRACK Z */
02421                 {
02422                     /* Projection of Vector on the plane */
02423                     project_v3_v3v3(vec2, vec, cob->matrix[1]);
02424                     sub_v3_v3v3(totmat[2], vec, vec2);
02425                     normalize_v3(totmat[2]);
02426                     
02427                     /* the y axis is fixed */
02428                     normalize_v3_v3(totmat[1], cob->matrix[1]);
02429                     
02430                     /* the z axis gets mapped onto a third orthogonal vector */
02431                     cross_v3_v3v3(totmat[0], totmat[1], totmat[2]);
02432                 }
02433                     break;
02434                 case TRACK_nX: /* LOCK Y TRACK -X */
02435                 {
02436                     /* Projection of Vector on the plane */
02437                     project_v3_v3v3(vec2, vec, cob->matrix[1]);
02438                     sub_v3_v3v3(totmat[0], vec, vec2);
02439                     normalize_v3(totmat[0]);
02440                     negate_v3(totmat[0]);
02441                     
02442                     /* the y axis is fixed */
02443                     normalize_v3_v3(totmat[1], cob->matrix[1]);
02444                     
02445                     /* the z axis gets mapped onto a third orthogonal vector */
02446                     cross_v3_v3v3(totmat[2], totmat[0], totmat[1]);
02447                 }
02448                     break;
02449                 case TRACK_nZ: /* LOCK Y TRACK -Z */
02450                 {
02451                     /* Projection of Vector on the plane */
02452                     project_v3_v3v3(vec2, vec, cob->matrix[1]);
02453                     sub_v3_v3v3(totmat[2], vec, vec2);
02454                     normalize_v3(totmat[2]);
02455                     negate_v3(totmat[2]);
02456                     
02457                     /* the y axis is fixed */
02458                     normalize_v3_v3(totmat[1], cob->matrix[1]);
02459                     
02460                     /* the z axis gets mapped onto a third orthogonal vector */
02461                     cross_v3_v3v3(totmat[0], totmat[1], totmat[2]);
02462                 }
02463                     break;
02464                 default:
02465                 {
02466                     unit_m3(totmat);
02467                 }
02468                     break;
02469             }
02470         }
02471             break;
02472         case LOCK_Z: /* LOCK Z */
02473         {
02474             switch (data->trackflag) {
02475                 case TRACK_X: /* LOCK Z TRACK X */
02476                 {
02477                     /* Projection of Vector on the plane */
02478                     project_v3_v3v3(vec2, vec, cob->matrix[2]);
02479                     sub_v3_v3v3(totmat[0], vec, vec2);
02480                     normalize_v3(totmat[0]);
02481                     
02482                     /* the z axis is fixed */
02483                     normalize_v3_v3(totmat[2], cob->matrix[2]);
02484                     
02485                     /* the x axis gets mapped onto a third orthogonal vector */
02486                     cross_v3_v3v3(totmat[1], totmat[2], totmat[0]);
02487                 }
02488                     break;
02489                 case TRACK_Y: /* LOCK Z TRACK Y */
02490                 {
02491                     /* Projection of Vector on the plane */
02492                     project_v3_v3v3(vec2, vec, cob->matrix[2]);
02493                     sub_v3_v3v3(totmat[1], vec, vec2);
02494                     normalize_v3(totmat[1]);
02495                     
02496                     /* the z axis is fixed */
02497                     normalize_v3_v3(totmat[2], cob->matrix[2]);
02498                         
02499                     /* the x axis gets mapped onto a third orthogonal vector */
02500                     cross_v3_v3v3(totmat[0], totmat[1], totmat[2]);
02501                 }
02502                     break;
02503                 case TRACK_nX: /* LOCK Z TRACK -X */
02504                 {
02505                     /* Projection of Vector on the plane */
02506                     project_v3_v3v3(vec2, vec, cob->matrix[2]);
02507                     sub_v3_v3v3(totmat[0], vec, vec2);
02508                     normalize_v3(totmat[0]);
02509                     negate_v3(totmat[0]);
02510                     
02511                     /* the z axis is fixed */
02512                     normalize_v3_v3(totmat[2], cob->matrix[2]);
02513                     
02514                     /* the x axis gets mapped onto a third orthogonal vector */
02515                     cross_v3_v3v3(totmat[1], totmat[2], totmat[0]);
02516                 }
02517                     break;
02518                 case TRACK_nY: /* LOCK Z TRACK -Y */
02519                 {
02520                     /* Projection of Vector on the plane */
02521                     project_v3_v3v3(vec2, vec, cob->matrix[2]);
02522                     sub_v3_v3v3(totmat[1], vec, vec2);
02523                     normalize_v3(totmat[1]);
02524                     negate_v3(totmat[1]);
02525                     
02526                     /* the z axis is fixed */
02527                     normalize_v3_v3(totmat[2], cob->matrix[2]);
02528                         
02529                     /* the x axis gets mapped onto a third orthogonal vector */
02530                     cross_v3_v3v3(totmat[0], totmat[1], totmat[2]);
02531                 }
02532                     break;
02533                 default:
02534                 {
02535                     unit_m3(totmat);
02536                 }
02537                     break;
02538             }
02539         }
02540             break;
02541         default:
02542         {
02543             unit_m3(totmat);
02544         }
02545             break;
02546         }
02547         /* Block to keep matrix heading */
02548         copy_m3_m4(tmpmat, cob->matrix);
02549         normalize_m3(tmpmat);
02550         invert_m3_m3(invmat, tmpmat);
02551         mul_m3_m3m3(tmpmat, totmat, invmat);
02552         totmat[0][0] = tmpmat[0][0];totmat[0][1] = tmpmat[0][1];totmat[0][2] = tmpmat[0][2];
02553         totmat[1][0] = tmpmat[1][0];totmat[1][1] = tmpmat[1][1];totmat[1][2] = tmpmat[1][2];
02554         totmat[2][0] = tmpmat[2][0];totmat[2][1] = tmpmat[2][1];totmat[2][2] = tmpmat[2][2];
02555         
02556         copy_m4_m4(tmat, cob->matrix);
02557         
02558         mdet = determinant_m3(  totmat[0][0],totmat[0][1],totmat[0][2],
02559                         totmat[1][0],totmat[1][1],totmat[1][2],
02560                         totmat[2][0],totmat[2][1],totmat[2][2]);
02561         if (mdet==0) {
02562             unit_m3(totmat);
02563         }
02564         
02565         /* apply out transformaton to the object */
02566         mul_m4_m3m4(cob->matrix, totmat, tmat);
02567     }
02568 }
02569 
02570 static bConstraintTypeInfo CTI_LOCKTRACK = {
02571     CONSTRAINT_TYPE_LOCKTRACK, /* type */
02572     sizeof(bLockTrackConstraint), /* size */
02573     "Locked Track", /* name */
02574     "bLockTrackConstraint", /* struct name */
02575     NULL, /* free data */
02576     NULL, /* relink data */
02577     locktrack_id_looper, /* id looper */
02578     NULL, /* copy data */
02579     locktrack_new_data, /* new data */
02580     locktrack_get_tars, /* get constraint targets */
02581     locktrack_flush_tars, /* flush constraint targets */
02582     default_get_tarmat, /* get target matrix */
02583     locktrack_evaluate /* evaluate */
02584 };
02585 
02586 /* ---------- Limit Distance Constraint ----------- */
02587 
02588 static void distlimit_new_data (void *cdata)
02589 {
02590     bDistLimitConstraint *data= (bDistLimitConstraint *)cdata;
02591     
02592     data->dist= 0.0f;
02593 }
02594 
02595 static void distlimit_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
02596 {
02597     bDistLimitConstraint *data= con->data;
02598     
02599     /* target only */
02600     func(con, (ID**)&data->tar, userdata);
02601 }
02602 
02603 static int distlimit_get_tars (bConstraint *con, ListBase *list)
02604 {
02605     if (con && list) {
02606         bDistLimitConstraint *data= con->data;
02607         bConstraintTarget *ct;
02608         
02609         /* standard target-getting macro for single-target constraints */
02610         SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
02611         
02612         return 1;
02613     }
02614     
02615     return 0;
02616 }
02617 
02618 static void distlimit_flush_tars (bConstraint *con, ListBase *list, short nocopy)
02619 {
02620     if (con && list) {
02621         bDistLimitConstraint *data= con->data;
02622         bConstraintTarget *ct= list->first;
02623         
02624         /* the following macro is used for all standard single-target constraints */
02625         SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
02626     }
02627 }
02628 
02629 static void distlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
02630 {
02631     bDistLimitConstraint *data= con->data;
02632     bConstraintTarget *ct= targets->first;
02633     
02634     /* only evaluate if there is a target */
02635     if (VALID_CONS_TARGET(ct)) {
02636         float dvec[3], dist=0.0f, sfac=1.0f;
02637         short clamp_surf= 0;
02638         
02639         /* calculate our current distance from the target */
02640         dist= len_v3v3(cob->matrix[3], ct->matrix[3]);
02641         
02642         /* set distance (flag is only set when user demands it) */
02643         if (data->dist == 0)
02644             data->dist= dist;
02645         
02646         /* check if we're which way to clamp from, and calculate interpolation factor (if needed) */
02647         if (data->mode == LIMITDIST_OUTSIDE) {
02648             /* if inside, then move to surface */
02649             if (dist <= data->dist) {
02650                 clamp_surf= 1;
02651                 if (dist != 0.0f) sfac= data->dist / dist;
02652             }
02653             /* if soft-distance is enabled, start fading once owner is dist+softdist from the target */
02654             else if (data->flag & LIMITDIST_USESOFT) {
02655                 if (dist <= (data->dist + data->soft)) {
02656                     
02657                 }
02658             }
02659         }
02660         else if (data->mode == LIMITDIST_INSIDE) {
02661             /* if outside, then move to surface */
02662             if (dist >= data->dist) {
02663                 clamp_surf= 1;
02664                 if (dist != 0.0f) sfac= data->dist / dist;
02665             }
02666             /* if soft-distance is enabled, start fading once owner is dist-soft from the target */
02667             else if (data->flag & LIMITDIST_USESOFT) {
02668                 // FIXME: there's a problem with "jumping" when this kicks in
02669                 if (dist >= (data->dist - data->soft)) {
02670                     sfac = (float)( data->soft*(1.0f - expf(-(dist - data->dist)/data->soft)) + data->dist );
02671                     if (dist != 0.0f) sfac /= dist;
02672                     
02673                     clamp_surf= 1;
02674                 }
02675             }
02676         }
02677         else {
02678             if (IS_EQF(dist, data->dist)==0) {
02679                 clamp_surf= 1;
02680                 if (dist != 0.0f) sfac= data->dist / dist;
02681             }
02682         }
02683         
02684         /* clamp to 'surface' (i.e. move owner so that dist == data->dist) */
02685         if (clamp_surf) {
02686             /* simply interpolate along line formed by target -> owner */
02687             interp_v3_v3v3(dvec, ct->matrix[3], cob->matrix[3], sfac);
02688             
02689             /* copy new vector onto owner */
02690             copy_v3_v3(cob->matrix[3], dvec);
02691         }
02692     }
02693 }
02694 
02695 static bConstraintTypeInfo CTI_DISTLIMIT = {
02696     CONSTRAINT_TYPE_DISTLIMIT, /* type */
02697     sizeof(bDistLimitConstraint), /* size */
02698     "Limit Distance", /* name */
02699     "bDistLimitConstraint", /* struct name */
02700     NULL, /* free data */
02701     NULL, /* relink data */
02702     distlimit_id_looper, /* id looper */
02703     NULL, /* copy data */
02704     distlimit_new_data, /* new data */
02705     distlimit_get_tars, /* get constraint targets */
02706     distlimit_flush_tars, /* flush constraint targets */
02707     default_get_tarmat, /* get a target matrix */
02708     distlimit_evaluate /* evaluate */
02709 };
02710 
02711 /* ---------- Stretch To ------------ */
02712 
02713 static void stretchto_new_data (void *cdata)
02714 {
02715     bStretchToConstraint *data= (bStretchToConstraint *)cdata;
02716     
02717     data->volmode = 0;
02718     data->plane = 0;
02719     data->orglength = 0.0; 
02720     data->bulge = 1.0;
02721 }
02722 
02723 static void stretchto_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
02724 {
02725     bStretchToConstraint *data= con->data;
02726     
02727     /* target only */
02728     func(con, (ID**)&data->tar, userdata);
02729 }
02730 
02731 static int stretchto_get_tars (bConstraint *con, ListBase *list)
02732 {
02733     if (con && list) {
02734         bStretchToConstraint *data= con->data;
02735         bConstraintTarget *ct;
02736         
02737         /* standard target-getting macro for single-target constraints */
02738         SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
02739         
02740         return 1;
02741     }
02742     
02743     return 0;
02744 }
02745 
02746 static void stretchto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
02747 {
02748     if (con && list) {
02749         bStretchToConstraint *data= con->data;
02750         bConstraintTarget *ct= list->first;
02751         
02752         /* the following macro is used for all standard single-target constraints */
02753         SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
02754     }
02755 }
02756 
02757 static void stretchto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
02758 {
02759     bStretchToConstraint *data= con->data;
02760     bConstraintTarget *ct= targets->first;
02761     
02762     /* only evaluate if there is a target */
02763     if (VALID_CONS_TARGET(ct)) {
02764         float size[3], scale[3], vec[3], xx[3], zz[3], orth[3];
02765         float totmat[3][3];
02766         float tmat[4][4];
02767         float dist;
02768         
02769         /* store scaling before destroying obmat */
02770         mat4_to_size(size, cob->matrix);
02771         
02772         /* store X orientation before destroying obmat */
02773         normalize_v3_v3(xx, cob->matrix[0]);
02774         
02775         /* store Z orientation before destroying obmat */
02776         normalize_v3_v3(zz, cob->matrix[2]);
02777         
02778         sub_v3_v3v3(vec, cob->matrix[3], ct->matrix[3]);
02779         vec[0] /= size[0];
02780         vec[1] /= size[1];
02781         vec[2] /= size[2];
02782         
02783         dist = normalize_v3(vec);
02784         //dist = len_v3v3( ob->obmat[3], targetmat[3]);
02785         
02786         /* data->orglength==0 occurs on first run, and after 'R' button is clicked */
02787         if (data->orglength == 0)  
02788             data->orglength = dist;
02789         if (data->bulge == 0) 
02790             data->bulge = 1.0;
02791         
02792         scale[1] = dist/data->orglength;
02793         switch (data->volmode) {
02794         /* volume preserving scaling */
02795         case VOLUME_XZ :
02796             scale[0] = 1.0f - (float)sqrt(data->bulge) + (float)sqrt(data->bulge*(data->orglength/dist));
02797             scale[2] = scale[0];
02798             break;
02799         case VOLUME_X:
02800             scale[0] = 1.0f + data->bulge * (data->orglength /dist - 1);
02801             scale[2] = 1.0;
02802             break;
02803         case VOLUME_Z:
02804             scale[0] = 1.0;
02805             scale[2] = 1.0f + data->bulge * (data->orglength /dist - 1);
02806             break;
02807             /* don't care for volume */
02808         case NO_VOLUME:
02809             scale[0] = 1.0;
02810             scale[2] = 1.0;
02811             break;
02812         default: /* should not happen, but in case*/
02813             return;    
02814         } /* switch (data->volmode) */
02815 
02816         /* Clear the object's rotation and scale */
02817         cob->matrix[0][0]=size[0]*scale[0];
02818         cob->matrix[0][1]=0;
02819         cob->matrix[0][2]=0;
02820         cob->matrix[1][0]=0;
02821         cob->matrix[1][1]=size[1]*scale[1];
02822         cob->matrix[1][2]=0;
02823         cob->matrix[2][0]=0;
02824         cob->matrix[2][1]=0;
02825         cob->matrix[2][2]=size[2]*scale[2];
02826         
02827         sub_v3_v3v3(vec, cob->matrix[3], ct->matrix[3]);
02828         normalize_v3(vec);
02829         
02830         /* new Y aligns  object target connection*/
02831         negate_v3_v3(totmat[1], vec);
02832         switch (data->plane) {
02833         case PLANE_X:
02834             /* build new Z vector */
02835             /* othogonal to "new Y" "old X! plane */
02836             cross_v3_v3v3(orth, vec, xx);
02837             normalize_v3(orth);
02838             
02839             /* new Z*/
02840             copy_v3_v3(totmat[2], orth);
02841             
02842             /* we decided to keep X plane*/
02843             cross_v3_v3v3(xx, orth, vec);
02844             normalize_v3_v3(totmat[0], xx);
02845             break;
02846         case PLANE_Z:
02847             /* build new X vector */
02848             /* othogonal to "new Y" "old Z! plane */
02849             cross_v3_v3v3(orth, vec, zz);
02850             normalize_v3(orth);
02851             
02852             /* new X */
02853             negate_v3_v3(totmat[0], orth);
02854             
02855             /* we decided to keep Z */
02856             cross_v3_v3v3(zz, orth, vec);
02857             normalize_v3_v3(totmat[2], zz);
02858             break;
02859         } /* switch (data->plane) */
02860         
02861         copy_m4_m4(tmat, cob->matrix);
02862         mul_m4_m3m4(cob->matrix, totmat, tmat);
02863     }
02864 }
02865 
02866 static bConstraintTypeInfo CTI_STRETCHTO = {
02867     CONSTRAINT_TYPE_STRETCHTO, /* type */
02868     sizeof(bStretchToConstraint), /* size */
02869     "Stretch To", /* name */
02870     "bStretchToConstraint", /* struct name */
02871     NULL, /* free data */
02872     NULL, /* relink data */
02873     stretchto_id_looper, /* id looper */
02874     NULL, /* copy data */
02875     stretchto_new_data, /* new data */
02876     stretchto_get_tars, /* get constraint targets */
02877     stretchto_flush_tars, /* flush constraint targets */
02878     default_get_tarmat, /* get target matrix */
02879     stretchto_evaluate /* evaluate */
02880 };
02881 
02882 /* ---------- Floor ------------ */
02883 
02884 static void minmax_new_data (void *cdata)
02885 {
02886     bMinMaxConstraint *data= (bMinMaxConstraint *)cdata;
02887     
02888     data->minmaxflag = TRACK_Z;
02889     data->offset = 0.0f;
02890     data->cache[0] = data->cache[1] = data->cache[2] = 0.0f;
02891     data->flag = 0;
02892 }
02893 
02894 static void minmax_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
02895 {
02896     bMinMaxConstraint *data= con->data;
02897     
02898     /* target only */
02899     func(con, (ID**)&data->tar, userdata);
02900 }
02901 
02902 static int minmax_get_tars (bConstraint *con, ListBase *list)
02903 {
02904     if (con && list) {
02905         bMinMaxConstraint *data= con->data;
02906         bConstraintTarget *ct;
02907         
02908         /* standard target-getting macro for single-target constraints */
02909         SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
02910         
02911         return 1;
02912     }
02913     
02914     return 0;
02915 }
02916 
02917 static void minmax_flush_tars (bConstraint *con, ListBase *list, short nocopy)
02918 {
02919     if (con && list) {
02920         bMinMaxConstraint *data= con->data;
02921         bConstraintTarget *ct= list->first;
02922         
02923         /* the following macro is used for all standard single-target constraints */
02924         SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
02925     }
02926 }
02927 
02928 static void minmax_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
02929 {
02930     bMinMaxConstraint *data= con->data;
02931     bConstraintTarget *ct= targets->first;
02932     
02933     /* only evaluate if there is a target */
02934     if (VALID_CONS_TARGET(ct)) {
02935         float obmat[4][4], imat[4][4], tarmat[4][4], tmat[4][4];
02936         float val1, val2;
02937         int index;
02938         
02939         copy_m4_m4(obmat, cob->matrix);
02940         copy_m4_m4(tarmat, ct->matrix);
02941         
02942         if (data->flag & MINMAX_USEROT) {
02943             /* take rotation of target into account by doing the transaction in target's localspace */
02944             invert_m4_m4(imat, tarmat);
02945             mult_m4_m4m4(tmat, imat, obmat);
02946             copy_m4_m4(obmat, tmat);
02947             unit_m4(tarmat);
02948         }
02949         
02950         switch (data->minmaxflag) {
02951         case TRACK_Z:
02952             val1 = tarmat[3][2];
02953             val2 = obmat[3][2]-data->offset;
02954             index = 2;
02955             break;
02956         case TRACK_Y:
02957             val1 = tarmat[3][1];
02958             val2 = obmat[3][1]-data->offset;
02959             index = 1;
02960             break;
02961         case TRACK_X:
02962             val1 = tarmat[3][0];
02963             val2 = obmat[3][0]-data->offset;
02964             index = 0;
02965             break;
02966         case TRACK_nZ:
02967             val2 = tarmat[3][2];
02968             val1 = obmat[3][2]-data->offset;
02969             index = 2;
02970             break;
02971         case TRACK_nY:
02972             val2 = tarmat[3][1];
02973             val1 = obmat[3][1]-data->offset;
02974             index = 1;
02975             break;
02976         case TRACK_nX:
02977             val2 = tarmat[3][0];
02978             val1 = obmat[3][0]-data->offset;
02979             index = 0;
02980             break;
02981         default:
02982             return;
02983         }
02984         
02985         if (val1 > val2) {
02986             obmat[3][index] = tarmat[3][index] + data->offset;
02987             if (data->flag & MINMAX_STICKY) {
02988                 if (data->flag & MINMAX_STUCK) {
02989                     copy_v3_v3(obmat[3], data->cache);
02990                 } 
02991                 else {
02992                     copy_v3_v3(data->cache, obmat[3]);
02993                     data->flag |= MINMAX_STUCK;
02994                 }
02995             }
02996             if (data->flag & MINMAX_USEROT) {
02997                 /* get out of localspace */
02998                 mult_m4_m4m4(tmat, ct->matrix, obmat);
02999                 copy_m4_m4(cob->matrix, tmat);
03000             } 
03001             else {          
03002                 copy_v3_v3(cob->matrix[3], obmat[3]);
03003             }
03004         } 
03005         else {
03006             data->flag &= ~MINMAX_STUCK;
03007         }
03008     }
03009 }
03010 
03011 static bConstraintTypeInfo CTI_MINMAX = {
03012     CONSTRAINT_TYPE_MINMAX, /* type */
03013     sizeof(bMinMaxConstraint), /* size */
03014     "Floor", /* name */
03015     "bMinMaxConstraint", /* struct name */
03016     NULL, /* free data */
03017     NULL, /* relink data */
03018     minmax_id_looper, /* id looper */
03019     NULL, /* copy data */
03020     minmax_new_data, /* new data */
03021     minmax_get_tars, /* get constraint targets */
03022     minmax_flush_tars, /* flush constraint targets */
03023     default_get_tarmat, /* get target matrix */
03024     minmax_evaluate /* evaluate */
03025 };
03026 
03027 /* ------- RigidBody Joint ---------- */
03028 
03029 static void rbj_new_data (void *cdata)
03030 {
03031     bRigidBodyJointConstraint *data= (bRigidBodyJointConstraint *)cdata;
03032     
03033     // removed code which set target of this constraint  
03034     data->type=1;
03035 }
03036 
03037 static void rbj_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
03038 {
03039     bRigidBodyJointConstraint *data= con->data;
03040     
03041     /* target only */
03042     func(con, (ID**)&data->tar, userdata);
03043     func(con, (ID**)&data->child, userdata);
03044 }
03045 
03046 static int rbj_get_tars (bConstraint *con, ListBase *list)
03047 {
03048     if (con && list) {
03049         bRigidBodyJointConstraint *data= con->data;
03050         bConstraintTarget *ct;
03051         
03052         /* standard target-getting macro for single-target constraints without subtargets */
03053         SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
03054         
03055         return 1;
03056     }
03057     
03058     return 0;
03059 }
03060 
03061 static void rbj_flush_tars (bConstraint *con, ListBase *list, short nocopy)
03062 {
03063     if (con && list) {
03064         bRigidBodyJointConstraint *data= con->data;
03065         bConstraintTarget *ct= list->first;
03066         
03067         /* the following macro is used for all standard single-target constraints */
03068         SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy)
03069     }
03070 }
03071 
03072 static bConstraintTypeInfo CTI_RIGIDBODYJOINT = {
03073     CONSTRAINT_TYPE_RIGIDBODYJOINT, /* type */
03074     sizeof(bRigidBodyJointConstraint), /* size */
03075     "Rigid Body Joint", /* name */
03076     "bRigidBodyJointConstraint", /* struct name */
03077     NULL, /* free data */
03078     NULL, /* relink data */
03079     rbj_id_looper, /* id looper */
03080     NULL, /* copy data */
03081     rbj_new_data, /* new data */
03082     rbj_get_tars, /* get constraint targets */
03083     rbj_flush_tars, /* flush constraint targets */
03084     default_get_tarmat, /* get target matrix */
03085     NULL /* evaluate - this is not solved here... is just an interface for game-engine */
03086 };
03087 
03088 /* -------- Clamp To ---------- */
03089 
03090 static void clampto_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
03091 {
03092     bClampToConstraint *data= con->data;
03093     
03094     /* target only */
03095     func(con, (ID**)&data->tar, userdata);
03096 }
03097 
03098 static int clampto_get_tars (bConstraint *con, ListBase *list)
03099 {
03100     if (con && list) {
03101         bClampToConstraint *data= con->data;
03102         bConstraintTarget *ct;
03103         
03104         /* standard target-getting macro for single-target constraints without subtargets */
03105         SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
03106         
03107         return 1;
03108     }
03109     
03110     return 0;
03111 }
03112 
03113 static void clampto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
03114 {
03115     if (con && list) {
03116         bClampToConstraint *data= con->data;
03117         bConstraintTarget *ct= list->first;
03118         
03119         /* the following macro is used for all standard single-target constraints */
03120         SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy)
03121     }
03122 }
03123 
03124 static void clampto_get_tarmat (bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
03125 {
03126     if (VALID_CONS_TARGET(ct)) {
03127         Curve *cu= ct->tar->data;
03128         
03129         /* note: when creating constraints that follow path, the curve gets the CU_PATH set now,
03130          *      currently for paths to work it needs to go through the bevlist/displist system (ton) 
03131          */
03132         
03133         /* only happens on reload file, but violates depsgraph still... fix! */
03134         if (cu->path==NULL || cu->path->data==NULL)
03135             makeDispListCurveTypes(cob->scene, ct->tar, 0);
03136     }
03137     
03138     /* technically, this isn't really needed for evaluation, but we don't know what else
03139      * might end up calling this...
03140      */
03141     if (ct)
03142         unit_m4(ct->matrix);
03143 }
03144 
03145 static void clampto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
03146 {
03147     bClampToConstraint *data= con->data;
03148     bConstraintTarget *ct= targets->first;
03149     
03150     /* only evaluate if there is a target and it is a curve */
03151     if (VALID_CONS_TARGET(ct) && (ct->tar->type == OB_CURVE)) {
03152         Curve *cu= data->tar->data;
03153         float obmat[4][4], ownLoc[3];
03154         float curveMin[3], curveMax[3];
03155         float targetMatrix[4][4]= MAT4_UNITY;
03156         
03157         copy_m4_m4(obmat, cob->matrix);
03158         copy_v3_v3(ownLoc, obmat[3]);
03159         
03160         INIT_MINMAX(curveMin, curveMax)
03161         minmax_object(ct->tar, curveMin, curveMax);
03162         
03163         /* get targetmatrix */
03164         if (cu->path && cu->path->data) {
03165             float vec[4], dir[3], totmat[4][4];
03166             float curvetime;
03167             short clamp_axis;
03168             
03169             /* find best position on curve */
03170             /* 1. determine which axis to sample on? */
03171             if (data->flag == CLAMPTO_AUTO) {
03172                 float size[3];
03173                 sub_v3_v3v3(size, curveMax, curveMin);
03174                 
03175                 /* find axis along which the bounding box has the greatest
03176                  * extent. Otherwise, default to the x-axis, as that is quite
03177                  * frequently used.
03178                  */
03179                 if ((size[2]>size[0]) && (size[2]>size[1]))
03180                     clamp_axis= CLAMPTO_Z - 1;
03181                 else if ((size[1]>size[0]) && (size[1]>size[2]))
03182                     clamp_axis= CLAMPTO_Y - 1;
03183                 else
03184                     clamp_axis = CLAMPTO_X - 1;
03185             }
03186             else 
03187                 clamp_axis= data->flag - 1;
03188                 
03189             /* 2. determine position relative to curve on a 0-1 scale based on bounding box */
03190             if (data->flag2 & CLAMPTO_CYCLIC) {
03191                 /* cyclic, so offset within relative bounding box is used */
03192                 float len= (curveMax[clamp_axis] - curveMin[clamp_axis]);
03193                 float offset;
03194                 
03195                 /* check to make sure len is not so close to zero that it'll cause errors */
03196                 if (IS_EQ(len, 0) == 0) {
03197                     /* find bounding-box range where target is located */
03198                     if (ownLoc[clamp_axis] < curveMin[clamp_axis]) {
03199                         /* bounding-box range is before */
03200                         offset= curveMin[clamp_axis];
03201                         
03202                         while (ownLoc[clamp_axis] < offset)
03203                             offset -= len;
03204                         
03205                         /* now, we calculate as per normal, except using offset instead of curveMin[clamp_axis] */
03206                         curvetime = (ownLoc[clamp_axis] - offset) / (len);
03207                     }
03208                     else if (ownLoc[clamp_axis] > curveMax[clamp_axis]) {
03209                         /* bounding-box range is after */
03210                         offset= curveMax[clamp_axis];
03211                         
03212                         while (ownLoc[clamp_axis] > offset) {
03213                             if ((offset + len) > ownLoc[clamp_axis])
03214                                 break;
03215                             else
03216                                 offset += len;
03217                         }
03218                         
03219                         /* now, we calculate as per normal, except using offset instead of curveMax[clamp_axis] */
03220                         curvetime = (ownLoc[clamp_axis] - offset) / (len);
03221                     }
03222                     else {
03223                         /* as the location falls within bounds, just calculate */
03224                         curvetime = (ownLoc[clamp_axis] - curveMin[clamp_axis]) / (len);
03225                     }
03226                 }
03227                 else {
03228                     /* as length is close to zero, curvetime by default should be 0 (i.e. the start) */
03229                     curvetime= 0.0f;
03230                 }
03231             }
03232             else {
03233                 /* no cyclic, so position is clamped to within the bounding box */
03234                 if (ownLoc[clamp_axis] <= curveMin[clamp_axis])
03235                     curvetime = 0.0f;
03236                 else if (ownLoc[clamp_axis] >= curveMax[clamp_axis])
03237                     curvetime = 1.0f;
03238                 else if ( IS_EQ((curveMax[clamp_axis] - curveMin[clamp_axis]), 0) == 0 )
03239                     curvetime = (ownLoc[clamp_axis] - curveMin[clamp_axis]) / (curveMax[clamp_axis] - curveMin[clamp_axis]);
03240                 else 
03241                     curvetime = 0.0f;
03242             }
03243             
03244             /* 3. position on curve */
03245             if (where_on_path(ct->tar, curvetime, vec, dir, NULL, NULL, NULL) ) {
03246                 unit_m4(totmat);
03247                 copy_v3_v3(totmat[3], vec);
03248                 
03249                 mul_serie_m4(targetMatrix, ct->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL);
03250             }
03251         }
03252         
03253         /* obtain final object position */
03254         copy_v3_v3(cob->matrix[3], targetMatrix[3]);
03255     }
03256 }
03257 
03258 static bConstraintTypeInfo CTI_CLAMPTO = {
03259     CONSTRAINT_TYPE_CLAMPTO, /* type */
03260     sizeof(bClampToConstraint), /* size */
03261     "Clamp To", /* name */
03262     "bClampToConstraint", /* struct name */
03263     NULL, /* free data */
03264     NULL, /* relink data */
03265     clampto_id_looper, /* id looper */
03266     NULL, /* copy data */
03267     NULL, /* new data */
03268     clampto_get_tars, /* get constraint targets */
03269     clampto_flush_tars, /* flush constraint targets */
03270     clampto_get_tarmat, /* get target matrix */
03271     clampto_evaluate /* evaluate */
03272 };
03273 
03274 /* ---------- Transform Constraint ----------- */
03275 
03276 static void transform_new_data (void *cdata)
03277 {
03278     bTransformConstraint *data= (bTransformConstraint *)cdata;
03279     
03280     data->map[0]= 0;
03281     data->map[1]= 1;
03282     data->map[2]= 2;
03283 }
03284 
03285 static void transform_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
03286 {
03287     bTransformConstraint *data= con->data;
03288     
03289     /* target only */
03290     func(con, (ID**)&data->tar, userdata);
03291 }
03292 
03293 static int transform_get_tars (bConstraint *con, ListBase *list)
03294 {
03295     if (con && list) {
03296         bTransformConstraint *data= con->data;
03297         bConstraintTarget *ct;
03298         
03299         /* standard target-getting macro for single-target constraints */
03300         SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
03301         
03302         return 1;
03303     }
03304     
03305     return 0;
03306 }
03307 
03308 static void transform_flush_tars (bConstraint *con, ListBase *list, short nocopy)
03309 {
03310     if (con && list) {
03311         bTransformConstraint *data= con->data;
03312         bConstraintTarget *ct= list->first;
03313         
03314         /* the following macro is used for all standard single-target constraints */
03315         SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
03316     }
03317 }
03318 
03319 static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
03320 {
03321     bTransformConstraint *data= con->data;
03322     bConstraintTarget *ct= targets->first;
03323     
03324     /* only evaluate if there is a target */
03325     if (VALID_CONS_TARGET(ct)) {
03326         float loc[3], eul[3], size[3];
03327         float dvec[3], sval[3];
03328         int i;
03329         
03330         /* obtain target effect */
03331         switch (data->from) {
03332             case 2: /* scale */
03333                 mat4_to_size( dvec,ct->matrix);
03334                 break;
03335             case 1: /* rotation (convert to degrees first) */
03336                 mat4_to_eulO(dvec, cob->rotOrder, ct->matrix);
03337                 mul_v3_fl(dvec, RAD2DEGF(1.0f)); /* rad -> deg */
03338                 break;
03339             default: /* location */
03340                 copy_v3_v3(dvec, ct->matrix[3]);
03341                 break;
03342         }
03343         
03344         /* extract components of owner's matrix */
03345         copy_v3_v3(loc, cob->matrix[3]);
03346         mat4_to_eulO(eul, cob->rotOrder, cob->matrix);
03347         mat4_to_size(size, cob->matrix);    
03348         
03349         /* determine where in range current transforms lie */
03350         if (data->expo) {
03351             for (i=0; i<3; i++) {
03352                 if (data->from_max[i] - data->from_min[i])
03353                     sval[i]= (dvec[i] - data->from_min[i]) / (data->from_max[i] - data->from_min[i]);
03354                 else
03355                     sval[i]= 0.0f;
03356             }
03357         }
03358         else {
03359             /* clamp transforms out of range */
03360             for (i=0; i<3; i++) {
03361                 CLAMP(dvec[i], data->from_min[i], data->from_max[i]);
03362                 if (data->from_max[i] - data->from_min[i])
03363                     sval[i]= (dvec[i] - data->from_min[i]) / (data->from_max[i] - data->from_min[i]);
03364                 else
03365                     sval[i]= 0.0f;
03366             }
03367         }
03368         
03369         
03370         /* apply transforms */
03371         switch (data->to) {
03372             case 2: /* scaling */
03373                 for (i=0; i<3; i++)
03374                     size[i]= data->to_min[i] + (sval[(int)data->map[i]] * (data->to_max[i] - data->to_min[i])); 
03375                 break;
03376             case 1: /* rotation */
03377                 for (i=0; i<3; i++) {
03378                     float tmin, tmax;
03379                     
03380                     tmin= data->to_min[i];
03381                     tmax= data->to_max[i];
03382                     
03383                     /* all values here should be in degrees */
03384                     eul[i]= tmin + (sval[(int)data->map[i]] * (tmax - tmin)); 
03385                     
03386                     /* now convert final value back to radians */
03387                     eul[i] = DEG2RADF(eul[i]);
03388                 }
03389                 break;
03390             default: /* location */
03391                 /* get new location */
03392                 for (i=0; i<3; i++)
03393                     loc[i]= (data->to_min[i] + (sval[(int)data->map[i]] * (data->to_max[i] - data->to_min[i])));
03394                 
03395                 /* add original location back on (so that it can still be moved) */
03396                 add_v3_v3v3(loc, cob->matrix[3], loc);
03397                 break;
03398         }
03399         
03400         /* apply to matrix */
03401         loc_eulO_size_to_mat4(cob->matrix, loc, eul, size, cob->rotOrder);
03402     }
03403 }
03404 
03405 static bConstraintTypeInfo CTI_TRANSFORM = {
03406     CONSTRAINT_TYPE_TRANSFORM, /* type */
03407     sizeof(bTransformConstraint), /* size */
03408     "Transform", /* name */
03409     "bTransformConstraint", /* struct name */
03410     NULL, /* free data */
03411     NULL, /* relink data */
03412     transform_id_looper, /* id looper */
03413     NULL, /* copy data */
03414     transform_new_data, /* new data */
03415     transform_get_tars, /* get constraint targets */
03416     transform_flush_tars, /* flush constraint targets */
03417     default_get_tarmat, /* get a target matrix */
03418     transform_evaluate /* evaluate */
03419 };
03420 
03421 /* ---------- Shrinkwrap Constraint ----------- */
03422 
03423 static void shrinkwrap_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
03424 {
03425     bShrinkwrapConstraint *data= con->data;
03426     
03427     /* target only */
03428     func(con, (ID**)&data->target, userdata);
03429 }
03430 
03431 static int shrinkwrap_get_tars (bConstraint *con, ListBase *list)
03432 {
03433     if (con && list) {
03434         bShrinkwrapConstraint *data = con->data;
03435         bConstraintTarget *ct;
03436         
03437         SINGLETARGETNS_GET_TARS(con, data->target, ct, list)
03438         
03439         return 1;
03440     }
03441     
03442     return 0;
03443 }
03444 
03445 
03446 static void shrinkwrap_flush_tars (bConstraint *con, ListBase *list, short nocopy)
03447 {
03448     if (con && list) {
03449         bShrinkwrapConstraint *data = con->data;
03450         bConstraintTarget *ct= list->first;
03451         
03452         SINGLETARGETNS_FLUSH_TARS(con, data->target, ct, list, nocopy)
03453     }
03454 }
03455 
03456 
03457 static void shrinkwrap_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
03458 {
03459     bShrinkwrapConstraint *scon = (bShrinkwrapConstraint *) con->data;
03460     
03461     if( VALID_CONS_TARGET(ct) && (ct->tar->type == OB_MESH) )
03462     {
03463         int fail = FALSE;
03464         float co[3] = {0.0f, 0.0f, 0.0f};
03465         float no[3] = {0.0f, 0.0f, 0.0f};
03466         float dist;
03467         
03468         SpaceTransform transform;
03469         DerivedMesh *target = object_get_derived_final(ct->tar);
03470         BVHTreeRayHit hit;
03471         BVHTreeNearest nearest;
03472         
03473         BVHTreeFromMesh treeData= {NULL};
03474         
03475         nearest.index = -1;
03476         nearest.dist = FLT_MAX;
03477         
03478         hit.index = -1;
03479         hit.dist = 100000.0f;  //TODO should use FLT_MAX.. but normal projection doenst yet supports it
03480         
03481         unit_m4(ct->matrix);
03482         
03483         if(target != NULL)
03484         {
03485             space_transform_from_matrixs(&transform, cob->matrix, ct->tar->obmat);
03486             
03487             switch(scon->shrinkType)
03488             {
03489                 case MOD_SHRINKWRAP_NEAREST_SURFACE:
03490                 case MOD_SHRINKWRAP_NEAREST_VERTEX:
03491                     
03492                     if(scon->shrinkType == MOD_SHRINKWRAP_NEAREST_VERTEX)
03493                         bvhtree_from_mesh_verts(&treeData, target, 0.0, 2, 6);
03494                     else
03495                         bvhtree_from_mesh_faces(&treeData, target, 0.0, 2, 6);
03496                     
03497                     if(treeData.tree == NULL)
03498                     {
03499                         fail = TRUE;
03500                         break;
03501                     }
03502                     
03503                     space_transform_apply(&transform, co);
03504                     
03505                     BLI_bvhtree_find_nearest(treeData.tree, co, &nearest, treeData.nearest_callback, &treeData);
03506                     
03507                     dist = len_v3v3(co, nearest.co);
03508                     if(dist != 0.0f) {
03509                         interp_v3_v3v3(co, co, nearest.co, (dist - scon->dist)/dist);   /* linear interpolation */
03510                     }
03511                     space_transform_invert(&transform, co);
03512                 break;
03513                 
03514                 case MOD_SHRINKWRAP_PROJECT:
03515                     if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS) no[0] = 1.0f;
03516                     if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS) no[1] = 1.0f;
03517                     if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS) no[2] = 1.0f;
03518                     
03519                     if(INPR(no,no) < FLT_EPSILON)
03520                     {
03521                         fail = TRUE;
03522                         break;
03523                     }
03524                     
03525                     normalize_v3(no);
03526                     
03527                     
03528                     bvhtree_from_mesh_faces(&treeData, target, scon->dist, 4, 6);
03529                     if(treeData.tree == NULL)
03530                     {
03531                         fail = TRUE;
03532                         break;
03533                     }
03534                     
03535                     if(normal_projection_project_vertex(0, co, no, &transform, treeData.tree, &hit, treeData.raycast_callback, &treeData) == FALSE)
03536                     {
03537                         fail = TRUE;
03538                         break;
03539                     }
03540                     copy_v3_v3(co, hit.co);
03541                 break;
03542             }
03543             
03544             free_bvhtree_from_mesh(&treeData);
03545             
03546             target->release(target);
03547             
03548             if(fail == TRUE)
03549             {
03550                 /* Don't move the point */
03551                 co[0] = co[1] = co[2] = 0.0f;
03552             }
03553             
03554             /* co is in local object coordinates, change it to global and update target position */
03555             mul_m4_v3(cob->matrix, co);
03556             copy_v3_v3(ct->matrix[3], co);
03557         }
03558     }
03559 }
03560 
03561 static void shrinkwrap_evaluate (bConstraint *UNUSED(con), bConstraintOb *cob, ListBase *targets)
03562 {
03563     bConstraintTarget *ct= targets->first;
03564     
03565     /* only evaluate if there is a target */
03566     if (VALID_CONS_TARGET(ct))
03567     {
03568         copy_v3_v3(cob->matrix[3], ct->matrix[3]);
03569     }
03570 }
03571 
03572 static bConstraintTypeInfo CTI_SHRINKWRAP = {
03573     CONSTRAINT_TYPE_SHRINKWRAP, /* type */
03574     sizeof(bShrinkwrapConstraint), /* size */
03575     "Shrinkwrap", /* name */
03576     "bShrinkwrapConstraint", /* struct name */
03577     NULL, /* free data */
03578     NULL, /* relink data */
03579     shrinkwrap_id_looper, /* id looper */
03580     NULL, /* copy data */
03581     NULL, /* new data */
03582     shrinkwrap_get_tars, /* get constraint targets */
03583     shrinkwrap_flush_tars, /* flush constraint targets */
03584     shrinkwrap_get_tarmat, /* get a target matrix */
03585     shrinkwrap_evaluate /* evaluate */
03586 };
03587 
03588 /* --------- Damped Track ---------- */
03589 
03590 static void damptrack_new_data (void *cdata)
03591 {
03592     bDampTrackConstraint *data= (bDampTrackConstraint *)cdata;
03593     
03594     data->trackflag = TRACK_Y;
03595 }   
03596 
03597 static void damptrack_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
03598 {
03599     bDampTrackConstraint *data= con->data;
03600     
03601     /* target only */
03602     func(con, (ID**)&data->tar, userdata);
03603 }
03604 
03605 static int damptrack_get_tars (bConstraint *con, ListBase *list)
03606 {
03607     if (con && list) {
03608         bDampTrackConstraint *data= con->data;
03609         bConstraintTarget *ct;
03610         
03611         /* the following macro is used for all standard single-target constraints */
03612         SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
03613         
03614         return 1;
03615     }
03616     
03617     return 0;
03618 }
03619 
03620 static void damptrack_flush_tars (bConstraint *con, ListBase *list, short nocopy)
03621 {
03622     if (con && list) {
03623         bDampTrackConstraint *data= con->data;
03624         bConstraintTarget *ct= list->first;
03625         
03626         /* the following macro is used for all standard single-target constraints */
03627         SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
03628     }
03629 }
03630 
03631 /* array of direction vectors for the tracking flags */
03632 static const float track_dir_vecs[6][3] = {
03633     {+1,0,0}, {0,+1,0}, {0,0,+1},       /* TRACK_X,  TRACK_Y,  TRACK_Z */
03634     {-1,0,0}, {0,-1,0}, {0,0,-1}        /* TRACK_NX, TRACK_NY, TRACK_NZ */
03635 };
03636 
03637 static void damptrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
03638 {
03639     bDampTrackConstraint *data= con->data;
03640     bConstraintTarget *ct= targets->first;
03641     
03642     if (VALID_CONS_TARGET(ct)) {
03643         float obvec[3], tarvec[3], obloc[3];
03644         float raxis[3], rangle;
03645         float rmat[3][3], tmat[4][4];
03646         
03647         /* find the (unit) direction that the axis we're interested in currently points 
03648          *  - mul_mat3_m4_v3() only takes the 3x3 (rotation+scaling) components of the 4x4 matrix 
03649          *  - the normalisation step at the end should take care of any unwanted scaling
03650          *    left over in the 3x3 matrix we used
03651          */
03652         copy_v3_v3(obvec, track_dir_vecs[data->trackflag]);
03653         mul_mat3_m4_v3(cob->matrix, obvec);
03654         
03655         if (normalize_v3(obvec) == 0.0f) {
03656             /* exceptional case - just use the track vector as appropriate */
03657             copy_v3_v3(obvec, track_dir_vecs[data->trackflag]);
03658         }
03659         
03660         /* find the (unit) direction vector going from the owner to the target */
03661         copy_v3_v3(obloc, cob->matrix[3]);
03662         sub_v3_v3v3(tarvec, ct->matrix[3], obloc);
03663         
03664         if (normalize_v3(tarvec) == 0.0f) {
03665             /* the target is sitting on the owner, so just make them use the same direction vectors */
03666             // FIXME: or would it be better to use the pure direction vector?
03667             copy_v3_v3(tarvec, obvec);
03668             //copy_v3_v3(tarvec, track_dir_vecs[data->trackflag]);
03669         }
03670         
03671         /* determine the axis-angle rotation, which represents the smallest possible rotation
03672          * between the two rotation vectors (i.e. the 'damping' referred to in the name)
03673          *  - we take this to be the rotation around the normal axis/vector to the plane defined
03674          *    by the current and destination vectors, which will 'map' the current axis to the 
03675          *    destination vector
03676          *  - the min/max wrappers around (obvec . tarvec) result (stored temporarily in rangle)
03677          *    are used to ensure that the smallest angle is chosen
03678          */
03679         cross_v3_v3v3(raxis, obvec, tarvec);
03680         
03681         rangle= dot_v3v3(obvec, tarvec);
03682         rangle= acos( MAX2(-1.0f, MIN2(1.0f, rangle)) );
03683         
03684         /* construct rotation matrix from the axis-angle rotation found above 
03685          *  - this call takes care to make sure that the axis provided is a unit vector first
03686          */
03687         axis_angle_to_mat3(rmat, raxis, rangle);
03688         
03689         /* rotate the owner in the way defined by this rotation matrix, then reapply the location since
03690          * we may have destroyed that in the process of multiplying the matrix
03691          */
03692         unit_m4(tmat);
03693         mul_m4_m3m4(tmat, rmat, cob->matrix); // m1, m3, m2
03694         
03695         copy_m4_m4(cob->matrix, tmat);
03696         copy_v3_v3(cob->matrix[3], obloc);
03697     }
03698 }
03699 
03700 static bConstraintTypeInfo CTI_DAMPTRACK = {
03701     CONSTRAINT_TYPE_DAMPTRACK, /* type */
03702     sizeof(bDampTrackConstraint), /* size */
03703     "Damped Track", /* name */
03704     "bDampTrackConstraint", /* struct name */
03705     NULL, /* free data */
03706     NULL, /* relink data */
03707     damptrack_id_looper, /* id looper */
03708     NULL, /* copy data */
03709     damptrack_new_data, /* new data */
03710     damptrack_get_tars, /* get constraint targets */
03711     damptrack_flush_tars, /* flush constraint targets */
03712     default_get_tarmat, /* get target matrix */
03713     damptrack_evaluate /* evaluate */
03714 };
03715 
03716 /* ----------- Spline IK ------------ */
03717 
03718 static void splineik_free (bConstraint *con)
03719 {
03720     bSplineIKConstraint *data= con->data;
03721     
03722     /* binding array */
03723     if (data->points)
03724         MEM_freeN(data->points);
03725 }   
03726 
03727 static void splineik_copy (bConstraint *con, bConstraint *srccon)
03728 {
03729     bSplineIKConstraint *src= srccon->data;
03730     bSplineIKConstraint *dst= con->data;
03731     
03732     /* copy the binding array */
03733     dst->points= MEM_dupallocN(src->points);
03734 }
03735 
03736 static void splineik_new_data (void *cdata)
03737 {
03738     bSplineIKConstraint *data= (bSplineIKConstraint *)cdata;
03739 
03740     data->chainlen= 1;
03741 }
03742 
03743 static void splineik_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
03744 {
03745     bSplineIKConstraint *data= con->data;
03746     
03747     /* target only */
03748     func(con, (ID**)&data->tar, userdata);
03749 }
03750 
03751 static int splineik_get_tars (bConstraint *con, ListBase *list)
03752 {
03753     if (con && list) {
03754         bSplineIKConstraint *data= con->data;
03755         bConstraintTarget *ct;
03756         
03757         /* standard target-getting macro for single-target constraints without subtargets */
03758         SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
03759         
03760         return 1;
03761     }
03762     
03763     return 0;
03764 }
03765 
03766 static void splineik_flush_tars (bConstraint *con, ListBase *list, short nocopy)
03767 {
03768     if (con && list) {
03769         bSplineIKConstraint *data= con->data;
03770         bConstraintTarget *ct= list->first;
03771         
03772         /* the following macro is used for all standard single-target constraints */
03773         SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy)
03774     }
03775 }
03776 
03777 static void splineik_get_tarmat (bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
03778 {
03779     if (VALID_CONS_TARGET(ct)) {
03780         Curve *cu= ct->tar->data;
03781         
03782         /* note: when creating constraints that follow path, the curve gets the CU_PATH set now,
03783          *      currently for paths to work it needs to go through the bevlist/displist system (ton) 
03784          */
03785         
03786         /* only happens on reload file, but violates depsgraph still... fix! */
03787         if (cu->path==NULL || cu->path->data==NULL)
03788             makeDispListCurveTypes(cob->scene, ct->tar, 0);
03789     }
03790     
03791     /* technically, this isn't really needed for evaluation, but we don't know what else
03792      * might end up calling this...
03793      */
03794     if (ct)
03795         unit_m4(ct->matrix);
03796 }
03797 
03798 static bConstraintTypeInfo CTI_SPLINEIK = {
03799     CONSTRAINT_TYPE_SPLINEIK, /* type */
03800     sizeof(bSplineIKConstraint), /* size */
03801     "Spline IK", /* name */
03802     "bSplineIKConstraint", /* struct name */
03803     splineik_free, /* free data */
03804     NULL, /* relink data */
03805     splineik_id_looper, /* id looper */
03806     splineik_copy, /* copy data */
03807     splineik_new_data, /* new data */
03808     splineik_get_tars, /* get constraint targets */
03809     splineik_flush_tars, /* flush constraint targets */
03810     splineik_get_tarmat, /* get target matrix */
03811     NULL /* evaluate - solved as separate loop */
03812 };
03813 
03814 /* ----------- Pivot ------------- */
03815 
03816 static void pivotcon_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
03817 {
03818     bPivotConstraint *data= con->data;
03819     
03820     /* target only */
03821     func(con, (ID**)&data->tar, userdata);
03822 }
03823 
03824 static int pivotcon_get_tars (bConstraint *con, ListBase *list)
03825 {
03826     if (con && list) {
03827         bPivotConstraint *data= con->data;
03828         bConstraintTarget *ct;
03829         
03830         /* standard target-getting macro for single-target constraints */
03831         SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
03832         
03833         return 1;
03834     }
03835     
03836     return 0;
03837 }
03838 
03839 static void pivotcon_flush_tars (bConstraint *con, ListBase *list, short nocopy)
03840 {
03841     if (con && list) {
03842         bPivotConstraint *data= con->data;
03843         bConstraintTarget *ct= list->first;
03844         
03845         /* the following macro is used for all standard single-target constraints */
03846         SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
03847     }
03848 }
03849 
03850 static void pivotcon_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
03851 {
03852     bPivotConstraint *data= con->data;
03853     bConstraintTarget *ct= targets->first;
03854     
03855     float pivot[3], vec[3];
03856     float rotMat[3][3];
03857 
03858     /* pivot correction */
03859     float axis[3], angle;
03860     
03861     /* firstly, check if pivoting should take place based on the current rotation */
03862     if (data->rotAxis != PIVOTCON_AXIS_NONE) {
03863         float rot[3];
03864         
03865         /* extract euler-rotation of target */
03866         mat4_to_eulO(rot, cob->rotOrder, cob->matrix);
03867         
03868         /* check which range might be violated */
03869         if (data->rotAxis < PIVOTCON_AXIS_X) {
03870             /* negative rotations (data->rotAxis = 0 -> 2) */
03871             if (rot[data->rotAxis] > 0.0f)
03872                 return;
03873         }
03874         else {
03875             /* positive rotations (data->rotAxis = 3 -> 5 */
03876             if (rot[data->rotAxis - PIVOTCON_AXIS_X] < 0.0f)
03877                 return;
03878         }
03879     }
03880     
03881     /* find the pivot-point to use  */
03882     if (VALID_CONS_TARGET(ct)) {
03883         /* apply offset to target location */
03884         add_v3_v3v3(pivot, ct->matrix[3], data->offset);
03885     }
03886     else {
03887         /* no targets to worry about... */
03888         if ((data->flag & PIVOTCON_FLAG_OFFSET_ABS) == 0) {
03889             /* offset is relative to owner */
03890             add_v3_v3v3(pivot, cob->matrix[3], data->offset);
03891         }
03892         else {
03893             /* directly use the 'offset' specified as an absolute position instead */
03894             copy_v3_v3(pivot, data->offset);
03895         }
03896     }
03897     
03898     /* get rotation matrix representing the rotation of the owner */
03899     // TODO: perhaps we might want to include scaling based on the pivot too?
03900     copy_m3_m4(rotMat, cob->matrix);
03901     normalize_m3(rotMat);
03902 
03903 
03904     /* correct the pivot by the rotation axis otherwise the pivot translates when it shouldnt */
03905     mat3_to_axis_angle(axis, &angle, rotMat);
03906     if(angle) {
03907         float dvec[3];
03908         sub_v3_v3v3(vec, pivot, cob->matrix[3]);
03909         project_v3_v3v3(dvec, vec, axis);
03910         sub_v3_v3(pivot, dvec);
03911     }
03912 
03913     /* perform the pivoting... */
03914         /* 1. take the vector from owner to the pivot */
03915     sub_v3_v3v3(vec, cob->matrix[3], pivot);
03916         /* 2. rotate this vector by the rotation of the object... */
03917     mul_m3_v3(rotMat, vec);
03918         /* 3. make the rotation in terms of the pivot now */
03919     add_v3_v3v3(cob->matrix[3], pivot, vec);
03920 }
03921 
03922 
03923 static bConstraintTypeInfo CTI_PIVOT = {
03924     CONSTRAINT_TYPE_PIVOT, /* type */
03925     sizeof(bPivotConstraint), /* size */
03926     "Pivot", /* name */
03927     "bPivotConstraint", /* struct name */
03928     NULL, /* free data */
03929     NULL, /* relink data */
03930     pivotcon_id_looper, /* id looper */
03931     NULL, /* copy data */
03932     NULL, /* new data */ // XXX: might be needed to get 'normal' pivot behaviour...
03933     pivotcon_get_tars, /* get constraint targets */
03934     pivotcon_flush_tars, /* flush constraint targets */
03935     default_get_tarmat, /* get target matrix */
03936     pivotcon_evaluate /* evaluate */
03937 };
03938 
03939 /* ----------- Follow Track ------------- */
03940 
03941 static void followtrack_new_data (void *cdata)
03942 {
03943     bFollowTrackConstraint *data= (bFollowTrackConstraint *)cdata;
03944     
03945     data->clip= NULL;
03946     data->flag |= FOLLOWTRACK_ACTIVECLIP;
03947 }
03948 
03949 static void followtrack_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
03950 {
03951     bFollowTrackConstraint *data= con->data;
03952     
03953     func(con, (ID**)&data->clip, userdata);
03954     func(con, (ID**)&data->camera, userdata);
03955     func(con, (ID**)&data->depth_ob, userdata);
03956 }
03957 
03958 static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
03959 {
03960     Scene *scene= cob->scene;
03961     bFollowTrackConstraint *data= con->data;
03962     MovieClip *clip= data->clip;
03963     MovieTracking *tracking;
03964     MovieTrackingTrack *track;
03965     MovieTrackingObject *tracking_object;
03966     Object *camob= data->camera ? data->camera : scene->camera;
03967 
03968     if (data->flag & FOLLOWTRACK_ACTIVECLIP)
03969         clip= scene->clip;
03970 
03971     if (!clip || !data->track[0] || !camob)
03972         return;
03973 
03974     tracking= &clip->tracking;
03975 
03976     if(data->object[0])
03977         tracking_object= BKE_tracking_named_object(tracking, data->object);
03978     else
03979         tracking_object= BKE_tracking_get_camera_object(tracking);
03980 
03981     if(!tracking_object)
03982         return;
03983 
03984     track= BKE_tracking_named_track(tracking, tracking_object, data->track);
03985 
03986     if (!track)
03987         return;
03988 
03989     if (data->flag & FOLLOWTRACK_USE_3D_POSITION) {
03990         if (track->flag & TRACK_HAS_BUNDLE) {
03991             float obmat[4][4], mat[4][4];
03992 
03993             copy_m4_m4(obmat, cob->matrix);
03994 
03995             if((tracking_object->flag&TRACKING_OBJECT_CAMERA)==0) {
03996                 float imat[4][4];
03997 
03998                 copy_m4_m4(mat, camob->obmat);
03999 
04000                 BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, imat);
04001                 invert_m4(imat);
04002 
04003                 mul_serie_m4(cob->matrix, obmat, mat, imat, NULL, NULL, NULL, NULL, NULL);
04004                 translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
04005             }
04006             else {
04007                 BKE_get_tracking_mat(cob->scene, camob, mat);
04008 
04009                 mult_m4_m4m4(cob->matrix, obmat, mat);
04010                 translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
04011             }
04012         }
04013     }
04014     else {
04015         MovieTrackingMarker *marker;
04016         float vec[3], disp[3], axis[3], mat[4][4];
04017         float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp);
04018         float len, d;
04019 
04020         where_is_object_mat(scene, camob, mat);
04021 
04022         /* camera axis */
04023         vec[0]= 0.0f;
04024         vec[1]= 0.0f;
04025         vec[2]= 1.0f;
04026         mul_v3_m4v3(axis, mat, vec);
04027 
04028         /* distance to projection plane */
04029         copy_v3_v3(vec, cob->matrix[3]);
04030         sub_v3_v3(vec, mat[3]);
04031         project_v3_v3v3(disp, vec, axis);
04032 
04033         len= len_v3(disp);
04034 
04035         if (len > FLT_EPSILON) {
04036             CameraParams params;
04037             float pos[2], rmat[4][4];
04038 
04039             marker= BKE_tracking_get_marker(track, scene->r.cfra);
04040 
04041             add_v2_v2v2(pos, marker->pos, track->offset);
04042 
04043             camera_params_init(&params);
04044             camera_params_from_object(&params, camob);
04045 
04046             if (params.is_ortho) {
04047                 vec[0]= params.ortho_scale * (pos[0]-0.5f+params.shiftx);
04048                 vec[1]= params.ortho_scale * (pos[1]-0.5f+params.shifty);
04049                 vec[2]= -len;
04050 
04051                 if (aspect > 1.0f) vec[1] /= aspect;
04052                 else vec[0] *= aspect;
04053 
04054                 mul_v3_m4v3(disp, camob->obmat, vec);
04055 
04056                 copy_m4_m4(rmat, camob->obmat);
04057                 zero_v3(rmat[3]);
04058                 mult_m4_m4m4(cob->matrix, cob->matrix, rmat);
04059 
04060                 copy_v3_v3(cob->matrix[3], disp);
04061             }
04062             else {
04063                 d= (len*params.sensor_x) / (2.0f*params.lens);
04064 
04065                 vec[0]= d*(2.0f*(pos[0]+params.shiftx)-1.0f);
04066                 vec[1]= d*(2.0f*(pos[1]+params.shifty)-1.0f);
04067                 vec[2]= -len;
04068 
04069                 if (aspect > 1.0f) vec[1] /= aspect;
04070                 else vec[0] *= aspect;
04071 
04072                 mul_v3_m4v3(disp, camob->obmat, vec);
04073 
04074                 /* apply camera rotation so Z-axis would be co-linear */
04075                 copy_m4_m4(rmat, camob->obmat);
04076                 zero_v3(rmat[3]);
04077                 mult_m4_m4m4(cob->matrix, cob->matrix, rmat);
04078 
04079                 copy_v3_v3(cob->matrix[3], disp);
04080             }
04081 
04082             if(data->depth_ob && data->depth_ob->derivedFinal) {
04083                 Object *depth_ob= data->depth_ob;
04084                 BVHTreeFromMesh treeData= NULL_BVHTreeFromMesh;
04085                 BVHTreeRayHit hit;
04086                 float ray_start[3], ray_end[3], ray_nor[3], imat[4][4];
04087                 int result;
04088 
04089                 invert_m4_m4(imat, depth_ob->obmat);
04090 
04091                 mul_v3_m4v3(ray_start, imat, camob->obmat[3]);
04092                 mul_v3_m4v3(ray_end, imat, cob->matrix[3]);
04093 
04094                 sub_v3_v3v3(ray_nor, ray_end, ray_start);
04095 
04096                 bvhtree_from_mesh_faces(&treeData, depth_ob->derivedFinal, 0.0f, 4, 6);
04097 
04098                 hit.dist= FLT_MAX;
04099                 hit.index= -1;
04100 
04101                 result= BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_nor, 0.0f, &hit, treeData.raycast_callback, &treeData);
04102 
04103                 if(result != -1) {
04104                     mul_v3_m4v3(cob->matrix[3], depth_ob->obmat, hit.co);
04105                 }
04106 
04107                 free_bvhtree_from_mesh(&treeData);
04108             }
04109         }
04110     }
04111 }
04112 
04113 static bConstraintTypeInfo CTI_FOLLOWTRACK = {
04114     CONSTRAINT_TYPE_FOLLOWTRACK, /* type */
04115     sizeof(bFollowTrackConstraint), /* size */
04116     "Follow Track", /* name */
04117     "bFollowTrackConstraint", /* struct name */
04118     NULL, /* free data */
04119     NULL, /* relink data */
04120     followtrack_id_looper, /* id looper */
04121     NULL, /* copy data */
04122     followtrack_new_data, /* new data */
04123     NULL, /* get constraint targets */
04124     NULL, /* flush constraint targets */
04125     NULL, /* get target matrix */
04126     followtrack_evaluate /* evaluate */
04127 };
04128 
04129 /* ----------- Camre Solver ------------- */
04130 
04131 static void camerasolver_new_data (void *cdata)
04132 {
04133     bCameraSolverConstraint *data= (bCameraSolverConstraint *)cdata;
04134     
04135     data->clip = NULL;
04136     data->flag |= CAMERASOLVER_ACTIVECLIP;
04137 }
04138 
04139 static void camerasolver_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
04140 {
04141     bCameraSolverConstraint *data= con->data;
04142     
04143     func(con, (ID**)&data->clip, userdata);
04144 }
04145 
04146 static void camerasolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
04147 {
04148     Scene *scene= cob->scene;
04149     bCameraSolverConstraint *data= con->data;
04150     MovieClip *clip= data->clip;
04151 
04152     if (data->flag & CAMERASOLVER_ACTIVECLIP)
04153         clip= scene->clip;
04154 
04155     if (clip) {
04156         float mat[4][4], obmat[4][4];
04157         MovieTracking *tracking= &clip->tracking;
04158         MovieTrackingObject *object= BKE_tracking_get_camera_object(tracking);
04159 
04160         BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat);
04161 
04162         copy_m4_m4(obmat, cob->matrix);
04163 
04164         mult_m4_m4m4(cob->matrix, obmat, mat);
04165     }
04166 }
04167 
04168 static bConstraintTypeInfo CTI_CAMERASOLVER = {
04169     CONSTRAINT_TYPE_CAMERASOLVER, /* type */
04170     sizeof(bCameraSolverConstraint), /* size */
04171     "Camera Solver", /* name */
04172     "bCameraSolverConstraint", /* struct name */
04173     NULL, /* free data */
04174     NULL, /* relink data */
04175     camerasolver_id_looper, /* id looper */
04176     NULL, /* copy data */
04177     camerasolver_new_data, /* new data */
04178     NULL, /* get constraint targets */
04179     NULL, /* flush constraint targets */
04180     NULL, /* get target matrix */
04181     camerasolver_evaluate /* evaluate */
04182 };
04183 
04184 /* ----------- Object Solver ------------- */
04185 
04186 static void objectsolver_new_data (void *cdata)
04187 {
04188     bObjectSolverConstraint *data= (bObjectSolverConstraint *)cdata;
04189 
04190     data->clip = NULL;
04191     data->flag |= OBJECTSOLVER_ACTIVECLIP;
04192     unit_m4(data->invmat);
04193 }
04194 
04195 static void objectsolver_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
04196 {
04197     bObjectSolverConstraint *data= con->data;
04198 
04199     func(con, (ID**)&data->clip, userdata);
04200     func(con, (ID**)&data->camera, userdata);
04201 }
04202 
04203 static void objectsolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
04204 {
04205     Scene *scene= cob->scene;
04206     bObjectSolverConstraint *data= con->data;
04207     MovieClip *clip= data->clip;
04208     Object *camob= data->camera ? data->camera : scene->camera;
04209 
04210     if (data->flag & OBJECTSOLVER_ACTIVECLIP)
04211         clip= scene->clip;
04212 
04213     if(!camob || !clip)
04214         return;
04215 
04216     if (clip) {
04217         MovieTracking *tracking= &clip->tracking;
04218         MovieTrackingObject *object;
04219 
04220         object= BKE_tracking_named_object(tracking, data->object);
04221 
04222         if(object) {
04223             float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4];
04224 
04225             where_is_object_mat(scene, camob, cammat);
04226 
04227             BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat);
04228 
04229             invert_m4_m4(camimat, cammat);
04230             mult_m4_m4m4(parmat, cammat, data->invmat);
04231 
04232             copy_m4_m4(cammat, camob->obmat);
04233             copy_m4_m4(obmat, cob->matrix);
04234 
04235             invert_m4_m4(imat, mat);
04236 
04237             mul_serie_m4(cob->matrix, cammat, imat, camimat, parmat, obmat, NULL, NULL, NULL);
04238         }
04239     }
04240 }
04241 
04242 static bConstraintTypeInfo CTI_OBJECTSOLVER = {
04243     CONSTRAINT_TYPE_OBJECTSOLVER, /* type */
04244     sizeof(bObjectSolverConstraint), /* size */
04245     "Object Solver", /* name */
04246     "bObjectSolverConstraint", /* struct name */
04247     NULL, /* free data */
04248     NULL, /* relink data */
04249     objectsolver_id_looper, /* id looper */
04250     NULL, /* copy data */
04251     objectsolver_new_data, /* new data */
04252     NULL, /* get constraint targets */
04253     NULL, /* flush constraint targets */
04254     NULL, /* get target matrix */
04255     objectsolver_evaluate /* evaluate */
04256 };
04257 
04258 /* ************************* Constraints Type-Info *************************** */
04259 /* All of the constraints api functions use bConstraintTypeInfo structs to carry out
04260  * and operations that involve constraint specific code.
04261  */
04262 
04263 /* These globals only ever get directly accessed in this file */
04264 static bConstraintTypeInfo *constraintsTypeInfo[NUM_CONSTRAINT_TYPES];
04265 static short CTI_INIT= 1; /* when non-zero, the list needs to be updated */
04266 
04267 /* This function only gets called when CTI_INIT is non-zero */
04268 static void constraints_init_typeinfo (void)
04269 {
04270     constraintsTypeInfo[0]=  NULL;                  /* 'Null' Constraint */
04271     constraintsTypeInfo[1]=  &CTI_CHILDOF;          /* ChildOf Constraint */
04272     constraintsTypeInfo[2]=  &CTI_TRACKTO;          /* TrackTo Constraint */
04273     constraintsTypeInfo[3]=  &CTI_KINEMATIC;        /* IK Constraint */
04274     constraintsTypeInfo[4]=  &CTI_FOLLOWPATH;       /* Follow-Path Constraint */
04275     constraintsTypeInfo[5]=  &CTI_ROTLIMIT;         /* Limit Rotation Constraint */
04276     constraintsTypeInfo[6]=  &CTI_LOCLIMIT;         /* Limit Location Constraint */
04277     constraintsTypeInfo[7]=  &CTI_SIZELIMIT;        /* Limit Scaling Constraint */
04278     constraintsTypeInfo[8]=  &CTI_ROTLIKE;          /* Copy Rotation Constraint */
04279     constraintsTypeInfo[9]=  &CTI_LOCLIKE;          /* Copy Location Constraint */
04280     constraintsTypeInfo[10]= &CTI_SIZELIKE;         /* Copy Scaling Constraint */
04281     constraintsTypeInfo[11]= &CTI_PYTHON;           /* Python/Script Constraint */
04282     constraintsTypeInfo[12]= &CTI_ACTION;           /* Action Constraint */
04283     constraintsTypeInfo[13]= &CTI_LOCKTRACK;        /* Locked-Track Constraint */
04284     constraintsTypeInfo[14]= &CTI_DISTLIMIT;        /* Limit Distance Constraint */
04285     constraintsTypeInfo[15]= &CTI_STRETCHTO;        /* StretchTo Constaint */ 
04286     constraintsTypeInfo[16]= &CTI_MINMAX;           /* Floor Constraint */
04287     constraintsTypeInfo[17]= &CTI_RIGIDBODYJOINT;   /* RigidBody Constraint */
04288     constraintsTypeInfo[18]= &CTI_CLAMPTO;          /* ClampTo Constraint */    
04289     constraintsTypeInfo[19]= &CTI_TRANSFORM;        /* Transformation Constraint */
04290     constraintsTypeInfo[20]= &CTI_SHRINKWRAP;       /* Shrinkwrap Constraint */
04291     constraintsTypeInfo[21]= &CTI_DAMPTRACK;        /* Damped TrackTo Constraint */
04292     constraintsTypeInfo[22]= &CTI_SPLINEIK;         /* Spline IK Constraint */
04293     constraintsTypeInfo[23]= &CTI_TRANSLIKE;        /* Copy Transforms Constraint */
04294     constraintsTypeInfo[24]= &CTI_SAMEVOL;          /* Maintain Volume Constraint */
04295     constraintsTypeInfo[25]= &CTI_PIVOT;            /* Pivot Constraint */
04296     constraintsTypeInfo[26]= &CTI_FOLLOWTRACK;      /* Follow Track Constraint */
04297     constraintsTypeInfo[27]= &CTI_CAMERASOLVER;     /* Camera Solver Constraint */
04298     constraintsTypeInfo[28]= &CTI_OBJECTSOLVER;     /* Object Solver Constraint */
04299 }
04300 
04301 /* This function should be used for getting the appropriate type-info when only
04302  * a constraint type is known
04303  */
04304 bConstraintTypeInfo *get_constraint_typeinfo (int type)
04305 {
04306     /* initialise the type-info list? */
04307     if (CTI_INIT) {
04308         constraints_init_typeinfo();
04309         CTI_INIT = 0;
04310     }
04311     
04312     /* only return for valid types */
04313     if ( (type >= CONSTRAINT_TYPE_NULL) && 
04314          (type < NUM_CONSTRAINT_TYPES ) ) 
04315     {
04316         /* there shouldn't be any segfaults here... */
04317         return constraintsTypeInfo[type];
04318     }
04319     else {
04320         printf("No valid constraint type-info data available. Type = %i \n", type);
04321     }
04322     
04323     return NULL;
04324 } 
04325  
04326 /* This function should always be used to get the appropriate type-info, as it
04327  * has checks which prevent segfaults in some weird cases.
04328  */
04329 bConstraintTypeInfo *constraint_get_typeinfo (bConstraint *con)
04330 {
04331     /* only return typeinfo for valid constraints */
04332     if (con)
04333         return get_constraint_typeinfo(con->type);
04334     else
04335         return NULL;
04336 }
04337 
04338 /* ************************* General Constraints API ************************** */
04339 /* The functions here are called by various parts of Blender. Very few (should be none if possible)
04340  * constraint-specific code should occur here.
04341  */
04342  
04343 /* ---------- Data Management ------- */
04344 
04345 /* Free data of a specific constraint if it has any info.
04346  * be sure to run BIK_clear_data() when freeing an IK constraint,
04347  * unless DAG_scene_sort is called. */
04348 void free_constraint_data (bConstraint *con)
04349 {
04350     if (con->data) {
04351         bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
04352         
04353         /* perform any special freeing constraint may have */
04354         if (cti && cti->free_data)
04355             cti->free_data(con);
04356         
04357         /* free constraint data now */
04358         MEM_freeN(con->data);
04359     }
04360 }
04361 
04362 /* Free all constraints from a constraint-stack */
04363 void free_constraints (ListBase *list)
04364 {
04365     bConstraint *con;
04366     
04367     /* Free constraint data and also any extra data */
04368     for (con= list->first; con; con= con->next)
04369         free_constraint_data(con);
04370     
04371     /* Free the whole list */
04372     BLI_freelistN(list);
04373 }
04374 
04375 
04376 /* Remove the specified constraint from the given constraint stack */
04377 int remove_constraint (ListBase *list, bConstraint *con)
04378 {
04379     if (con) {
04380         free_constraint_data(con);
04381         BLI_freelinkN(list, con);
04382         return 1;
04383     }
04384     else
04385         return 0;
04386 }
04387 
04388 /* Remove all the constraints of the specified type from the given constraint stack */
04389 void remove_constraints_type (ListBase *list, short type, short last_only)
04390 {
04391     bConstraint *con, *conp;
04392     
04393     if (list == NULL)
04394         return;
04395     
04396     /* remove from the end of the list to make it faster to find the last instance */
04397     for (con= list->last; con; con= conp) {
04398         conp= con->prev;
04399         
04400         if (con->type == type) {
04401             remove_constraint(list, con);
04402             if (last_only) 
04403                 return;
04404         }
04405     }
04406 }
04407 
04408 /* ......... */
04409 
04410 /* Creates a new constraint, initialises its data, and returns it */
04411 static bConstraint *add_new_constraint_internal (const char *name, short type)
04412 {
04413     bConstraint *con= MEM_callocN(sizeof(bConstraint), "Constraint");
04414     bConstraintTypeInfo *cti= get_constraint_typeinfo(type);
04415     const char *newName;
04416 
04417     /* Set up a generic constraint datablock */
04418     con->type = type;
04419     con->flag |= CONSTRAINT_EXPAND;
04420     con->enforce = 1.0f;
04421 
04422     /* Determine a basic name, and info */
04423     if (cti) {
04424         /* initialise constraint data */
04425         con->data = MEM_callocN(cti->size, cti->structName);
04426         
04427         /* only constraints that change any settings need this */
04428         if (cti->new_data)
04429             cti->new_data(con->data);
04430         
04431         /* if no name is provided, use the type of the constraint as the name */
04432         newName= (name && name[0]) ? name : cti->name;
04433     }
04434     else {
04435         /* if no name is provided, use the generic "Const" name */
04436         // NOTE: any constraint type that gets here really shouldn't get added...
04437         newName= (name && name[0]) ? name : "Const";
04438     }
04439     
04440     /* copy the name */
04441     BLI_strncpy(con->name, newName, sizeof(con->name));
04442     
04443     /* return the new constraint */
04444     return con;
04445 }
04446 
04447 /* if pchan is not NULL then assume we're adding a pose constraint */
04448 static bConstraint *add_new_constraint (Object *ob, bPoseChannel *pchan, const char *name, short type)
04449 {
04450     bConstraint *con;
04451     ListBase *list;
04452     
04453     /* add the constraint */
04454     con= add_new_constraint_internal(name, type);
04455     
04456     /* find the constraint stack - bone or object? */
04457     list = (pchan) ? (&pchan->constraints) : (&ob->constraints);
04458     
04459     if (list) {
04460         /* add new constraint to end of list of constraints before ensuring that it has a unique name
04461          * (otherwise unique-naming code will fail, since it assumes element exists in list)
04462          */
04463         BLI_addtail(list, con);
04464         unique_constraint_name(con, list);
04465         
04466         /* if the target list is a list on some PoseChannel belonging to a proxy-protected
04467          * Armature layer, we must tag newly added constraints with a flag which allows them
04468          * to persist after proxy syncing has been done
04469          */
04470         if (proxylocked_constraints_owner(ob, pchan))
04471             con->flag |= CONSTRAINT_PROXY_LOCAL;
04472         
04473         /* make this constraint the active one */
04474         constraints_set_active(list, con);
04475     }
04476     
04477     /* set type+owner specific immutable settings */
04478     // TODO: does action constraint need anything here - i.e. spaceonce?
04479     switch (type) {
04480         case CONSTRAINT_TYPE_CHILDOF:
04481         {
04482             /* if this constraint is being added to a posechannel, make sure
04483              * the constraint gets evaluated in pose-space */
04484             if (pchan) {
04485                 con->ownspace = CONSTRAINT_SPACE_POSE;
04486                 con->flag |= CONSTRAINT_SPACEONCE;
04487             }
04488         }
04489             break;
04490     }
04491     
04492     return con;
04493 }
04494 
04495 /* ......... */
04496 
04497 /* Add new constraint for the given bone */
04498 bConstraint *add_pose_constraint (Object *ob, bPoseChannel *pchan, const char *name, short type)
04499 {
04500     if (pchan == NULL)
04501         return NULL;
04502     
04503     return add_new_constraint(ob, pchan, name, type);
04504 }
04505 
04506 /* Add new constraint for the given object */
04507 bConstraint *add_ob_constraint(Object *ob, const char *name, short type)
04508 {
04509     return add_new_constraint(ob, NULL, name, type);
04510 }
04511 
04512 /* ......... */
04513 
04514 /* Reassign links that constraints have to other data (called during file loading?) */
04515 void relink_constraints (ListBase *conlist)
04516 {
04517     bConstraint *con;
04518     bConstraintTarget *ct;
04519     
04520     for (con= conlist->first; con; con= con->next) {
04521         bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
04522         
04523         if (cti) {
04524             /* relink any targets */
04525             if (cti->get_constraint_targets) {
04526                 ListBase targets = {NULL, NULL};
04527                 
04528                 cti->get_constraint_targets(con, &targets);
04529                 for (ct= targets.first; ct; ct= ct->next) {
04530                     ID_NEW(ct->tar);
04531                 }
04532                 
04533                 if (cti->flush_constraint_targets)
04534                     cti->flush_constraint_targets(con, &targets, 0);
04535             }
04536             
04537             /* relink any other special data */
04538             if (cti->relink_data)
04539                 cti->relink_data(con);
04540         }
04541     }
04542 }
04543 
04544 /* Run the given callback on all ID-blocks in list of constraints */
04545 void id_loop_constraints (ListBase *conlist, ConstraintIDFunc func, void *userdata)
04546 {
04547     bConstraint *con;
04548     
04549     for (con= conlist->first; con; con= con->next) {
04550         bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
04551         
04552         if (cti) {
04553             if (cti->id_looper)
04554                 cti->id_looper(con, func, userdata);
04555         }
04556     }
04557 }
04558 
04559 /* ......... */
04560 
04561 /* helper for copy_constraints(), to be used for making sure that ID's are valid */
04562 static void con_extern_cb(bConstraint *UNUSED(con), ID **idpoin, void *UNUSED(userData))
04563 {
04564     if (*idpoin && (*idpoin)->lib)
04565         id_lib_extern(*idpoin);
04566 }
04567 
04568 /* duplicate all of the constraints in a constraint stack */
04569 void copy_constraints (ListBase *dst, const ListBase *src, int do_extern)
04570 {
04571     bConstraint *con, *srccon;
04572     
04573     dst->first= dst->last= NULL;
04574     BLI_duplicatelist(dst, src);
04575     
04576     for (con=dst->first, srccon=src->first; con && srccon; srccon=srccon->next, con=con->next) {
04577         bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
04578         
04579         /* make a new copy of the constraint's data */
04580         con->data = MEM_dupallocN(con->data);
04581         
04582         /* only do specific constraints if required */
04583         if (cti) {
04584             /* perform custom copying operations if needed */
04585             if (cti->copy_data)
04586                 cti->copy_data(con, srccon);
04587             
04588             /* for proxies we dont want to make extern */
04589             if (do_extern) {
04590                 /* go over used ID-links for this constraint to ensure that they are valid for proxies */
04591                 if (cti->id_looper)
04592                     cti->id_looper(con, con_extern_cb, NULL);
04593             }
04594         }
04595     }
04596 }
04597 
04598 /* ......... */
04599 
04600 bConstraint *constraints_findByName(ListBase *list, const char *name)
04601 {
04602     return BLI_findstring(list, name, offsetof(bConstraint, name));
04603 }
04604 
04605 /* finds the 'active' constraint in a constraint stack */
04606 bConstraint *constraints_get_active (ListBase *list)
04607 {
04608     bConstraint *con;
04609     
04610     /* search for the first constraint with the 'active' flag set */
04611     if (list) {
04612         for (con= list->first; con; con= con->next) {
04613             if (con->flag & CONSTRAINT_ACTIVE)
04614                 return con;
04615         }
04616     }
04617     
04618     /* no active constraint found */
04619     return NULL;
04620 }
04621 
04622 /* Set the given constraint as the active one (clearing all the others) */
04623 void constraints_set_active (ListBase *list, bConstraint *con)
04624 {
04625     bConstraint *c;
04626     
04627     if (list) {
04628         for (c= list->first; c; c= c->next) {
04629             if (c == con) 
04630                 c->flag |= CONSTRAINT_ACTIVE;
04631             else 
04632                 c->flag &= ~CONSTRAINT_ACTIVE;
04633         }
04634     }
04635 }
04636 
04637 /* -------- Constraints and Proxies ------- */
04638 
04639 /* Rescue all constraints tagged as being CONSTRAINT_PROXY_LOCAL (i.e. added to bone that's proxy-synced in this file) */
04640 void extract_proxylocal_constraints (ListBase *dst, ListBase *src)
04641 {
04642     bConstraint *con, *next;
04643     
04644     /* for each tagged constraint, remove from src and move to dst */
04645     for (con= src->first; con; con= next) {
04646         next= con->next;
04647         
04648         /* check if tagged */
04649         if (con->flag & CONSTRAINT_PROXY_LOCAL) {
04650             BLI_remlink(src, con);
04651             BLI_addtail(dst, con);
04652         }
04653     }
04654 }
04655 
04656 /* Returns if the owner of the constraint is proxy-protected */
04657 short proxylocked_constraints_owner (Object *ob, bPoseChannel *pchan)
04658 {
04659     /* Currently, constraints can only be on object or bone level */
04660     if (ob && ob->proxy) {
04661         if (ob->pose && pchan) {
04662             bArmature *arm= ob->data;
04663             
04664             /* On bone-level, check if bone is on proxy-protected layer */
04665             if ((pchan->bone) && (pchan->bone->layer & arm->layer_protected))
04666                 return 1;
04667         }
04668         else {
04669             /* FIXME: constraints on object-level are not handled well yet */
04670             return 1;
04671         }   
04672     }
04673     
04674     return 0;
04675 }
04676 
04677 /* -------- Target-Matrix Stuff ------- */
04678 
04679 /* This function is a relic from the prior implementations of the constraints system, when all
04680  * constraints either had one or no targets. It used to be called during the main constraint solving
04681  * loop, but is now only used for the remaining cases for a few constraints. 
04682  *
04683  * None of the actual calculations of the matrices should be done here! Also, this function is
04684  * not to be used by any new constraints, particularly any that have multiple targets.
04685  */
04686 void get_constraint_target_matrix (struct Scene *scene, bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime)
04687 {
04688     bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
04689     ListBase targets = {NULL, NULL};
04690     bConstraintOb *cob;
04691     bConstraintTarget *ct;
04692     
04693     if (cti && cti->get_constraint_targets) {
04694         /* make 'constraint-ob' */
04695         cob= MEM_callocN(sizeof(bConstraintOb), "tempConstraintOb");
04696         cob->type= ownertype;
04697         cob->scene = scene;
04698         switch (ownertype) {
04699             case CONSTRAINT_OBTYPE_OBJECT: /* it is usually this case */
04700             {
04701                 cob->ob= (Object *)ownerdata;
04702                 cob->pchan= NULL;
04703                 if (cob->ob) {
04704                     copy_m4_m4(cob->matrix, cob->ob->obmat);
04705                     copy_m4_m4(cob->startmat, cob->matrix);
04706                 }
04707                 else {
04708                     unit_m4(cob->matrix);
04709                     unit_m4(cob->startmat);
04710                 }
04711             }   
04712                 break;
04713             case CONSTRAINT_OBTYPE_BONE: /* this may occur in some cases */
04714             {
04715                 cob->ob= NULL; /* this might not work at all :/ */
04716                 cob->pchan= (bPoseChannel *)ownerdata;
04717                 if (cob->pchan) {
04718                     copy_m4_m4(cob->matrix, cob->pchan->pose_mat);
04719                     copy_m4_m4(cob->startmat, cob->matrix);
04720                 }
04721                 else {
04722                     unit_m4(cob->matrix);
04723                     unit_m4(cob->startmat);
04724                 }
04725             }
04726                 break;
04727         }
04728         
04729         /* get targets - we only need the first one though (and there should only be one) */
04730         cti->get_constraint_targets(con, &targets);
04731         
04732         /* only calculate the target matrix on the first target */
04733         ct= (bConstraintTarget *)targets.first;
04734         while(ct && n-- > 0)
04735             ct= ct->next;
04736 
04737         if (ct) {
04738             if (cti->get_target_matrix)
04739                 cti->get_target_matrix(con, cob, ct, ctime);
04740             copy_m4_m4(mat, ct->matrix);
04741         }
04742         
04743         /* free targets + 'constraint-ob' */
04744         if (cti->flush_constraint_targets)
04745             cti->flush_constraint_targets(con, &targets, 1);
04746         MEM_freeN(cob);
04747     }
04748     else {
04749         /* invalid constraint - perhaps... */
04750         unit_m4(mat);
04751     }
04752 }
04753 
04754 /* Get the list of targets required for solving a constraint */
04755 void get_constraint_targets_for_solving (bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime)
04756 {
04757     bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
04758     
04759     if (cti && cti->get_constraint_targets) {
04760         bConstraintTarget *ct;
04761         
04762         /* get targets 
04763          *  - constraints should use ct->matrix, not directly accessing values
04764          *  - ct->matrix members have not yet been calculated here! 
04765          */
04766         cti->get_constraint_targets(con, targets);
04767         
04768         /* set matrices 
04769          *  - calculate if possible, otherwise just initialise as identity matrix 
04770          */
04771         if (cti->get_target_matrix) {
04772             for (ct= targets->first; ct; ct= ct->next) 
04773                 cti->get_target_matrix(con, cob, ct, ctime);
04774         }
04775         else {
04776             for (ct= targets->first; ct; ct= ct->next)
04777                 unit_m4(ct->matrix);
04778         }
04779     }
04780 }
04781  
04782 /* ---------- Evaluation ----------- */
04783 
04784 /* This function is called whenever constraints need to be evaluated. Currently, all
04785  * constraints that can be evaluated are everytime this gets run.
04786  *
04787  * constraints_make_evalob and constraints_clear_evalob should be called before and 
04788  * after running this function, to sort out cob
04789  */
04790 void solve_constraints (ListBase *conlist, bConstraintOb *cob, float ctime)
04791 {
04792     bConstraint *con;
04793     float oldmat[4][4];
04794     float enf;
04795 
04796     /* check that there is a valid constraint object to evaluate */
04797     if (cob == NULL)
04798         return;
04799     
04800     /* loop over available constraints, solving and blending them */
04801     for (con= conlist->first; con; con= con->next) {
04802         bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
04803         ListBase targets = {NULL, NULL};
04804         
04805         /* these we can skip completely (invalid constraints...) */
04806         if (cti == NULL) continue;
04807         if (con->flag & (CONSTRAINT_DISABLE|CONSTRAINT_OFF)) continue;
04808         /* these constraints can't be evaluated anyway */
04809         if (cti->evaluate_constraint == NULL) continue;
04810         /* influence == 0 should be ignored */
04811         if (con->enforce == 0.0f) continue;
04812         
04813         /* influence of constraint
04814          *  - value should have been set from animation data already
04815          */
04816         enf = con->enforce;
04817         
04818         /* make copy of worldspace matrix pre-constraint for use with blending later */
04819         copy_m4_m4(oldmat, cob->matrix);
04820         
04821         /* move owner matrix into right space */
04822         constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace);
04823         
04824         /* prepare targets for constraint solving */
04825         get_constraint_targets_for_solving(con, cob, &targets, ctime);
04826         
04827         /* Solve the constraint and put result in cob->matrix */
04828         cti->evaluate_constraint(con, cob, &targets);
04829         
04830         /* clear targets after use 
04831          *  - this should free temp targets but no data should be copied back
04832          *    as constraints may have done some nasty things to it...
04833          */
04834         if (cti->flush_constraint_targets) {
04835             cti->flush_constraint_targets(con, &targets, 1);
04836         }
04837         
04838         /* move owner back into worldspace for next constraint/other business */
04839         if ((con->flag & CONSTRAINT_SPACEONCE) == 0) 
04840             constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD);
04841             
04842         /* Interpolate the enforcement, to blend result of constraint into final owner transform 
04843          *  - all this happens in worldspace to prevent any weirdness creeping in ([#26014] and [#25725]),
04844          *    since some constraints may not convert the solution back to the input space before blending
04845          *    but all are guaranteed to end up in good "worldspace" result
04846          */
04847         /* Note: all kind of stuff here before (caused trouble), much easier to just interpolate, or did I miss something? -jahka */
04848         if (enf < 1.0f) {
04849             float solution[4][4];
04850             copy_m4_m4(solution, cob->matrix);
04851             blend_m4_m4m4(cob->matrix, oldmat, solution, enf);
04852         }
04853     }
04854 }