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