Blender V2.61 - r43446

implicit.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) Blender Foundation
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include "MEM_guardedalloc.h"
00034 
00035 #include "DNA_scene_types.h"
00036 #include "DNA_object_types.h"
00037 #include "DNA_object_force.h"
00038 #include "DNA_meshdata_types.h"
00039 
00040 #include "BLI_threads.h"
00041 #include "BLI_math.h"
00042 #include "BLI_linklist.h"
00043 #include "BLI_utildefines.h"
00044 
00045 #include "BKE_cloth.h"
00046 #include "BKE_collision.h"
00047 #include "BKE_effect.h"
00048 #include "BKE_global.h"
00049 
00050 
00051 #define CLOTH_OPENMP_LIMIT 512
00052 
00053 #ifdef _WIN32
00054 #include <windows.h>
00055 static LARGE_INTEGER _itstart, _itend;
00056 static LARGE_INTEGER ifreq;
00057 static void itstart(void)
00058 {
00059     static int first = 1;
00060     if(first) {
00061         QueryPerformanceFrequency(&ifreq);
00062         first = 0;
00063     }
00064     QueryPerformanceCounter(&_itstart);
00065 }
00066 static void itend(void)
00067 {
00068     QueryPerformanceCounter(&_itend);
00069 }
00070 double itval(void)
00071 {
00072     return ((double)_itend.QuadPart -
00073             (double)_itstart.QuadPart)/((double)ifreq.QuadPart);
00074 }
00075 #else
00076 #include <sys/time.h>
00077 // intrinsics need better compile flag checking
00078 // #include <xmmintrin.h>
00079 // #include <pmmintrin.h>
00080 // #include <pthread.h>
00081 
00082 static struct timeval _itstart, _itend;
00083 static struct timezone itz;
00084 void itstart(void)
00085 {
00086     gettimeofday(&_itstart, &itz);
00087 }
00088 static void itend(void)
00089 {
00090     gettimeofday(&_itend,&itz);
00091 }
00092 double itval(void)
00093 {
00094     double t1, t2;
00095     t1 =  (double)_itstart.tv_sec + (double)_itstart.tv_usec/(1000*1000);
00096     t2 =  (double)_itend.tv_sec + (double)_itend.tv_usec/(1000*1000);
00097     return t2-t1;
00098 }
00099 #endif
00100 
00101 static float I[3][3] = {{1,0,0},{0,1,0},{0,0,1}};
00102 static float ZERO[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}};
00103 
00104 /*
00105 #define C99
00106 #ifdef C99
00107 #defineDO_INLINE inline 
00108 #else 
00109 #defineDO_INLINE static 
00110 #endif
00111 */
00112 struct Cloth;
00113 
00115 /* fast vector / matrix library, enhancements are welcome :) -dg */
00117 
00118 /* DEFINITIONS */
00119 typedef float lfVector[3];
00120 typedef struct fmatrix3x3 {
00121     float m[3][3]; /* 3x3 matrix */
00122     unsigned int c,r; /* column and row number */
00123     int pinned; /* is this vertex allowed to move? */
00124     float n1,n2,n3; /* three normal vectors for collision constrains */
00125     unsigned int vcount; /* vertex count */
00126     unsigned int scount; /* spring count */ 
00127 } fmatrix3x3;
00128 
00130 // float[3] vector
00132 /* simple vector code */
00133 /* STATUS: verified */
00134 DO_INLINE void mul_fvector_S(float to[3], float from[3], float scalar)
00135 {
00136     to[0] = from[0] * scalar;
00137     to[1] = from[1] * scalar;
00138     to[2] = from[2] * scalar;
00139 }
00140 /* simple cross product */
00141 /* STATUS: verified */
00142 DO_INLINE void cross_fvector(float to[3], float vectorA[3], float vectorB[3])
00143 {
00144     to[0] = vectorA[1] * vectorB[2] - vectorA[2] * vectorB[1];
00145     to[1] = vectorA[2] * vectorB[0] - vectorA[0] * vectorB[2];
00146     to[2] = vectorA[0] * vectorB[1] - vectorA[1] * vectorB[0];
00147 }
00148 /* simple v^T * v product ("outer product") */
00149 /* STATUS: HAS TO BE verified (*should* work) */
00150 DO_INLINE void mul_fvectorT_fvector(float to[3][3], float vectorA[3], float vectorB[3])
00151 {
00152     mul_fvector_S(to[0], vectorB, vectorA[0]);
00153     mul_fvector_S(to[1], vectorB, vectorA[1]);
00154     mul_fvector_S(to[2], vectorB, vectorA[2]);
00155 }
00156 /* simple v^T * v product with scalar ("outer product") */
00157 /* STATUS: HAS TO BE verified (*should* work) */
00158 DO_INLINE void mul_fvectorT_fvectorS(float to[3][3], float vectorA[3], float vectorB[3], float aS)
00159 {   
00160     mul_fvectorT_fvector(to, vectorA, vectorB);
00161     
00162     mul_fvector_S(to[0], to[0], aS);
00163     mul_fvector_S(to[1], to[1], aS);
00164     mul_fvector_S(to[2], to[2], aS);
00165 }
00166 
00167 
00168 /* printf vector[3] on console: for debug output */
00169 static void print_fvector(float m3[3])
00170 {
00171     printf("%f\n%f\n%f\n\n",m3[0],m3[1],m3[2]);
00172 }
00173 
00175 // long float vector float (*)[3]
00177 /* print long vector on console: for debug output */
00178 DO_INLINE void print_lfvector(float (*fLongVector)[3], unsigned int verts)
00179 {
00180     unsigned int i = 0;
00181     for(i = 0; i < verts; i++)
00182     {
00183         print_fvector(fLongVector[i]);
00184     }
00185 }
00186 /* create long vector */
00187 DO_INLINE lfVector *create_lfvector(unsigned int verts)
00188 {
00189     // TODO: check if memory allocation was successfull */
00190     return  (lfVector *)MEM_callocN (verts * sizeof(lfVector), "cloth_implicit_alloc_vector");
00191     // return (lfVector *)cloth_aligned_malloc(&MEMORY_BASE, verts * sizeof(lfVector));
00192 }
00193 /* delete long vector */
00194 DO_INLINE void del_lfvector(float (*fLongVector)[3])
00195 {
00196     if (fLongVector != NULL)
00197     {
00198         MEM_freeN (fLongVector);
00199         // cloth_aligned_free(&MEMORY_BASE, fLongVector);
00200     }
00201 }
00202 /* copy long vector */
00203 DO_INLINE void cp_lfvector(float (*to)[3], float (*from)[3], unsigned int verts)
00204 {
00205     memcpy(to, from, verts * sizeof(lfVector));
00206 }
00207 /* init long vector with float[3] */
00208 DO_INLINE void init_lfvector(float (*fLongVector)[3], float vector[3], unsigned int verts)
00209 {
00210     unsigned int i = 0;
00211     for(i = 0; i < verts; i++)
00212     {
00213         VECCOPY(fLongVector[i], vector);
00214     }
00215 }
00216 /* zero long vector with float[3] */
00217 DO_INLINE void zero_lfvector(float (*to)[3], unsigned int verts)
00218 {
00219     memset(to, 0.0f, verts * sizeof(lfVector));
00220 }
00221 /* multiply long vector with scalar*/
00222 DO_INLINE void mul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, unsigned int verts)
00223 {
00224     unsigned int i = 0;
00225 
00226     for(i = 0; i < verts; i++)
00227     {
00228         mul_fvector_S(to[i], fLongVector[i], scalar);
00229     }
00230 }
00231 /* multiply long vector with scalar*/
00232 /* A -= B * float */
00233 DO_INLINE void submul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, unsigned int verts)
00234 {
00235     unsigned int i = 0;
00236     for(i = 0; i < verts; i++)
00237     {
00238         VECSUBMUL(to[i], fLongVector[i], scalar);
00239     }
00240 }
00241 /* dot product for big vector */
00242 DO_INLINE float dot_lfvector(float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts)
00243 {
00244     long i = 0;
00245     float temp = 0.0;
00246 // XXX brecht, disabled this for now (first schedule line was already disabled),
00247 // due to non-commutative nature of floating point ops this makes the sim give
00248 // different results each time you run it!
00249 // schedule(guided, 2)
00250 //#pragma omp parallel for reduction(+: temp) if(verts > CLOTH_OPENMP_LIMIT)
00251     for(i = 0; i < (long)verts; i++)
00252     {
00253         temp += INPR(fLongVectorA[i], fLongVectorB[i]);
00254     }
00255     return temp;
00256 }
00257 /* A = B + C  --> for big vector */
00258 DO_INLINE void add_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts)
00259 {
00260     unsigned int i = 0;
00261 
00262     for(i = 0; i < verts; i++)
00263     {
00264         VECADD(to[i], fLongVectorA[i], fLongVectorB[i]);
00265     }
00266 
00267 }
00268 /* A = B + C * float --> for big vector */
00269 DO_INLINE void add_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, unsigned int verts)
00270 {
00271     unsigned int i = 0;
00272 
00273     for(i = 0; i < verts; i++)
00274     {
00275         VECADDS(to[i], fLongVectorA[i], fLongVectorB[i], bS);
00276 
00277     }
00278 }
00279 /* A = B * float + C * float --> for big vector */
00280 DO_INLINE void add_lfvectorS_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float aS, float (*fLongVectorB)[3], float bS, unsigned int verts)
00281 {
00282     unsigned int i = 0;
00283 
00284     for(i = 0; i < verts; i++)
00285     {
00286         VECADDSS(to[i], fLongVectorA[i], aS, fLongVectorB[i], bS);
00287     }
00288 }
00289 /* A = B - C * float --> for big vector */
00290 DO_INLINE void sub_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, unsigned int verts)
00291 {
00292     unsigned int i = 0;
00293     for(i = 0; i < verts; i++)
00294     {
00295         VECSUBS(to[i], fLongVectorA[i], fLongVectorB[i], bS);
00296     }
00297 
00298 }
00299 /* A = B - C --> for big vector */
00300 DO_INLINE void sub_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts)
00301 {
00302     unsigned int i = 0;
00303 
00304     for(i = 0; i < verts; i++)
00305     {
00306         VECSUB(to[i], fLongVectorA[i], fLongVectorB[i]);
00307     }
00308 
00309 }
00311 // 3x3 matrix
00313 #if 0
00314 /* printf 3x3 matrix on console: for debug output */
00315 static void print_fmatrix(float m3[3][3])
00316 {
00317     printf("%f\t%f\t%f\n",m3[0][0],m3[0][1],m3[0][2]);
00318     printf("%f\t%f\t%f\n",m3[1][0],m3[1][1],m3[1][2]);
00319     printf("%f\t%f\t%f\n\n",m3[2][0],m3[2][1],m3[2][2]);
00320 }
00321 #endif
00322 
00323 /* copy 3x3 matrix */
00324 DO_INLINE void cp_fmatrix(float to[3][3], float from[3][3])
00325 {
00326     // memcpy(to, from, sizeof (float) * 9);
00327     VECCOPY(to[0], from[0]);
00328     VECCOPY(to[1], from[1]);
00329     VECCOPY(to[2], from[2]);
00330 }
00331 
00332 /* copy 3x3 matrix */
00333 DO_INLINE void initdiag_fmatrixS(float to[3][3], float aS)
00334 {
00335     cp_fmatrix(to, ZERO);
00336     
00337     to[0][0] = aS;
00338     to[1][1] = aS;
00339     to[2][2] = aS;
00340 }
00341 
00342 /* calculate determinant of 3x3 matrix */
00343 DO_INLINE float det_fmatrix(float m[3][3])
00344 {
00345     return  m[0][0]*m[1][1]*m[2][2] + m[1][0]*m[2][1]*m[0][2] + m[0][1]*m[1][2]*m[2][0] 
00346             -m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2];
00347 }
00348 
00349 DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3])
00350 {
00351     unsigned int i, j;
00352     float d;
00353 
00354     if((d=det_fmatrix(from))==0)
00355     {
00356         printf("can't build inverse");
00357         exit(0);
00358     }
00359     for(i=0;i<3;i++) 
00360     {
00361         for(j=0;j<3;j++) 
00362         {
00363             int i1=(i+1)%3;
00364             int i2=(i+2)%3;
00365             int j1=(j+1)%3;
00366             int j2=(j+2)%3;
00367             // reverse indexs i&j to take transpose
00368             to[j][i] = (from[i1][j1]*from[i2][j2]-from[i1][j2]*from[i2][j1])/d;
00369             /*
00370             if(i==j)
00371             to[i][j] = 1.0f / from[i][j];
00372             else
00373             to[i][j] = 0;
00374             */
00375         }
00376     }
00377 
00378 }
00379 
00380 /* 3x3 matrix multiplied by a scalar */
00381 /* STATUS: verified */
00382 DO_INLINE void mul_fmatrix_S(float matrix[3][3], float scalar)
00383 {
00384     mul_fvector_S(matrix[0], matrix[0],scalar);
00385     mul_fvector_S(matrix[1], matrix[1],scalar);
00386     mul_fvector_S(matrix[2], matrix[2],scalar);
00387 }
00388 
00389 /* a vector multiplied by a 3x3 matrix */
00390 /* STATUS: verified */
00391 DO_INLINE void mul_fvector_fmatrix(float *to, float *from, float matrix[3][3])
00392 {
00393     to[0] = matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2];
00394     to[1] = matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2];
00395     to[2] = matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2];
00396 }
00397 
00398 /* 3x3 matrix multiplied by a vector */
00399 /* STATUS: verified */
00400 DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][3], float *from)
00401 {
00402     to[0] = INPR(matrix[0],from);
00403     to[1] = INPR(matrix[1],from);
00404     to[2] = INPR(matrix[2],from);
00405 }
00406 /* 3x3 matrix multiplied by a 3x3 matrix */
00407 /* STATUS: verified */
00408 DO_INLINE void mul_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
00409 {
00410     mul_fvector_fmatrix(to[0], matrixA[0],matrixB);
00411     mul_fvector_fmatrix(to[1], matrixA[1],matrixB);
00412     mul_fvector_fmatrix(to[2], matrixA[2],matrixB);
00413 }
00414 /* 3x3 matrix addition with 3x3 matrix */
00415 DO_INLINE void add_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
00416 {
00417     VECADD(to[0], matrixA[0], matrixB[0]);
00418     VECADD(to[1], matrixA[1], matrixB[1]);
00419     VECADD(to[2], matrixA[2], matrixB[2]);
00420 }
00421 /* 3x3 matrix add-addition with 3x3 matrix */
00422 DO_INLINE void addadd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
00423 {
00424     VECADDADD(to[0], matrixA[0], matrixB[0]);
00425     VECADDADD(to[1], matrixA[1], matrixB[1]);
00426     VECADDADD(to[2], matrixA[2], matrixB[2]);
00427 }
00428 /* 3x3 matrix sub-addition with 3x3 matrix */
00429 DO_INLINE void addsub_fmatrixS_fmatrixS(float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS)
00430 {
00431     VECADDSUBSS(to[0], matrixA[0], aS, matrixB[0], bS);
00432     VECADDSUBSS(to[1], matrixA[1], aS, matrixB[1], bS);
00433     VECADDSUBSS(to[2], matrixA[2], aS, matrixB[2], bS);
00434 }
00435 /* A -= B + C (3x3 matrix sub-addition with 3x3 matrix) */
00436 DO_INLINE void subadd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
00437 {
00438     VECSUBADD(to[0], matrixA[0], matrixB[0]);
00439     VECSUBADD(to[1], matrixA[1], matrixB[1]);
00440     VECSUBADD(to[2], matrixA[2], matrixB[2]);
00441 }
00442 /* A -= B*x + C*y (3x3 matrix sub-addition with 3x3 matrix) */
00443 DO_INLINE void subadd_fmatrixS_fmatrixS(float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS)
00444 {
00445     VECSUBADDSS(to[0], matrixA[0], aS, matrixB[0], bS);
00446     VECSUBADDSS(to[1], matrixA[1], aS, matrixB[1], bS);
00447     VECSUBADDSS(to[2], matrixA[2], aS, matrixB[2], bS);
00448 }
00449 /* A = B - C (3x3 matrix subtraction with 3x3 matrix) */
00450 DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
00451 {
00452     VECSUB(to[0], matrixA[0], matrixB[0]);
00453     VECSUB(to[1], matrixA[1], matrixB[1]);
00454     VECSUB(to[2], matrixA[2], matrixB[2]);
00455 }
00456 /* A += B - C (3x3 matrix add-subtraction with 3x3 matrix) */
00457 DO_INLINE void addsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
00458 {
00459     VECADDSUB(to[0], matrixA[0], matrixB[0]);
00460     VECADDSUB(to[1], matrixA[1], matrixB[1]);
00461     VECADDSUB(to[2], matrixA[2], matrixB[2]);
00462 }
00464 // special functions
00466 /* a vector multiplied and added to/by a 3x3 matrix */
00467 DO_INLINE void muladd_fvector_fmatrix(float to[3], float from[3], float matrix[3][3])
00468 {
00469     to[0] += matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2];
00470     to[1] += matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2];
00471     to[2] += matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2];
00472 }
00473 /* 3x3 matrix multiplied and added  to/by a 3x3 matrix  and added to another 3x3 matrix */
00474 DO_INLINE void muladd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
00475 {
00476     muladd_fvector_fmatrix(to[0], matrixA[0],matrixB);
00477     muladd_fvector_fmatrix(to[1], matrixA[1],matrixB);
00478     muladd_fvector_fmatrix(to[2], matrixA[2],matrixB);
00479 }
00480 /* a vector multiplied and sub'd to/by a 3x3 matrix */
00481 DO_INLINE void mulsub_fvector_fmatrix(float to[3], float from[3], float matrix[3][3])
00482 {
00483     to[0] -= matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2];
00484     to[1] -= matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2];
00485     to[2] -= matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2];
00486 }
00487 /* 3x3 matrix multiplied and sub'd  to/by a 3x3 matrix  and added to another 3x3 matrix */
00488 DO_INLINE void mulsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
00489 {
00490     mulsub_fvector_fmatrix(to[0], matrixA[0],matrixB);
00491     mulsub_fvector_fmatrix(to[1], matrixA[1],matrixB);
00492     mulsub_fvector_fmatrix(to[2], matrixA[2],matrixB);
00493 }
00494 /* 3x3 matrix multiplied+added by a vector */
00495 /* STATUS: verified */
00496 DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][3], float from[3])
00497 {
00498     to[0] += INPR(matrix[0],from);
00499     to[1] += INPR(matrix[1],from);
00500     to[2] += INPR(matrix[2],from);  
00501 }
00502 /* 3x3 matrix multiplied+sub'ed by a vector */
00503 DO_INLINE void mulsub_fmatrix_fvector(float to[3], float matrix[3][3], float from[3])
00504 {
00505     to[0] -= INPR(matrix[0],from);
00506     to[1] -= INPR(matrix[1],from);
00507     to[2] -= INPR(matrix[2],from);
00508 }
00510 
00512 // SPARSE SYMMETRIC big matrix with 3x3 matrix entries
00514 /* printf a big matrix on console: for debug output */
00515 #if 0
00516 static void print_bfmatrix(fmatrix3x3 *m3)
00517 {
00518     unsigned int i = 0;
00519 
00520     for(i = 0; i < m3[0].vcount + m3[0].scount; i++)
00521     {
00522         print_fmatrix(m3[i].m);
00523     }
00524 }
00525 #endif
00526 
00527 /* create big matrix */
00528 DO_INLINE fmatrix3x3 *create_bfmatrix(unsigned int verts, unsigned int springs)
00529 {
00530     // TODO: check if memory allocation was successfull */
00531     fmatrix3x3 *temp = (fmatrix3x3 *)MEM_callocN (sizeof (fmatrix3x3) * (verts + springs), "cloth_implicit_alloc_matrix");
00532     temp[0].vcount = verts;
00533     temp[0].scount = springs;
00534     return temp;
00535 }
00536 /* delete big matrix */
00537 DO_INLINE void del_bfmatrix(fmatrix3x3 *matrix)
00538 {
00539     if (matrix != NULL)
00540     {
00541         MEM_freeN (matrix);
00542     }
00543 }
00544 
00545 /* copy big matrix */
00546 DO_INLINE void cp_bfmatrix(fmatrix3x3 *to, fmatrix3x3 *from)
00547 {   
00548     // TODO bounds checking 
00549     memcpy(to, from, sizeof(fmatrix3x3) * (from[0].vcount+from[0].scount) );
00550 }
00551 
00552 /* init big matrix */
00553 // slow in parallel
00554 DO_INLINE void init_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
00555 {
00556     unsigned int i;
00557 
00558     for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++)
00559     {       
00560         cp_fmatrix(matrix[i].m, m3); 
00561     }
00562 }
00563 
00564 /* init the diagonal of big matrix */
00565 // slow in parallel
00566 DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
00567 {
00568     unsigned int i,j;
00569     float tmatrix[3][3] = {{0,0,0},{0,0,0},{0,0,0}};
00570 
00571     for(i = 0; i < matrix[0].vcount; i++)
00572     {       
00573         cp_fmatrix(matrix[i].m, m3); 
00574     }
00575     for(j = matrix[0].vcount; j < matrix[0].vcount+matrix[0].scount; j++)
00576     {
00577         cp_fmatrix(matrix[j].m, tmatrix); 
00578     }
00579 }
00580 
00581 /* multiply big matrix with scalar*/
00582 DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar)
00583 {
00584     unsigned int i = 0;
00585     for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++)
00586     {
00587         mul_fmatrix_S(matrix[i].m, scalar);
00588     }
00589 }
00590 
00591 /* SPARSE SYMMETRIC multiply big matrix with long vector*/
00592 /* STATUS: verified */
00593 DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
00594 {
00595     unsigned int i = 0;
00596     unsigned int vcount = from[0].vcount;
00597     lfVector *temp = create_lfvector(vcount);
00598     
00599     zero_lfvector(to, vcount);
00600 
00601 #pragma omp parallel sections private(i) if(vcount > CLOTH_OPENMP_LIMIT)
00602     {
00603 #pragma omp section
00604         {
00605             for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++)
00606             {
00607                 muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]);
00608             }
00609         }   
00610 #pragma omp section
00611         {
00612             for(i = 0; i < from[0].vcount+from[0].scount; i++)
00613             {
00614                 muladd_fmatrix_fvector(temp[from[i].r], from[i].m, fLongVector[from[i].c]);
00615             }
00616         }
00617     }
00618     add_lfvector_lfvector(to, to, temp, from[0].vcount);
00619     
00620     del_lfvector(temp);
00621     
00622     
00623 }
00624 
00625 /* SPARSE SYMMETRIC multiply big matrix with long vector (for diagonal preconditioner) */
00626 /* STATUS: verified */
00627 DO_INLINE void mul_prevfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
00628 {
00629     unsigned int i = 0;
00630     
00631     for(i = 0; i < from[0].vcount; i++)
00632     {
00633         mul_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]);
00634     }
00635 }
00636 
00637 /* SPARSE SYMMETRIC add big matrix with big matrix: A = B + C*/
00638 DO_INLINE void add_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from,  fmatrix3x3 *matrix)
00639 {
00640     unsigned int i = 0;
00641 
00642     /* process diagonal elements */
00643     for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++)
00644     {
00645         add_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);   
00646     }
00647 
00648 }
00649 /* SPARSE SYMMETRIC add big matrix with big matrix: A += B + C */
00650 DO_INLINE void addadd_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from,  fmatrix3x3 *matrix)
00651 {
00652     unsigned int i = 0;
00653 
00654     /* process diagonal elements */
00655     for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++)
00656     {
00657         addadd_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);    
00658     }
00659 
00660 }
00661 /* SPARSE SYMMETRIC subadd big matrix with big matrix: A -= B + C */
00662 DO_INLINE void subadd_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from,  fmatrix3x3 *matrix)
00663 {
00664     unsigned int i = 0;
00665 
00666     /* process diagonal elements */
00667     for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++)
00668     {
00669         subadd_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);    
00670     }
00671 
00672 }
00673 /*  A = B - C (SPARSE SYMMETRIC sub big matrix with big matrix) */
00674 DO_INLINE void sub_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from,  fmatrix3x3 *matrix)
00675 {
00676     unsigned int i = 0;
00677 
00678     /* process diagonal elements */
00679     for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++)
00680     {
00681         sub_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);   
00682     }
00683 
00684 }
00685 /* SPARSE SYMMETRIC sub big matrix with big matrix S (special constraint matrix with limited entries) */
00686 DO_INLINE void sub_bfmatrix_Smatrix( fmatrix3x3 *to, fmatrix3x3 *from,  fmatrix3x3 *matrix)
00687 {
00688     unsigned int i = 0;
00689 
00690     /* process diagonal elements */
00691     for(i = 0; i < matrix[0].vcount; i++)
00692     {
00693         sub_fmatrix_fmatrix(to[matrix[i].c].m, from[matrix[i].c].m, matrix[i].m);   
00694     }
00695 
00696 }
00697 /* A += B - C (SPARSE SYMMETRIC addsub big matrix with big matrix) */
00698 DO_INLINE void addsub_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from,  fmatrix3x3 *matrix)
00699 {
00700     unsigned int i = 0;
00701 
00702     /* process diagonal elements */
00703     for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++)
00704     {
00705         addsub_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);    
00706     }
00707 
00708 }
00709 /* SPARSE SYMMETRIC sub big matrix with big matrix*/
00710 /* A -= B * float + C * float --> for big matrix */
00711 /* VERIFIED */
00712 DO_INLINE void subadd_bfmatrixS_bfmatrixS( fmatrix3x3 *to, fmatrix3x3 *from, float aS,  fmatrix3x3 *matrix, float bS)
00713 {
00714     unsigned int i = 0;
00715 
00716     /* process diagonal elements */
00717     for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++)
00718     {
00719         subadd_fmatrixS_fmatrixS(to[i].m, from[i].m, aS, matrix[i].m, bS);  
00720     }
00721 
00722 }
00723 
00725 // simulator start
00727 typedef struct Implicit_Data 
00728 {
00729     lfVector *X, *V, *Xnew, *Vnew, *olddV, *F, *B, *dV, *z;
00730     fmatrix3x3 *A, *dFdV, *dFdX, *S, *P, *Pinv, *bigI, *M; 
00731 } Implicit_Data;
00732 
00733 int implicit_init (Object *UNUSED(ob), ClothModifierData *clmd)
00734 {
00735     unsigned int i = 0;
00736     unsigned int pinned = 0;
00737     Cloth *cloth = NULL;
00738     ClothVertex *verts = NULL;
00739     ClothSpring *spring = NULL;
00740     Implicit_Data *id = NULL;
00741     LinkNode *search = NULL;
00742     
00743     if(G.rt > 0)
00744         printf("implicit_init\n");
00745 
00746     // init memory guard
00747     // MEMORY_BASE.first = MEMORY_BASE.last = NULL;
00748 
00749     cloth = (Cloth *)clmd->clothObject;
00750     verts = cloth->verts;
00751 
00752     // create implicit base
00753     id = (Implicit_Data *)MEM_callocN (sizeof(Implicit_Data), "implicit vecmat");
00754     cloth->implicit = id;
00755 
00756     /* process diagonal elements */     
00757     id->A = create_bfmatrix(cloth->numverts, cloth->numsprings);
00758     id->dFdV = create_bfmatrix(cloth->numverts, cloth->numsprings);
00759     id->dFdX = create_bfmatrix(cloth->numverts, cloth->numsprings);
00760     id->S = create_bfmatrix(cloth->numverts, 0);
00761     id->Pinv = create_bfmatrix(cloth->numverts, cloth->numsprings);
00762     id->P = create_bfmatrix(cloth->numverts, cloth->numsprings);
00763     id->bigI = create_bfmatrix(cloth->numverts, cloth->numsprings); // TODO 0 springs
00764     id->M = create_bfmatrix(cloth->numverts, cloth->numsprings);
00765     id->X = create_lfvector(cloth->numverts);
00766     id->Xnew = create_lfvector(cloth->numverts);
00767     id->V = create_lfvector(cloth->numverts);
00768     id->Vnew = create_lfvector(cloth->numverts);
00769     id->olddV = create_lfvector(cloth->numverts);
00770     zero_lfvector(id->olddV, cloth->numverts);
00771     id->F = create_lfvector(cloth->numverts);
00772     id->B = create_lfvector(cloth->numverts);
00773     id->dV = create_lfvector(cloth->numverts);
00774     id->z = create_lfvector(cloth->numverts);
00775     
00776     for(i=0;i<cloth->numverts;i++) 
00777     {
00778         id->A[i].r = id->A[i].c = id->dFdV[i].r = id->dFdV[i].c = id->dFdX[i].r = id->dFdX[i].c = id->P[i].c = id->P[i].r = id->Pinv[i].c = id->Pinv[i].r = id->bigI[i].c = id->bigI[i].r = id->M[i].r = id->M[i].c = i;
00779 
00780         if(verts [i].flags & CLOTH_VERT_FLAG_PINNED)
00781         {
00782             id->S[pinned].pinned = 1;
00783             id->S[pinned].c = id->S[pinned].r = i;
00784             pinned++;
00785         }
00786         
00787         initdiag_fmatrixS(id->M[i].m, verts[i].mass);
00788     }
00789 
00790     // S is special and needs specific vcount and scount
00791     id->S[0].vcount = pinned; id->S[0].scount = 0;
00792 
00793     // init springs 
00794     search = cloth->springs;
00795     for(i=0;i<cloth->numsprings;i++) 
00796     {
00797         spring = search->link;
00798         
00799         // dFdV_start[i].r = big_I[i].r = big_zero[i].r = 
00800         id->A[i+cloth->numverts].r = id->dFdV[i+cloth->numverts].r = id->dFdX[i+cloth->numverts].r = 
00801                 id->P[i+cloth->numverts].r = id->Pinv[i+cloth->numverts].r = id->bigI[i+cloth->numverts].r = id->M[i+cloth->numverts].r = spring->ij;
00802 
00803         // dFdV_start[i].c = big_I[i].c = big_zero[i].c = 
00804         id->A[i+cloth->numverts].c = id->dFdV[i+cloth->numverts].c = id->dFdX[i+cloth->numverts].c = 
00805                 id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = id->M[i+cloth->numverts].c = spring->kl;
00806 
00807         spring->matrix_index = i + cloth->numverts;
00808         
00809         search = search->next;
00810     }
00811     
00812     initdiag_bfmatrix(id->bigI, I);
00813 
00814     for(i = 0; i < cloth->numverts; i++)
00815     {       
00816         VECCOPY(id->X[i], verts[i].x);
00817     }
00818 
00819     return 1;
00820 }
00821 int implicit_free (ClothModifierData *clmd)
00822 {
00823     Implicit_Data *id;
00824     Cloth *cloth;
00825     cloth = (Cloth *)clmd->clothObject;
00826 
00827     if(cloth)
00828     {
00829         id = cloth->implicit;
00830 
00831         if(id)
00832         {
00833             del_bfmatrix(id->A);
00834             del_bfmatrix(id->dFdV);
00835             del_bfmatrix(id->dFdX);
00836             del_bfmatrix(id->S);
00837             del_bfmatrix(id->P);
00838             del_bfmatrix(id->Pinv);
00839             del_bfmatrix(id->bigI);
00840             del_bfmatrix(id->M);
00841 
00842             del_lfvector(id->X);
00843             del_lfvector(id->Xnew);
00844             del_lfvector(id->V);
00845             del_lfvector(id->Vnew);
00846             del_lfvector(id->olddV);
00847             del_lfvector(id->F);
00848             del_lfvector(id->B);
00849             del_lfvector(id->dV);
00850             del_lfvector(id->z);
00851 
00852             MEM_freeN(id);
00853         }
00854     }
00855 
00856     return 1;
00857 }
00858 
00859 DO_INLINE float fb(float length, float L)
00860 {
00861     float x = length/L;
00862     return (-11.541f*pow(x,4)+34.193f*pow(x,3)-39.083f*pow(x,2)+23.116f*x-9.713f);
00863 }
00864 
00865 DO_INLINE float fbderiv(float length, float L)
00866 {
00867     float x = length/L;
00868 
00869     return (-46.164f*pow(x,3)+102.579f*pow(x,2)-78.166f*x+23.116f);
00870 }
00871 
00872 DO_INLINE float fbstar(float length, float L, float kb, float cb)
00873 {
00874     float tempfb = kb * fb(length, L);
00875 
00876     float fbstar = cb * (length - L);
00877     
00878     if(tempfb < fbstar)
00879         return fbstar;
00880     else
00881         return tempfb;      
00882 }
00883 
00884 // function to calculae bending spring force (taken from Choi & Co)
00885 DO_INLINE float fbstar_jacobi(float length, float L, float kb, float cb)
00886 {
00887     float tempfb = kb * fb(length, L);
00888     float fbstar = cb * (length - L);
00889 
00890     if(tempfb < fbstar)
00891     {       
00892         return cb;
00893     }
00894     else
00895     {
00896         return kb * fbderiv(length, L); 
00897     }   
00898 }
00899 
00900 DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
00901 {
00902     unsigned int i=0;
00903 
00904     for(i=0;i<S[0].vcount;i++)
00905     {
00906         mul_fvector_fmatrix(V[S[i].r], V[S[i].r], S[i].m);
00907     }
00908 }
00909 
00910 static int  cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S)
00911 {
00912     // Solves for unknown X in equation AX=B
00913     unsigned int conjgrad_loopcount=0, conjgrad_looplimit=100;
00914     float conjgrad_epsilon=0.0001f /* , conjgrad_lasterror=0 */ /* UNUSED */;
00915     lfVector *q, *d, *tmp, *r; 
00916     float s, starget, a, s_prev;
00917     unsigned int numverts = lA[0].vcount;
00918     q = create_lfvector(numverts);
00919     d = create_lfvector(numverts);
00920     tmp = create_lfvector(numverts);
00921     r = create_lfvector(numverts);
00922 
00923     // zero_lfvector(ldV, CLOTHPARTICLES);
00924     filter(ldV, S);
00925 
00926     add_lfvector_lfvector(ldV, ldV, z, numverts);
00927 
00928     // r = B - Mul(tmp,A,X);    // just use B if X known to be zero
00929     cp_lfvector(r, lB, numverts);
00930     mul_bfmatrix_lfvector(tmp, lA, ldV);
00931     sub_lfvector_lfvector(r, r, tmp, numverts);
00932 
00933     filter(r,S);
00934 
00935     cp_lfvector(d, r, numverts);
00936 
00937     s = dot_lfvector(r, r, numverts);
00938     starget = s * sqrt(conjgrad_epsilon);
00939 
00940     while(s>starget && conjgrad_loopcount < conjgrad_looplimit)
00941     {   
00942         // Mul(q,A,d); // q = A*d;
00943         mul_bfmatrix_lfvector(q, lA, d);
00944 
00945         filter(q,S);
00946 
00947         a = s/dot_lfvector(d, q, numverts);
00948 
00949         // X = X + d*a;
00950         add_lfvector_lfvectorS(ldV, ldV, d, a, numverts);
00951 
00952         // r = r - q*a;
00953         sub_lfvector_lfvectorS(r, r, q, a, numverts);
00954 
00955         s_prev = s;
00956         s = dot_lfvector(r, r, numverts);
00957 
00958         //d = r+d*(s/s_prev);
00959         add_lfvector_lfvectorS(d, r, d, (s/s_prev), numverts);
00960 
00961         filter(d,S);
00962 
00963         conjgrad_loopcount++;
00964     }
00965     /* conjgrad_lasterror = s; */ /* UNUSED */
00966 
00967     del_lfvector(q);
00968     del_lfvector(d);
00969     del_lfvector(tmp);
00970     del_lfvector(r);
00971     // printf("W/O conjgrad_loopcount: %d\n", conjgrad_loopcount);
00972 
00973     return conjgrad_loopcount<conjgrad_looplimit;  // true means we reached desired accuracy in given time - ie stable
00974 }
00975 
00976 // block diagonalizer
00977 DO_INLINE void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv)
00978 {
00979     unsigned int i = 0;
00980     
00981     // Take only the diagonal blocks of A
00982 // #pragma omp parallel for private(i) if(lA[0].vcount > CLOTH_OPENMP_LIMIT)
00983     for(i = 0; i<lA[0].vcount; i++)
00984     {
00985         // block diagonalizer
00986         cp_fmatrix(P[i].m, lA[i].m);
00987         inverse_fmatrix(Pinv[i].m, P[i].m);
00988         
00989     }
00990 }
00991 #if 0
00992 /*
00993 // version 1.3
00994 static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv)
00995 {
00996     unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit=100;
00997     float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0;
00998     float conjgrad_epsilon=0.0001; // 0.2 is dt for steps=5
00999     lfVector *r = create_lfvector(numverts);
01000     lfVector *p = create_lfvector(numverts);
01001     lfVector *s = create_lfvector(numverts);
01002     lfVector *h = create_lfvector(numverts);
01003     
01004     BuildPPinv(lA, P, Pinv);
01005     
01006     filter(dv, S);
01007     add_lfvector_lfvector(dv, dv, z, numverts);
01008     
01009     mul_bfmatrix_lfvector(r, lA, dv);
01010     sub_lfvector_lfvector(r, lB, r, numverts);
01011     filter(r, S);
01012     
01013     mul_prevfmatrix_lfvector(p, Pinv, r);
01014     filter(p, S);
01015     
01016     deltaNew = dot_lfvector(r, p, numverts);
01017     
01018     delta0 = deltaNew * sqrt(conjgrad_epsilon);
01019     
01020     // itstart();
01021     
01022     while ((deltaNew > delta0) && (iterations < conjgrad_looplimit))
01023     {
01024         iterations++;
01025         
01026         mul_bfmatrix_lfvector(s, lA, p);
01027         filter(s, S);
01028         
01029         alpha = deltaNew / dot_lfvector(p, s, numverts);
01030         
01031         add_lfvector_lfvectorS(dv, dv, p, alpha, numverts);
01032         
01033         add_lfvector_lfvectorS(r, r, s, -alpha, numverts);
01034         
01035         mul_prevfmatrix_lfvector(h, Pinv, r);
01036         filter(h, S);
01037         
01038         deltaOld = deltaNew;
01039         
01040         deltaNew = dot_lfvector(r, h, numverts);
01041         
01042         add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts);
01043         
01044         filter(p, S);
01045         
01046     }
01047     
01048     // itend();
01049     // printf("cg_filtered_pre time: %f\n", (float)itval());
01050     
01051     del_lfvector(h);
01052     del_lfvector(s);
01053     del_lfvector(p);
01054     del_lfvector(r);
01055     
01056     printf("iterations: %d\n", iterations);
01057     
01058     return iterations<conjgrad_looplimit;
01059 }
01060 */
01061 // version 1.4
01062 static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *bigI)
01063 {
01064     unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit=100;
01065     float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0, tol = 0;
01066     lfVector *r = create_lfvector(numverts);
01067     lfVector *p = create_lfvector(numverts);
01068     lfVector *s = create_lfvector(numverts);
01069     lfVector *h = create_lfvector(numverts);
01070     lfVector *bhat = create_lfvector(numverts);
01071     lfVector *btemp = create_lfvector(numverts);
01072     
01073     BuildPPinv(lA, P, Pinv);
01074     
01075     initdiag_bfmatrix(bigI, I);
01076     sub_bfmatrix_Smatrix(bigI, bigI, S);
01077     
01078     // x = Sx_0+(I-S)z
01079     filter(dv, S);
01080     add_lfvector_lfvector(dv, dv, z, numverts);
01081     
01082     // b_hat = S(b-A(I-S)z)
01083     mul_bfmatrix_lfvector(r, lA, z);
01084     mul_bfmatrix_lfvector(bhat, bigI, r);
01085     sub_lfvector_lfvector(bhat, lB, bhat, numverts);
01086     
01087     // r = S(b-Ax)
01088     mul_bfmatrix_lfvector(r, lA, dv);
01089     sub_lfvector_lfvector(r, lB, r, numverts);
01090     filter(r, S);
01091     
01092     // p = SP^-1r
01093     mul_prevfmatrix_lfvector(p, Pinv, r);
01094     filter(p, S);
01095     
01096     // delta0 = bhat^TP^-1bhat
01097     mul_prevfmatrix_lfvector(btemp, Pinv, bhat);
01098     delta0 = dot_lfvector(bhat, btemp, numverts);
01099     
01100     // deltaNew = r^TP
01101     deltaNew = dot_lfvector(r, p, numverts);
01102     
01103     /*
01104     filter(dv, S);
01105     add_lfvector_lfvector(dv, dv, z, numverts);
01106     
01107     mul_bfmatrix_lfvector(r, lA, dv);
01108     sub_lfvector_lfvector(r, lB, r, numverts);
01109     filter(r, S);
01110     
01111     mul_prevfmatrix_lfvector(p, Pinv, r);
01112     filter(p, S);
01113     
01114     deltaNew = dot_lfvector(r, p, numverts);
01115     
01116     delta0 = deltaNew * sqrt(conjgrad_epsilon);
01117     */
01118     
01119     // itstart();
01120     
01121     tol = (0.01*0.2);
01122     
01123     while ((deltaNew > delta0*tol*tol) && (iterations < conjgrad_looplimit))
01124     {
01125         iterations++;
01126         
01127         mul_bfmatrix_lfvector(s, lA, p);
01128         filter(s, S);
01129         
01130         alpha = deltaNew / dot_lfvector(p, s, numverts);
01131         
01132         add_lfvector_lfvectorS(dv, dv, p, alpha, numverts);
01133         
01134         add_lfvector_lfvectorS(r, r, s, -alpha, numverts);
01135         
01136         mul_prevfmatrix_lfvector(h, Pinv, r);
01137         filter(h, S);
01138         
01139         deltaOld = deltaNew;
01140         
01141         deltaNew = dot_lfvector(r, h, numverts);
01142         
01143         add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts);
01144         
01145         filter(p, S);
01146         
01147     }
01148     
01149     // itend();
01150     // printf("cg_filtered_pre time: %f\n", (float)itval());
01151     
01152     del_lfvector(btemp);
01153     del_lfvector(bhat);
01154     del_lfvector(h);
01155     del_lfvector(s);
01156     del_lfvector(p);
01157     del_lfvector(r);
01158     
01159     // printf("iterations: %d\n", iterations);
01160     
01161     return iterations<conjgrad_looplimit;
01162 }
01163 #endif
01164 
01165 // outer product is NOT cross product!!!
01166 DO_INLINE void dfdx_spring_type1(float to[3][3], float extent[3], float length, float L, float dot, float k)
01167 {
01168     // dir is unit length direction, rest is spring's restlength, k is spring constant.
01169     // return  (outerprod(dir,dir)*k + (I - outerprod(dir,dir))*(k - ((k*L)/length)));
01170     float temp[3][3];
01171     float temp1 = k*(1.0 - (L/length)); 
01172     
01173     mul_fvectorT_fvectorS(temp, extent, extent, 1.0 / dot);
01174     sub_fmatrix_fmatrix(to, I, temp);
01175     mul_fmatrix_S(to, temp1);
01176     
01177     mul_fvectorT_fvectorS(temp, extent, extent, k/ dot);
01178     add_fmatrix_fmatrix(to, to, temp);
01179     
01180     /*
01181     mul_fvectorT_fvector(temp, dir, dir);
01182     sub_fmatrix_fmatrix(to, I, temp);
01183     mul_fmatrix_S(to, k* (1.0f-(L/length)));
01184     mul_fmatrix_S(temp, k);
01185     add_fmatrix_fmatrix(to, temp, to);
01186     */
01187 }
01188 
01189 DO_INLINE void dfdx_spring_type2(float to[3][3], float dir[3], float length, float L, float k, float cb)
01190 {
01191     // return  outerprod(dir,dir)*fbstar_jacobi(length, L, k, cb);
01192     mul_fvectorT_fvectorS(to, dir, dir, fbstar_jacobi(length, L, k, cb));
01193 }
01194 
01195 DO_INLINE void dfdv_damp(float to[3][3], float dir[3], float damping)
01196 {
01197     // derivative of force wrt velocity.  
01198     mul_fvectorT_fvectorS(to, dir, dir, damping);
01199     
01200 }
01201 
01202 DO_INLINE void dfdx_spring(float to[3][3],  float dir[3],float length,float L,float k)
01203 {
01204     // dir is unit length direction, rest is spring's restlength, k is spring constant.
01205     //return  ( (I-outerprod(dir,dir))*Min(1.0f,rest/length) - I) * -k;
01206     mul_fvectorT_fvector(to, dir, dir);
01207     sub_fmatrix_fmatrix(to, I, to);
01208 
01209     mul_fmatrix_S(to, (L/length)); 
01210     sub_fmatrix_fmatrix(to, to, I);
01211     mul_fmatrix_S(to, -k);
01212 }
01213 
01214 // unused atm
01215 DO_INLINE void dfdx_damp(float to[3][3],  float dir[3],float length,const float vel[3],float rest,float damping)
01216 {
01217     // inner spring damping   vel is the relative velocity  of the endpoints.  
01218     //  return (I-outerprod(dir,dir)) * (-damping * -(dot(dir,vel)/Max(length,rest)));
01219     mul_fvectorT_fvector(to, dir, dir);
01220     sub_fmatrix_fmatrix(to, I, to);
01221     mul_fmatrix_S(to,  (-damping * -(INPR(dir,vel)/MAX2(length,rest)))); 
01222 
01223 }
01224 
01225 DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *UNUSED(lF), lfVector *X, lfVector *V, fmatrix3x3 *UNUSED(dFdV), fmatrix3x3 *UNUSED(dFdX), float time)
01226 {
01227     Cloth *cloth = clmd->clothObject;
01228     ClothVertex *verts = cloth->verts;
01229     float extent[3];
01230     float length = 0, dot = 0;
01231     float dir[3] = {0,0,0};
01232     float vel[3];
01233     float k = 0.0f;
01234     float L = s->restlen;
01235     float cb; /* = clmd->sim_parms->structural; */ /*UNUSED*/
01236 
01237     float nullf[3] = {0,0,0};
01238     float stretch_force[3] = {0,0,0};
01239     float bending_force[3] = {0,0,0};
01240     float damping_force[3] = {0,0,0};
01241     float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}};
01242     
01243     float scaling = 0.0;
01244 
01245     int no_compress = clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS;
01246     
01247     VECCOPY(s->f, nullf);
01248     cp_fmatrix(s->dfdx, nulldfdx);
01249     cp_fmatrix(s->dfdv, nulldfdx);
01250 
01251     // calculate elonglation
01252     VECSUB(extent, X[s->kl], X[s->ij]);
01253     VECSUB(vel, V[s->kl], V[s->ij]);
01254     dot = INPR(extent, extent);
01255     length = sqrt(dot);
01256     
01257     s->flags &= ~CLOTH_SPRING_FLAG_NEEDED;
01258     
01259     if(length > ALMOST_ZERO)
01260     {
01261         /*
01262         if(length>L)
01263         {
01264         if((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) 
01265         && ((((length-L)*100.0f/L) > clmd->sim_parms->maxspringlen))) // cut spring!
01266         {
01267         s->flags |= CSPRING_FLAG_DEACTIVATE;
01268         return;
01269     }
01270     } 
01271         */
01272         mul_fvector_S(dir, extent, 1.0f/length);
01273     }
01274     else    
01275     {
01276         mul_fvector_S(dir, extent, 0.0f);
01277     }
01278     
01279     // calculate force of structural + shear springs
01280     if((s->type & CLOTH_SPRING_TYPE_STRUCTURAL) || (s->type & CLOTH_SPRING_TYPE_SHEAR))
01281     {
01282         if(length > L || no_compress)
01283         {
01284             s->flags |= CLOTH_SPRING_FLAG_NEEDED;
01285             
01286             k = clmd->sim_parms->structural;
01287                 
01288             scaling = k + s->stiffness * ABS(clmd->sim_parms->max_struct-k);
01289             
01290             k = scaling / (clmd->sim_parms->avg_spring_len + FLT_EPSILON);
01291             
01292             // TODO: verify, half verified (couldn't see error)
01293             mul_fvector_S(stretch_force, dir, k*(length-L)); 
01294 
01295             VECADD(s->f, s->f, stretch_force);
01296 
01297             // Ascher & Boxman, p.21: Damping only during elonglation
01298             // something wrong with it...
01299             mul_fvector_S(damping_force, dir, clmd->sim_parms->Cdis * INPR(vel,dir));
01300             VECADD(s->f, s->f, damping_force);
01301             
01302             /* VERIFIED */
01303             dfdx_spring(s->dfdx, dir, length, L, k);
01304             
01305             /* VERIFIED */
01306             dfdv_damp(s->dfdv, dir, clmd->sim_parms->Cdis);
01307             
01308         }
01309     }
01310     else if(s->type & CLOTH_SPRING_TYPE_GOAL)
01311     {
01312         float tvect[3];
01313         
01314         s->flags |= CLOTH_SPRING_FLAG_NEEDED;
01315         
01316         // current_position = xold + t * (newposition - xold)
01317         VECSUB(tvect, verts[s->ij].xconst, verts[s->ij].xold);
01318         mul_fvector_S(tvect, tvect, time);
01319         VECADD(tvect, tvect, verts[s->ij].xold);
01320 
01321         VECSUB(extent, X[s->ij], tvect);
01322         
01323         // SEE MSG BELOW (these are UNUSED)
01324         // dot = INPR(extent, extent);
01325         // length = sqrt(dot);
01326         
01327         k = clmd->sim_parms->goalspring;
01328         
01329         scaling = k + s->stiffness * ABS(clmd->sim_parms->max_struct-k);
01330             
01331         k = verts [s->ij].goal * scaling / (clmd->sim_parms->avg_spring_len + FLT_EPSILON);
01332         
01333         VECADDS(s->f, s->f, extent, -k);
01334         
01335         mul_fvector_S(damping_force, dir, clmd->sim_parms->goalfrict * 0.01 * INPR(vel,dir));
01336         VECADD(s->f, s->f, damping_force);
01337         
01338         // HERE IS THE PROBLEM!!!!
01339         // dfdx_spring(s->dfdx, dir, length, 0.0, k);
01340         // dfdv_damp(s->dfdv, dir, MIN2(1.0, (clmd->sim_parms->goalfrict/100.0)));
01341     }
01342     else // calculate force of bending springs
01343     {
01344         if(length < L)
01345         {
01346             s->flags |= CLOTH_SPRING_FLAG_NEEDED;
01347             
01348             k = clmd->sim_parms->bending;   
01349             
01350             scaling = k + s->stiffness * ABS(clmd->sim_parms->max_bend-k);          
01351             cb = k = scaling / (20.0*(clmd->sim_parms->avg_spring_len + FLT_EPSILON));
01352 
01353             mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb));
01354             VECADD(s->f, s->f, bending_force);
01355 
01356             dfdx_spring_type2(s->dfdx, dir, length,L, k, cb);
01357         }
01358     }
01359 }
01360 
01361 DO_INLINE void cloth_apply_spring_force(ClothModifierData *UNUSED(clmd), ClothSpring *s, lfVector *lF, lfVector *UNUSED(X), lfVector *UNUSED(V), fmatrix3x3 *dFdV, fmatrix3x3 *dFdX)
01362 {
01363     if(s->flags & CLOTH_SPRING_FLAG_NEEDED)
01364     {
01365         if(!(s->type & CLOTH_SPRING_TYPE_BENDING))
01366         {
01367             sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, s->dfdv);
01368             sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv);
01369             add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv); 
01370         }
01371 
01372         VECADD(lF[s->ij], lF[s->ij], s->f);
01373         
01374         if(!(s->type & CLOTH_SPRING_TYPE_GOAL))
01375             VECSUB(lF[s->kl], lF[s->kl], s->f);
01376         
01377         sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, s->dfdx);
01378         sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx);
01379         add_fmatrix_fmatrix(dFdX[s->matrix_index].m, dFdX[s->matrix_index].m, s->dfdx);
01380     }   
01381 }
01382 
01383 
01384 static void CalcFloat( float *v1, float *v2, float *v3, float *n)
01385 {
01386     float n1[3],n2[3];
01387 
01388     n1[0]= v1[0]-v2[0];
01389     n2[0]= v2[0]-v3[0];
01390     n1[1]= v1[1]-v2[1];
01391     n2[1]= v2[1]-v3[1];
01392     n1[2]= v1[2]-v2[2];
01393     n2[2]= v2[2]-v3[2];
01394     n[0]= n1[1]*n2[2]-n1[2]*n2[1];
01395     n[1]= n1[2]*n2[0]-n1[0]*n2[2];
01396     n[2]= n1[0]*n2[1]-n1[1]*n2[0];
01397 }
01398 
01399 static void CalcFloat4( float *v1, float *v2, float *v3, float *v4, float *n)
01400 {
01401     /* real cross! */
01402     float n1[3],n2[3];
01403 
01404     n1[0]= v1[0]-v3[0];
01405     n1[1]= v1[1]-v3[1];
01406     n1[2]= v1[2]-v3[2];
01407 
01408     n2[0]= v2[0]-v4[0];
01409     n2[1]= v2[1]-v4[1];
01410     n2[2]= v2[2]-v4[2];
01411 
01412     n[0]= n1[1]*n2[2]-n1[2]*n2[1];
01413     n[1]= n1[2]*n2[0]-n1[0]*n2[2];
01414     n[2]= n1[0]*n2[1]-n1[1]*n2[0];
01415 }
01416 
01417 static float calculateVertexWindForce(float wind[3], float vertexnormal[3])  
01418 {
01419     return (INPR(wind, vertexnormal));
01420 }
01421 
01422 typedef struct HairGridVert {
01423     float velocity[3];
01424     float density;
01425 } HairGridVert;
01426 #define HAIR_GRID_INDEX(vec, min, max, axis) (int)( (vec[axis] - min[axis]) / (max[axis] - min[axis]) * 9.99f );
01427 /* Smoothing of hair velocities:
01428  * adapted from
01429         Volumetric Methods for Simulation and Rendering of Hair
01430         by Lena Petrovic, Mark Henne and John Anderson
01431  *      Pixar Technical Memo #06-08, Pixar Animation Studios
01432  */
01433 static void hair_velocity_smoothing(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, unsigned int numverts)
01434 {
01435     /* TODO: This is an initial implementation and should be made much better in due time.
01436      * What should at least be implemented is a grid size parameter and a smoothing kernel
01437      * for bigger grids.
01438      */
01439 
01440     /* 10x10x10 grid gives nice initial results */
01441     HairGridVert grid[10][10][10];
01442     HairGridVert colg[10][10][10];
01443     ListBase *colliders = get_collider_cache(clmd->scene, NULL, NULL);
01444     ColliderCache *col = NULL;
01445     float gmin[3], gmax[3], density;
01446     /* 2.0f is an experimental value that seems to give good results */
01447     float smoothfac = 2.0f * clmd->sim_parms->velocity_smooth;
01448     float collfac = 2.0f * clmd->sim_parms->collider_friction;
01449     unsigned int    v = 0;
01450     unsigned int    i = 0;
01451     int             j = 0;
01452     int             k = 0;
01453 
01454     INIT_MINMAX(gmin, gmax);
01455 
01456     for(i = 0; i < numverts; i++)
01457         DO_MINMAX(lX[i], gmin, gmax);
01458 
01459     /* initialize grid */
01460     for(i = 0; i < 10; i++) {
01461         for(j = 0; j < 10; j++) {
01462             for(k = 0; k < 10; k++) {
01463                 grid[i][j][k].velocity[0] = 0.0f;
01464                 grid[i][j][k].velocity[1] = 0.0f;
01465                 grid[i][j][k].velocity[2] = 0.0f;
01466                 grid[i][j][k].density = 0.0f;
01467 
01468                 colg[i][j][k].velocity[0] = 0.0f;
01469                 colg[i][j][k].velocity[1] = 0.0f;
01470                 colg[i][j][k].velocity[2] = 0.0f;
01471                 colg[i][j][k].density = 0.0f;
01472             }
01473         }
01474     }
01475 
01476     /* gather velocities & density */
01477     if(smoothfac > 0.0f) for(v = 0; v < numverts; v++) {
01478         i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0);
01479         j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1);
01480         k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2);
01481         if (i < 0 || j < 0 || k < 0 || i > 10 || j >= 10 || k >= 10)
01482             continue;
01483 
01484         grid[i][j][k].velocity[0] += lV[v][0];
01485         grid[i][j][k].velocity[1] += lV[v][1];
01486         grid[i][j][k].velocity[2] += lV[v][2];
01487         grid[i][j][k].density += 1.0f;
01488     }
01489 
01490     /* gather colliders */
01491     if(colliders && collfac > 0.0f) for(col = colliders->first; col; col = col->next)
01492     {
01493         MVert *loc0 = col->collmd->x;
01494         MVert *loc1 = col->collmd->xnew;
01495         float vel[3];
01496 
01497         for(v=0; v<col->collmd->numverts; v++, loc0++, loc1++) {
01498             i = HAIR_GRID_INDEX(loc1->co, gmin, gmax, 0);
01499 
01500             if(i>=0 && i<10) {
01501                 j = HAIR_GRID_INDEX(loc1->co, gmin, gmax, 1);
01502 
01503                 if(j>=0 && j<10) {
01504                     k = HAIR_GRID_INDEX(loc1->co, gmin, gmax, 2);
01505 
01506                     if(k>=0 && k<10) {
01507                         VECSUB(vel, loc1->co, loc0->co);
01508 
01509                         colg[i][j][k].velocity[0] += vel[0];
01510                         colg[i][j][k].velocity[1] += vel[1];
01511                         colg[i][j][k].velocity[2] += vel[2];
01512                         colg[i][j][k].density += 1.0;
01513                     }
01514                 }
01515             }
01516         }
01517     }
01518     
01519 
01520     /* divide velocity with density */
01521     for(i = 0; i < 10; i++) {
01522         for(j = 0; j < 10; j++) {
01523             for(k = 0; k < 10; k++) {
01524                 density = grid[i][j][k].density;
01525                 if(density > 0.0f) {
01526                     grid[i][j][k].velocity[0] /= density;
01527                     grid[i][j][k].velocity[1] /= density;
01528                     grid[i][j][k].velocity[2] /= density;
01529                 }
01530 
01531                 density = colg[i][j][k].density;
01532                 if(density > 0.0f) {
01533                     colg[i][j][k].velocity[0] /= density;
01534                     colg[i][j][k].velocity[1] /= density;
01535                     colg[i][j][k].velocity[2] /= density;
01536                 }
01537             }
01538         }
01539     }
01540 
01541     /* calculate forces */
01542     for(v = 0; v < numverts; v++) {
01543         i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0);
01544         j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1);
01545         k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2);
01546         if (i < 0 || j < 0 || k < 0 || i > 10 || j >= 10 || k >= 10)
01547             continue;
01548 
01549         lF[v][0] += smoothfac * (grid[i][j][k].velocity[0] - lV[v][0]);
01550         lF[v][1] += smoothfac * (grid[i][j][k].velocity[1] - lV[v][1]);
01551         lF[v][2] += smoothfac * (grid[i][j][k].velocity[2] - lV[v][2]);
01552 
01553         if(colg[i][j][k].density > 0.0f) {
01554             lF[v][0] += collfac * (colg[i][j][k].velocity[0] - lV[v][0]);
01555             lF[v][1] += collfac * (colg[i][j][k].velocity[1] - lV[v][1]);
01556             lF[v][2] += collfac * (colg[i][j][k].velocity[2] - lV[v][2]);
01557         }
01558     }
01559 
01560     free_collider_cache(&colliders);
01561 }
01562 
01563 static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time, fmatrix3x3 *M)
01564 {
01565     /* Collect forces and derivatives:  F,dFdX,dFdV */
01566     Cloth       *cloth      = clmd->clothObject;
01567     unsigned int i  = 0;
01568     float       spring_air  = clmd->sim_parms->Cvi * 0.01f; /* viscosity of air scaled in percent */
01569     float       gravity[3] = {0.0f, 0.0f, 0.0f};
01570     float       tm2[3][3]   = {{0}};
01571     MFace       *mfaces     = cloth->mfaces;
01572     unsigned int numverts = cloth->numverts;
01573     LinkNode *search;
01574     lfVector *winvec;
01575     EffectedPoint epoint;
01576 
01577     tm2[0][0]= tm2[1][1]= tm2[2][2]= -spring_air;
01578     
01579     /* global acceleration (gravitation) */
01580     if(clmd->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
01581         VECCOPY(gravity, clmd->scene->physics_settings.gravity);
01582         mul_fvector_S(gravity, gravity, 0.001f * clmd->sim_parms->effector_weights->global_gravity); /* scale gravity force */
01583     }
01584 
01585     /* set dFdX jacobi matrix to zero */
01586     init_bfmatrix(dFdX, ZERO);
01587     /* set dFdX jacobi matrix diagonal entries to -spring_air */ 
01588     initdiag_bfmatrix(dFdV, tm2);
01589 
01590     init_lfvector(lF, gravity, numverts);
01591     
01592     if(clmd->sim_parms->velocity_smooth > 0.0f || clmd->sim_parms->collider_friction > 0.0f)
01593         hair_velocity_smoothing(clmd, lF, lX, lV, numverts);
01594 
01595     /* multiply lF with mass matrix
01596     // force = mass * acceleration (in this case: gravity)
01597     */
01598     for(i = 0; i < numverts; i++)
01599     {
01600         float temp[3];
01601         VECCOPY(temp, lF[i]);
01602         mul_fmatrix_fvector(lF[i], M[i].m, temp);
01603     }
01604 
01605     submul_lfvectorS(lF, lV, spring_air, numverts);
01606     
01607     /* handle external forces like wind */
01608     if(effectors)
01609     {   
01610         // 0 = force, 1 = normalized force
01611         winvec = create_lfvector(cloth->numverts);
01612         
01613         if(!winvec)
01614             printf("winvec: out of memory in implicit.c\n");
01615         
01616         // precalculate wind forces
01617         for(i = 0; i < cloth->numverts; i++)
01618         {   
01619             pd_point_from_loc(clmd->scene, (float*)lX[i], (float*)lV[i], i, &epoint);
01620             pdDoEffectors(effectors, NULL, clmd->sim_parms->effector_weights, &epoint, winvec[i], NULL);
01621         }
01622         
01623         for(i = 0; i < cloth->numfaces; i++)
01624         {
01625             float trinormal[3]={0,0,0}; // normalized triangle normal
01626             float triunnormal[3]={0,0,0}; // not-normalized-triangle normal
01627             float tmp[3]={0,0,0};
01628             float factor = (mfaces[i].v4) ? 0.25 : 1.0 / 3.0;
01629             factor *= 0.02;
01630             
01631             // calculate face normal
01632             if(mfaces[i].v4)
01633                 CalcFloat4(lX[mfaces[i].v1],lX[mfaces[i].v2],lX[mfaces[i].v3],lX[mfaces[i].v4],triunnormal);
01634             else
01635                 CalcFloat(lX[mfaces[i].v1],lX[mfaces[i].v2],lX[mfaces[i].v3],triunnormal);
01636 
01637             normalize_v3_v3(trinormal, triunnormal);
01638             
01639             // add wind from v1
01640             VECCOPY(tmp, trinormal);
01641             mul_v3_fl(tmp, calculateVertexWindForce(winvec[mfaces[i].v1], triunnormal));
01642             VECADDS(lF[mfaces[i].v1], lF[mfaces[i].v1], tmp, factor);
01643             
01644             // add wind from v2
01645             VECCOPY(tmp, trinormal);
01646             mul_v3_fl(tmp, calculateVertexWindForce(winvec[mfaces[i].v2], triunnormal));
01647             VECADDS(lF[mfaces[i].v2], lF[mfaces[i].v2], tmp, factor);
01648             
01649             // add wind from v3
01650             VECCOPY(tmp, trinormal);
01651             mul_v3_fl(tmp, calculateVertexWindForce(winvec[mfaces[i].v3], triunnormal));
01652             VECADDS(lF[mfaces[i].v3], lF[mfaces[i].v3], tmp, factor);
01653             
01654             // add wind from v4
01655             if(mfaces[i].v4)
01656             {
01657                 VECCOPY(tmp, trinormal);
01658                 mul_v3_fl(tmp, calculateVertexWindForce(winvec[mfaces[i].v4], triunnormal));
01659                 VECADDS(lF[mfaces[i].v4], lF[mfaces[i].v4], tmp, factor);
01660             }
01661         }
01662 
01663         /* Hair has only edges */
01664         if(cloth->numfaces == 0) {
01665             ClothSpring *spring;
01666             float edgevec[3]={0,0,0}; //edge vector
01667             float edgeunnormal[3]={0,0,0}; // not-normalized-edge normal
01668             float tmp[3]={0,0,0};
01669             float factor = 0.01;
01670 
01671             search = cloth->springs;
01672             while(search) {
01673                 spring = search->link;
01674                 
01675                 if(spring->type == CLOTH_SPRING_TYPE_STRUCTURAL) {
01676                     VECSUB(edgevec, (float*)lX[spring->ij], (float*)lX[spring->kl]);
01677 
01678                     project_v3_v3v3(tmp, winvec[spring->ij], edgevec);
01679                     VECSUB(edgeunnormal, winvec[spring->ij], tmp);
01680                     /* hair doesn't stretch too much so we can use restlen pretty safely */
01681                     VECADDS(lF[spring->ij], lF[spring->ij], edgeunnormal, spring->restlen * factor);
01682 
01683                     project_v3_v3v3(tmp, winvec[spring->kl], edgevec);
01684                     VECSUB(edgeunnormal, winvec[spring->kl], tmp);
01685                     VECADDS(lF[spring->kl], lF[spring->kl], edgeunnormal, spring->restlen * factor);
01686                 }
01687 
01688                 search = search->next;
01689             }
01690         }
01691 
01692         del_lfvector(winvec);
01693     }
01694         
01695     // calculate spring forces
01696     search = cloth->springs;
01697     while(search)
01698     {
01699         // only handle active springs
01700         // if(((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)){}
01701         cloth_calc_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX, time);
01702 
01703         search = search->next;
01704     }
01705     
01706     // apply spring forces
01707     search = cloth->springs;
01708     while(search)
01709     {
01710         // only handle active springs
01711         // if(((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED))  
01712         cloth_apply_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX);
01713         search = search->next;
01714     }
01715     // printf("\n");
01716 }
01717 
01718 static void simulate_implicit_euler(lfVector *Vnew, lfVector *UNUSED(lX), lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV, fmatrix3x3 *UNUSED(P), fmatrix3x3 *UNUSED(Pinv), fmatrix3x3 *M, fmatrix3x3 *UNUSED(bigI))
01719 {
01720     unsigned int numverts = dFdV[0].vcount;
01721 
01722     lfVector *dFdXmV = create_lfvector(numverts);
01723     zero_lfvector(dV, numverts);
01724     
01725     cp_bfmatrix(A, M);
01726     
01727     subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt));
01728 
01729     mul_bfmatrix_lfvector(dFdXmV, dFdX, lV);
01730 
01731     add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, (dt*dt), numverts);
01732     
01733     itstart();
01734     
01735     cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */
01736     // cg_filtered_pre(dV, A, B, z, S, P, Pinv, bigI);
01737     
01738     itend();
01739     // printf("cg_filtered calc time: %f\n", (float)itval());
01740     
01741     cp_lfvector(olddV, dV, numverts);
01742 
01743     // advance velocities
01744     add_lfvector_lfvector(Vnew, lV, dV, numverts);
01745     
01746 
01747     del_lfvector(dFdXmV);
01748 }
01749 
01750 /*computes where the cloth would be if it were subject to perfectly stiff edges
01751   (edge distance constraints) in a lagrangian solver.  then add forces to help
01752   guide the implicit solver to that state.  this function is called after
01753   collisions*/
01754 int cloth_calc_helper_forces(Object *UNUSED(ob), ClothModifierData * clmd, float (*initial_cos)[3], float UNUSED(step), float dt)
01755 {
01756     Cloth *cloth= clmd->clothObject;
01757     float (*cos)[3] = MEM_callocN(sizeof(float)*3*cloth->numverts, "cos cloth_calc_helper_forces");
01758     float *masses = MEM_callocN(sizeof(float)*cloth->numverts, "cos cloth_calc_helper_forces");
01759     LinkNode *node;
01760     ClothSpring *spring;
01761     ClothVertex *cv;
01762     int i, steps;
01763     
01764     cv = cloth->verts;
01765     for (i=0; i<cloth->numverts; i++, cv++) {
01766         copy_v3_v3(cos[i], cv->tx);
01767         
01768         if (cv->goal == 1.0f || len_v3v3(initial_cos[i], cv->tx) != 0.0) {
01769             masses[i] = 1e+10;  
01770         } else {
01771             masses[i] = cv->mass;
01772         }
01773     }
01774     
01775     steps = 55;
01776     for (i=0; i<steps; i++) {
01777         for (node=cloth->springs; node; node=node->next) {
01778             /* ClothVertex *cv1, *cv2; */ /* UNUSED */
01779             int v1, v2;
01780             float len, c, l, vec[3];
01781             
01782             spring = node->link;
01783             if (spring->type != CLOTH_SPRING_TYPE_STRUCTURAL && spring->type != CLOTH_SPRING_TYPE_SHEAR) 
01784                 continue;
01785             
01786             v1 = spring->ij; v2 = spring->kl;
01787             /* cv1 = cloth->verts + v1; */ /* UNUSED */
01788             /* cv2 = cloth->verts + v2; */ /* UNUSED */
01789             len = len_v3v3(cos[v1], cos[v2]);
01790             
01791             sub_v3_v3v3(vec, cos[v1], cos[v2]);
01792             normalize_v3(vec);
01793             
01794             c = (len - spring->restlen);
01795             if (c == 0.0)
01796                 continue;
01797             
01798             l = c / ((1.0/masses[v1]) + (1.0/masses[v2]));
01799             
01800             mul_v3_fl(vec, -(1.0/masses[v1])*l);
01801             add_v3_v3(cos[v1], vec);
01802     
01803             sub_v3_v3v3(vec, cos[v2], cos[v1]);
01804             normalize_v3(vec);
01805             
01806             mul_v3_fl(vec, -(1.0/masses[v2])*l);
01807             add_v3_v3(cos[v2], vec);
01808         }
01809     }
01810     
01811     cv = cloth->verts;
01812     for (i=0; i<cloth->numverts; i++, cv++) {
01813         float vec[3];
01814         
01815         /*compute forces*/
01816         sub_v3_v3v3(vec, cos[i], cv->tx);
01817         mul_v3_fl(vec, cv->mass*dt*20.0f);
01818         add_v3_v3(cv->tv, vec);
01819         //copy_v3_v3(cv->tx, cos[i]);
01820     }
01821     
01822     MEM_freeN(cos);
01823     MEM_freeN(masses);
01824     
01825     return 1;
01826 }
01827 int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors)
01828 {
01829     unsigned int i=0;
01830     float step=0.0f, tf=clmd->sim_parms->timescale;
01831     Cloth *cloth = clmd->clothObject;
01832     ClothVertex *verts = cloth->verts, *cv;
01833     unsigned int numverts = cloth->numverts;
01834     float dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame;
01835     float spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
01836     float (*initial_cos)[3] = MEM_callocN(sizeof(float)*3*cloth->numverts, "initial_cos implicit.c");
01837     Implicit_Data *id = cloth->implicit;
01838     int do_extra_solve;
01839 
01840     if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */
01841     {
01842         for(i = 0; i < numverts; i++)
01843         {           
01844             // update velocities with constrained velocities from pinned verts
01845             if(verts [i].flags & CLOTH_VERT_FLAG_PINNED)
01846             {           
01847                 VECSUB(id->V[i], verts[i].xconst, verts[i].xold);
01848                 // mul_v3_fl(id->V[i], clmd->sim_parms->stepsPerFrame);
01849             }
01850         }   
01851     }
01852     
01853     while(step < tf)
01854     {   
01855         // calculate forces
01856         cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step, id->M);
01857         
01858         // calculate new velocity
01859         simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI);
01860         
01861         // advance positions
01862         add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts);
01863         
01864         /* move pinned verts to correct position */
01865         for(i = 0; i < numverts; i++)
01866         {   
01867             if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) 
01868             {           
01869                 if(verts [i].flags & CLOTH_VERT_FLAG_PINNED)
01870                 {           
01871                     float tvect[3] = {.0,.0,.0};
01872                     VECSUB(tvect, verts[i].xconst, verts[i].xold);
01873                     mul_fvector_S(tvect, tvect, step+dt);
01874                     VECADD(tvect, tvect, verts[i].xold);
01875                     VECCOPY(id->Xnew[i], tvect);
01876                 }   
01877             }
01878             
01879             VECCOPY(verts[i].txold, id->X[i]);
01880         }
01881 
01882         if(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED && clmd->clothObject->bvhtree)
01883         {
01884             // collisions 
01885             // itstart();
01886             
01887             // update verts to current positions
01888             for(i = 0; i < numverts; i++)
01889             {
01890                 VECCOPY(verts[i].tx, id->Xnew[i]);
01891 
01892                 VECSUB(verts[i].tv, verts[i].tx, verts[i].txold);
01893                 VECCOPY(verts[i].v, verts[i].tv);
01894             }
01895 
01896             for (i=0, cv=cloth->verts; i<cloth->numverts; i++, cv++) {
01897                 copy_v3_v3(initial_cos[i], cv->tx);
01898             }
01899             
01900             // call collision function
01901             // TODO: check if "step" or "step+dt" is correct - dg
01902             do_extra_solve = cloth_bvh_objcollision(ob, clmd, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
01903                         
01904             // copy corrected positions back to simulation
01905             for(i = 0; i < numverts; i++)
01906             {       
01907                 // correct velocity again, just to be sure we had to change it due to adaptive collisions
01908                 VECSUB(verts[i].tv, verts[i].tx, id->X[i]);
01909             }
01910 
01911             //if (do_extra_solve)
01912             //  cloth_calc_helper_forces(ob, clmd, initial_cos, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
01913             
01914             for(i = 0; i < numverts; i++)
01915             {       
01916 
01917                 if(do_extra_solve)
01918                 {
01919                     
01920                     if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (verts [i].flags & CLOTH_VERT_FLAG_PINNED))
01921                         continue;
01922 
01923                     VECCOPY(id->Xnew[i], verts[i].tx);
01924                     VECCOPY(id->Vnew[i], verts[i].tv);
01925                     mul_v3_fl(id->Vnew[i], spf);
01926                 }
01927             }
01928             
01929             // X = Xnew;
01930             cp_lfvector(id->X, id->Xnew, numverts);
01931 
01932             // if there were collisions, advance the velocity from v_n+1/2 to v_n+1
01933             
01934             if(do_extra_solve)
01935             {
01936                 // V = Vnew;
01937                 cp_lfvector(id->V, id->Vnew, numverts);
01938 
01939                 // calculate 
01940                 cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step+dt, id->M);  
01941                 
01942                 simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI);
01943             }
01944         }
01945         else
01946         {
01947             // X = Xnew;
01948             cp_lfvector(id->X, id->Xnew, numverts);
01949         }
01950         
01951         // itend();
01952         // printf("collision time: %f\n", (float)itval());
01953         
01954         // V = Vnew;
01955         cp_lfvector(id->V, id->Vnew, numverts);
01956         
01957         step += dt;
01958     }
01959 
01960     for(i = 0; i < numverts; i++)
01961     {               
01962         if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (verts [i].flags & CLOTH_VERT_FLAG_PINNED))
01963         {
01964             VECCOPY(verts[i].txold, verts[i].xconst); // TODO: test --> should be .x 
01965             VECCOPY(verts[i].x, verts[i].xconst);
01966             VECCOPY(verts[i].v, id->V[i]);
01967         }
01968         else
01969         {
01970             VECCOPY(verts[i].txold, id->X[i]);
01971             VECCOPY(verts[i].x, id->X[i]);
01972             VECCOPY(verts[i].v, id->V[i]);
01973         }
01974     }
01975     
01976     MEM_freeN(initial_cos);
01977     
01978     return 1;
01979 }
01980 
01981 void implicit_set_positions (ClothModifierData *clmd)
01982 {
01983     Cloth *cloth = clmd->clothObject;
01984     ClothVertex *verts = cloth->verts;
01985     unsigned int numverts = cloth->numverts, i;
01986     Implicit_Data *id = cloth->implicit;
01987     
01988     for(i = 0; i < numverts; i++)
01989     {               
01990         VECCOPY(id->X[i], verts[i].x);
01991         VECCOPY(id->V[i], verts[i].v);
01992     }
01993     if(G.rt > 0)
01994         printf("implicit_set_positions\n"); 
01995 }
01996