Reason of all this work: Commiting my work-in-progress on reviewed collision system...
[blender.git] / source / blender / blenkernel / intern / collision.c
1 /*  collision.c
2 *
3 *
4 * ***** BEGIN GPL LICENSE BLOCK *****
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 *
20 * The Original Code is Copyright (C) Blender Foundation
21 * All rights reserved.
22 *
23 * The Original Code is: all of this file.
24 *
25 * Contributor(s): none yet.
26 *
27 * ***** END GPL LICENSE BLOCK *****
28 */
29
30 #include "MEM_guardedalloc.h"
31
32 #include "BKE_cloth.h"
33
34 #include "DNA_group_types.h"
35 #include "DNA_object_types.h"
36 #include "DNA_cloth_types.h"
37 #include "DNA_mesh_types.h"
38 #include "DNA_scene_types.h"
39
40 #include "BKE_DerivedMesh.h"
41 #include "BKE_global.h"
42 #include "BKE_mesh.h"
43 #include "BKE_object.h"
44 #include "BKE_modifier.h"
45 #include "BKE_utildefines.h"
46 #include "BKE_DerivedMesh.h"
47 #include "mydevice.h"
48
49 #include "Bullet-C-Api.h"
50
51 #include "BLI_kdopbvh.h"
52 #include "BKE_collision.h"
53
54 #ifdef _WIN32
55 static void start ( void )
56 {}
57 static void end ( void )
58 {
59 }
60 static double val()
61 {
62         return 0;
63 }
64 #else
65 #include <sys/time.h>
66 static void mystart ( struct timeval *start, struct timezone *z )
67 {
68         gettimeofday ( start, z );
69 }
70 static void myend ( struct timeval *end, struct timezone *z )
71 {
72         gettimeofday ( end,z );
73 }
74 static double myval ( struct timeval *start, struct timeval *end )
75 {
76         double t1, t2;
77         t1 = ( double ) start->tv_sec + ( double ) start->tv_usec/ ( 1000*1000 );
78         t2 = ( double ) end->tv_sec + ( double ) end->tv_usec/ ( 1000*1000 );
79         return t2-t1;
80 }
81 #endif
82
83 /***********************************
84 Collision modifier code start
85 ***********************************/
86
87 /* step is limited from 0 (frame start position) to 1 (frame end position) */
88 void collision_move_object ( CollisionModifierData *collmd, float step, float prevstep )
89 {
90         float tv[3] = {0,0,0};
91         unsigned int i = 0;
92
93         for ( i = 0; i < collmd->numverts; i++ )
94         {
95                 VECSUB ( tv, collmd->xnew[i].co, collmd->x[i].co );
96                 VECADDS ( collmd->current_x[i].co, collmd->x[i].co, tv, prevstep );
97                 VECADDS ( collmd->current_xnew[i].co, collmd->x[i].co, tv, step );
98                 VECSUB ( collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co );
99         }
100         bvhtree_update_from_mvert ( collmd->bvhtree, collmd->mfaces, collmd->numfaces, collmd->current_x, collmd->current_xnew, collmd->numverts, 1 );
101 }
102
103 BVHTree *bvhtree_build_from_mvert ( MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon )
104 {
105         BVHTree *tree;
106         float co[12];
107         int i;
108         MFace *tface = mfaces;
109
110         tree = BLI_bvhtree_new ( numfaces*2, epsilon, 4, 26 );
111
112         // fill tree
113         for ( i = 0; i < numfaces; i++, tface++ )
114         {
115                 VECCOPY ( &co[0*3], x[tface->v1].co );
116                 VECCOPY ( &co[1*3], x[tface->v2].co );
117                 VECCOPY ( &co[2*3], x[tface->v3].co );
118                 if ( tface->v4 )
119                         VECCOPY ( &co[3*3], x[tface->v4].co );
120
121                 BLI_bvhtree_insert ( tree, i, co, ( mfaces->v4 ? 4 : 3 ) );
122         }
123
124         // balance tree
125         BLI_bvhtree_balance ( tree );
126
127         return tree;
128 }
129
130 void bvhtree_update_from_mvert ( BVHTree * bvhtree, MFace *faces, int numfaces, MVert *x, MVert *xnew, int numverts, int moving )
131 {
132         int i;
133         MFace *mfaces = faces;
134         float co[12], co_moving[12];
135         int ret = 0;
136
137         if ( !bvhtree )
138                 return;
139
140         if ( x )
141         {
142                 for ( i = 0; i < numfaces; i++, mfaces++ )
143                 {
144                         VECCOPY ( &co[0*3], x[mfaces->v1].co );
145                         VECCOPY ( &co[1*3], x[mfaces->v2].co );
146                         VECCOPY ( &co[2*3], x[mfaces->v3].co );
147                         if ( mfaces->v4 )
148                                 VECCOPY ( &co[3*3], x[mfaces->v4].co );
149
150                         // copy new locations into array
151                         if ( moving && xnew )
152                         {
153                                 // update moving positions
154                                 VECCOPY ( &co_moving[0*3], xnew[mfaces->v1].co );
155                                 VECCOPY ( &co_moving[1*3], xnew[mfaces->v2].co );
156                                 VECCOPY ( &co_moving[2*3], xnew[mfaces->v3].co );
157                                 if ( mfaces->v4 )
158                                         VECCOPY ( &co_moving[3*3], xnew[mfaces->v4].co );
159
160                                 ret = BLI_bvhtree_update_node ( bvhtree, i, co, co_moving, ( mfaces->v4 ? 4 : 3 ) );
161                         }
162                         else
163                         {
164                                 ret = BLI_bvhtree_update_node ( bvhtree, i, co, NULL, ( mfaces->v4 ? 4 : 3 ) );
165                         }
166
167                         // check if tree is already full
168                         if ( !ret )
169                                 break;
170                 }
171
172                 BLI_bvhtree_update_tree ( bvhtree );
173         }
174 }
175
176 /***********************************
177 Collision modifier code end
178 ***********************************/
179
180 /**
181  * gsl_poly_solve_cubic -
182  *
183  * copied from SOLVE_CUBIC.C --> GSL
184  */
185
186 /* DG: debug hint! don't forget that all functions were "fabs", "sinf", etc before */
187 #define mySWAP(a,b) { float tmp = b ; b = a ; a = tmp ; }
188
189 int gsl_poly_solve_cubic ( float a, float b, float c, float *x0, float *x1, float *x2 )
190 {
191         float q = ( a * a - 3 * b );
192         float r = ( 2 * a * a * a - 9 * a * b + 27 * c );
193
194         float Q = q / 9;
195         float R = r / 54;
196
197         float Q3 = Q * Q * Q;
198         float R2 = R * R;
199
200         float CR2 = 729 * r * r;
201         float CQ3 = 2916 * q * q * q;
202
203         if ( R == 0 && Q == 0 )
204         {
205                 *x0 = - a / 3 ;
206                 *x1 = - a / 3 ;
207                 *x2 = - a / 3 ;
208                 return 3 ;
209         }
210         else if ( CR2 == CQ3 )
211         {
212                 /* this test is actually R2 == Q3, written in a form suitable
213                 for exact computation with integers */
214
215                 /* Due to finite precision some float roots may be missed, and
216                 considered to be a pair of complex roots z = x +/- epsilon i
217                 close to the real axis. */
218
219                 float sqrtQ = sqrt ( Q );
220
221                 if ( R > 0 )
222                 {
223                         *x0 = -2 * sqrtQ  - a / 3;
224                         *x1 = sqrtQ - a / 3;
225                         *x2 = sqrtQ - a / 3;
226                 }
227                 else
228                 {
229                         *x0 = - sqrtQ  - a / 3;
230                         *x1 = - sqrtQ - a / 3;
231                         *x2 = 2 * sqrtQ - a / 3;
232                 }
233                 return 3 ;
234         }
235         else if ( CR2 < CQ3 ) /* equivalent to R2 < Q3 */
236         {
237                 float sqrtQ = sqrt ( Q );
238                 float sqrtQ3 = sqrtQ * sqrtQ * sqrtQ;
239                 float theta = acos ( R / sqrtQ3 );
240                 float norm = -2 * sqrtQ;
241                 *x0 = norm * cos ( theta / 3 ) - a / 3;
242                 *x1 = norm * cos ( ( theta + 2.0 * M_PI ) / 3 ) - a / 3;
243                 *x2 = norm * cos ( ( theta - 2.0 * M_PI ) / 3 ) - a / 3;
244
245                 /* Sort *x0, *x1, *x2 into increasing order */
246
247                 if ( *x0 > *x1 )
248                         mySWAP ( *x0, *x1 ) ;
249
250                 if ( *x1 > *x2 )
251                 {
252                         mySWAP ( *x1, *x2 ) ;
253
254                         if ( *x0 > *x1 )
255                                 mySWAP ( *x0, *x1 ) ;
256                 }
257
258                 return 3;
259         }
260         else
261         {
262                 float sgnR = ( R >= 0 ? 1 : -1 );
263                 float A = -sgnR * pow ( ABS ( R ) + sqrt ( R2 - Q3 ), 1.0/3.0 );
264                 float B = Q / A ;
265                 *x0 = A + B - a / 3;
266                 return 1;
267         }
268 }
269
270
271 /**
272  * gsl_poly_solve_quadratic
273  *
274  * copied from GSL
275  */
276 int gsl_poly_solve_quadratic ( float a, float b, float c,  float *x0, float *x1 )
277 {
278         float disc = b * b - 4 * a * c;
279
280         if ( disc > 0 )
281         {
282                 if ( b == 0 )
283                 {
284                         float r = ABS ( 0.5 * sqrt ( disc ) / a );
285                         *x0 = -r;
286                         *x1 =  r;
287                 }
288                 else
289                 {
290                         float sgnb = ( b > 0 ? 1 : -1 );
291                         float temp = -0.5 * ( b + sgnb * sqrt ( disc ) );
292                         float r1 = temp / a ;
293                         float r2 = c / temp ;
294
295                         if ( r1 < r2 )
296                         {
297                                 *x0 = r1 ;
298                                 *x1 = r2 ;
299                         }
300                         else
301                         {
302                                 *x0 = r2 ;
303                                 *x1 = r1 ;
304                         }
305                 }
306                 return 2;
307         }
308         else if ( disc == 0 )
309         {
310                 *x0 = -0.5 * b / a ;
311                 *x1 = -0.5 * b / a ;
312                 return 2 ;
313         }
314         else
315         {
316                 return 0;
317         }
318 }
319
320
321
322 /*
323  * See Bridson et al. "Robust Treatment of Collision, Contact and Friction for Cloth Animation"
324  *     page 4, left column
325  */
326
327 int cloth_get_collision_time ( float a[3], float b[3], float c[3], float d[3], float e[3], float f[3], float solution[3] )
328 {
329         int num_sols = 0;
330
331         float g = -a[2] * c[1] * e[0] + a[1] * c[2] * e[0] +
332                   a[2] * c[0] * e[1] - a[0] * c[2] * e[1] -
333                   a[1] * c[0] * e[2] + a[0] * c[1] * e[2];
334
335         float h = -b[2] * c[1] * e[0] + b[1] * c[2] * e[0] - a[2] * d[1] * e[0] +
336                   a[1] * d[2] * e[0] + b[2] * c[0] * e[1] - b[0] * c[2] * e[1] +
337                   a[2] * d[0] * e[1] - a[0] * d[2] * e[1] - b[1] * c[0] * e[2] +
338                   b[0] * c[1] * e[2] - a[1] * d[0] * e[2] + a[0] * d[1] * e[2] -
339                   a[2] * c[1] * f[0] + a[1] * c[2] * f[0] + a[2] * c[0] * f[1] -
340                   a[0] * c[2] * f[1] - a[1] * c[0] * f[2] + a[0] * c[1] * f[2];
341
342         float i = -b[2] * d[1] * e[0] + b[1] * d[2] * e[0] +
343                   b[2] * d[0] * e[1] - b[0] * d[2] * e[1] -
344                   b[1] * d[0] * e[2] + b[0] * d[1] * e[2] -
345                   b[2] * c[1] * f[0] + b[1] * c[2] * f[0] -
346                   a[2] * d[1] * f[0] + a[1] * d[2] * f[0] +
347                   b[2] * c[0] * f[1] - b[0] * c[2] * f[1] +
348                   a[2] * d[0] * f[1] - a[0] * d[2] * f[1] -
349                   b[1] * c[0] * f[2] + b[0] * c[1] * f[2] -
350                   a[1] * d[0] * f[2] + a[0] * d[1] * f[2];
351
352         float j = -b[2] * d[1] * f[0] + b[1] * d[2] * f[0] +
353                   b[2] * d[0] * f[1] - b[0] * d[2] * f[1] -
354                   b[1] * d[0] * f[2] + b[0] * d[1] * f[2];
355
356         // Solve cubic equation to determine times t1, t2, t3, when the collision will occur.
357         if ( ABS ( j ) > ALMOST_ZERO )
358         {
359                 i /= j;
360                 h /= j;
361                 g /= j;
362
363                 num_sols = gsl_poly_solve_cubic ( i, h, g, &solution[0], &solution[1], &solution[2] );
364         }
365         else if ( ABS ( i ) > ALMOST_ZERO )
366         {
367                 num_sols = gsl_poly_solve_quadratic ( i, h, g, &solution[0], &solution[1] );
368                 solution[2] = -1.0;
369         }
370         else if ( ABS ( h ) > ALMOST_ZERO )
371         {
372                 solution[0] = -g / h;
373                 solution[1] = solution[2] = -1.0;
374                 num_sols = 1;
375         }
376         else if ( ABS ( g ) > ALMOST_ZERO )
377         {
378                 solution[0] = 0;
379                 solution[1] = solution[2] = -1.0;
380                 num_sols = 1;
381         }
382
383         // Discard negative solutions
384         if ( ( num_sols >= 1 ) && ( solution[0] < 0 ) )
385         {
386                 --num_sols;
387                 solution[0] = solution[num_sols];
388         }
389         if ( ( num_sols >= 2 ) && ( solution[1] < 0 ) )
390         {
391                 --num_sols;
392                 solution[1] = solution[num_sols];
393         }
394         if ( ( num_sols == 3 ) && ( solution[2] < 0 ) )
395         {
396                 --num_sols;
397         }
398
399         // Sort
400         if ( num_sols == 2 )
401         {
402                 if ( solution[0] > solution[1] )
403                 {
404                         double tmp = solution[0];
405                         solution[0] = solution[1];
406                         solution[1] = tmp;
407                 }
408         }
409         else if ( num_sols == 3 )
410         {
411
412                 // Bubblesort
413                 if ( solution[0] > solution[1] )
414                 {
415                         double tmp = solution[0]; solution[0] = solution[1]; solution[1] = tmp;
416                 }
417                 if ( solution[1] > solution[2] )
418                 {
419                         double tmp = solution[1]; solution[1] = solution[2]; solution[2] = tmp;
420                 }
421                 if ( solution[0] > solution[1] )
422                 {
423                         double tmp = solution[0]; solution[0] = solution[1]; solution[1] = tmp;
424                 }
425         }
426
427         return num_sols;
428 }
429
430 // w3 is not perfect
431 void collision_compute_barycentric ( float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3 )
432 {
433         double  tempV1[3], tempV2[3], tempV4[3];
434         double  a,b,c,d,e,f;
435
436         VECSUB ( tempV1, p1, p3 );
437         VECSUB ( tempV2, p2, p3 );
438         VECSUB ( tempV4, pv, p3 );
439
440         a = INPR ( tempV1, tempV1 );
441         b = INPR ( tempV1, tempV2 );
442         c = INPR ( tempV2, tempV2 );
443         e = INPR ( tempV1, tempV4 );
444         f = INPR ( tempV2, tempV4 );
445
446         d = ( a * c - b * b );
447
448         if ( ABS ( d ) < ALMOST_ZERO )
449         {
450                 *w1 = *w2 = *w3 = 1.0 / 3.0;
451                 return;
452         }
453
454         w1[0] = ( float ) ( ( e * c - b * f ) / d );
455
456         if ( w1[0] < 0 )
457                 w1[0] = 0;
458
459         w2[0] = ( float ) ( ( f - b * ( double ) w1[0] ) / c );
460
461         if ( w2[0] < 0 )
462                 w2[0] = 0;
463
464         w3[0] = 1.0f - w1[0] - w2[0];
465 }
466
467 DO_INLINE void collision_interpolateOnTriangle ( float to[3], float v1[3], float v2[3], float v3[3], double w1, double w2, double w3 )
468 {
469         to[0] = to[1] = to[2] = 0;
470         VECADDMUL ( to, v1, w1 );
471         VECADDMUL ( to, v2, w2 );
472         VECADDMUL ( to, v3, w3 );
473 }
474
475 int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
476 {
477         int result = 0;
478         Cloth *cloth1;
479         float w1, w2, w3, u1, u2, u3;
480         float v1[3], v2[3], relativeVelocity[3];
481         float magrelVel;
482         float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree );
483
484         cloth1 = clmd->clothObject;
485
486         for ( ; collpair != collision_end; collpair++ )
487         {
488                 // only handle static collisions here
489                 if ( collpair->flag & COLLISION_IN_FUTURE )
490                         continue;
491
492                 // compute barycentric coordinates for both collision points
493                 collision_compute_barycentric ( collpair->pa,
494                                                 cloth1->verts[collpair->ap1].txold,
495                                                 cloth1->verts[collpair->ap2].txold,
496                                                 cloth1->verts[collpair->ap3].txold,
497                                                 &w1, &w2, &w3 );
498
499                 // was: txold
500                 collision_compute_barycentric ( collpair->pb,
501                                                 collmd->current_x[collpair->bp1].co,
502                                                 collmd->current_x[collpair->bp2].co,
503                                                 collmd->current_x[collpair->bp3].co,
504                                                 &u1, &u2, &u3 );
505
506                 // Calculate relative "velocity".
507                 collision_interpolateOnTriangle ( v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3 );
508
509                 collision_interpolateOnTriangle ( v2, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, u1, u2, u3 );
510
511                 VECSUB ( relativeVelocity, v2, v1 );
512
513                 // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
514                 magrelVel = INPR ( relativeVelocity, collpair->normal );
515
516                 // printf("magrelVel: %f\n", magrelVel);
517
518                 // Calculate masses of points.
519                 // TODO
520
521                 // If v_n_mag < 0 the edges are approaching each other.
522                 if ( magrelVel > ALMOST_ZERO )
523                 {
524                         // Calculate Impulse magnitude to stop all motion in normal direction.
525                         float magtangent = 0, repulse = 0, d = 0;
526                         double impulse = 0.0;
527                         float vrel_t_pre[3];
528                         float temp[3];
529
530                         // calculate tangential velocity
531                         VECCOPY ( temp, collpair->normal );
532                         VecMulf ( temp, magrelVel );
533                         VECSUB ( vrel_t_pre, relativeVelocity, temp );
534
535                         // Decrease in magnitude of relative tangential velocity due to coulomb friction
536                         // in original formula "magrelVel" should be the "change of relative velocity in normal direction"
537                         magtangent = MIN2 ( clmd->coll_parms->friction * 0.01 * magrelVel,sqrt ( INPR ( vrel_t_pre,vrel_t_pre ) ) );
538
539                         // Apply friction impulse.
540                         if ( magtangent > ALMOST_ZERO )
541                         {
542                                 Normalize ( vrel_t_pre );
543
544                                 impulse = 2.0 * magtangent / ( 1.0 + w1*w1 + w2*w2 + w3*w3 );
545                                 VECADDMUL ( cloth1->verts[collpair->ap1].impulse, vrel_t_pre, w1 * impulse );
546                                 VECADDMUL ( cloth1->verts[collpair->ap2].impulse, vrel_t_pre, w2 * impulse );
547                                 VECADDMUL ( cloth1->verts[collpair->ap3].impulse, vrel_t_pre, w3 * impulse );
548                         }
549
550                         // Apply velocity stopping impulse
551                         // I_c = m * v_N / 2.0
552                         // no 2.0 * magrelVel normally, but looks nicer DG
553                         impulse =  magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3 );
554
555                         VECADDMUL ( cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse );
556                         cloth1->verts[collpair->ap1].impulse_count++;
557
558                         VECADDMUL ( cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse );
559                         cloth1->verts[collpair->ap2].impulse_count++;
560
561                         VECADDMUL ( cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse );
562                         cloth1->verts[collpair->ap3].impulse_count++;
563
564                         // Apply repulse impulse if distance too short
565                         // I_r = -min(dt*kd, m(0,1d/dt - v_n))
566                         d = clmd->coll_parms->epsilon*8.0/9.0 + epsilon2*8.0/9.0 - collpair->distance;
567                         if ( ( magrelVel < 0.1*d*clmd->sim_parms->stepsPerFrame ) && ( d > ALMOST_ZERO ) )
568                         {
569                                 repulse = MIN2 ( d*1.0/clmd->sim_parms->stepsPerFrame, 0.1*d*clmd->sim_parms->stepsPerFrame - magrelVel );
570
571                                 // stay on the safe side and clamp repulse
572                                 if ( impulse > ALMOST_ZERO )
573                                         repulse = MIN2 ( repulse, 5.0*impulse );
574                                 repulse = MAX2 ( impulse, repulse );
575
576                                 impulse = repulse / ( 1.0 + w1*w1 + w2*w2 + w3*w3 ); // original 2.0 / 0.25
577                                 VECADDMUL ( cloth1->verts[collpair->ap1].impulse, collpair->normal,  impulse );
578                                 VECADDMUL ( cloth1->verts[collpair->ap2].impulse, collpair->normal,  impulse );
579                                 VECADDMUL ( cloth1->verts[collpair->ap3].impulse, collpair->normal,  impulse );
580                         }
581
582                         result = 1;
583                 }
584         }
585
586
587         return result;
588 }
589
590 int cloth_collision_response_moving_tris ( ClothModifierData *clmd, ClothModifierData *coll_clmd )
591 {
592         return 1;
593 }
594
595
596 int cloth_collision_response_moving_edges ( ClothModifierData *clmd, ClothModifierData *coll_clmd )
597 {
598         return 1;
599 }
600
601 //Determines collisions on overlap, collisions are writen to collpair[i] and collision+number_collision_found is returned
602 CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap *overlap, CollPair *collpair )
603 {
604         ClothModifierData *clmd = ( ClothModifierData * ) md1;
605         CollisionModifierData *collmd = ( CollisionModifierData * ) md2;
606         MFace *face1=NULL, *face2 = NULL;
607         ClothVertex *verts1 = clmd->clothObject->verts;
608         double distance = 0;
609         float epsilon1 = clmd->coll_parms->epsilon;
610         float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree );
611         int i;
612
613         face1 = & ( clmd->clothObject->mfaces[overlap->indexA] );
614         face2 = & ( collmd->mfaces[overlap->indexB] );
615
616         // check all 4 possible collisions
617         for ( i = 0; i < 4; i++ )
618         {
619                 if ( i == 0 )
620                 {
621                         // fill faceA
622                         collpair->ap1 = face1->v1;
623                         collpair->ap2 = face1->v2;
624                         collpair->ap3 = face1->v3;
625
626                         // fill faceB
627                         collpair->bp1 = face2->v1;
628                         collpair->bp2 = face2->v2;
629                         collpair->bp3 = face2->v3;
630                 }
631                 else if ( i == 1 )
632                 {
633                         if ( face1->v4 )
634                         {
635                                 // fill faceA
636                                 collpair->ap1 = face1->v1;
637                                 collpair->ap2 = face1->v4;
638                                 collpair->ap3 = face1->v3;
639
640                                 // fill faceB
641                                 collpair->bp1 = face2->v1;
642                                 collpair->bp2 = face2->v2;
643                                 collpair->bp3 = face2->v3;
644                         }
645                         else
646                                 i++;
647                 }
648                 if ( i == 2 )
649                 {
650                         if ( face2->v4 )
651                         {
652                                 // fill faceA
653                                 collpair->ap1 = face1->v1;
654                                 collpair->ap2 = face1->v2;
655                                 collpair->ap3 = face1->v3;
656
657                                 // fill faceB
658                                 collpair->bp1 = face2->v1;
659                                 collpair->bp2 = face2->v4;
660                                 collpair->bp3 = face2->v3;
661                         }
662                         else
663                                 break;
664                 }
665                 else if ( i == 3 )
666                 {
667                         if ( face1->v4 && face2->v4 )
668                         {
669                                 // fill faceA
670                                 collpair->ap1 = face1->v1;
671                                 collpair->ap2 = face1->v4;
672                                 collpair->ap3 = face1->v3;
673
674                                 // fill faceB
675                                 collpair->bp1 = face2->v1;
676                                 collpair->bp2 = face2->v4;
677                                 collpair->bp3 = face2->v3;
678                         }
679                         else
680                                 break;
681                 }
682
683 #ifdef WITH_BULLET
684                 // calc distance + normal
685                 distance = plNearestPoints (
686                                verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, collmd->current_x[collpair->bp1].co, collmd->current_x[collpair->bp2].co, collmd->current_x[collpair->bp3].co, collpair->pa,collpair->pb,collpair->vector );
687 #else
688                 // just be sure that we don't add anything
689                 distance = 2.0 * ( epsilon1 + epsilon2 + ALMOST_ZERO );
690 #endif
691
692                 if ( distance <= ( epsilon1 + epsilon2 + ALMOST_ZERO ) )
693                 {
694                         VECCOPY ( collpair->normal, collpair->vector );
695                         Normalize ( collpair->normal );
696
697                         collpair->distance = distance;
698                         collpair->flag = 0;
699                 }
700                 else
701                 {
702                         // check for collision in the future
703                         collpair->flag |= COLLISION_IN_FUTURE;
704                 }
705                 collpair++;
706         }
707         return collpair;
708 }
709
710 int cloth_are_edges_adjacent ( ClothModifierData *clmd, CollisionModifierData *collmd, EdgeCollPair *edgecollpair )
711 {
712         Cloth *cloth1 = NULL;
713         ClothVertex *verts1 = NULL;
714         float temp[3];
715         MVert *verts2 = collmd->current_x; // old x
716
717         cloth1 = clmd->clothObject;
718         verts1 = cloth1->verts;
719
720         VECSUB ( temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].co );
721         if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO )
722                 return 1;
723
724         VECSUB ( temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].co );
725         if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO )
726                 return 1;
727
728         VECSUB ( temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].co );
729         if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO )
730                 return 1;
731
732         VECSUB ( temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].co );
733         if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO )
734                 return 1;
735
736         return 0;
737 }
738
739 void cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair )
740 {
741         EdgeCollPair edgecollpair;
742         Cloth *cloth1=NULL;
743         ClothVertex *verts1=NULL;
744         unsigned int i = 0, j = 0, k = 0;
745         int numsolutions = 0;
746         float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
747         MVert *verts2 = collmd->current_x; // old x
748         MVert *velocity2 = collmd->current_v; // velocity
749         float mintime = 0;
750
751         cloth1 = clmd->clothObject;
752         verts1 = cloth1->verts;
753
754         for(i = 0; i < 9; i++)
755         {
756                 // 9 edge - edge possibilities
757                 
758                 if(i == 0) // cloth edge: 1-2; coll edge: 1-2
759                 {
760                         edgecollpair.p11 = collpair->ap1;
761                         edgecollpair.p12 = collpair->ap2;
762                         
763                         edgecollpair.p21 = collpair->bp1;
764                         edgecollpair.p22 = collpair->bp2;
765                 }
766                 else if(i == 1) // cloth edge: 1-2; coll edge: 2-3
767                 {
768                         edgecollpair.p11 = collpair->ap1;
769                         edgecollpair.p12 = collpair->ap2;
770                         
771                         edgecollpair.p21 = collpair->bp2;
772                         edgecollpair.p22 = collpair->bp3;
773                 }
774                 else if(i == 2) // cloth edge: 1-2; coll edge: 1-3
775                 {
776                         edgecollpair.p11 = collpair->ap1;
777                         edgecollpair.p12 = collpair->ap2;
778                         
779                         edgecollpair.p21 = collpair->bp1;
780                         edgecollpair.p22 = collpair->bp3;
781                 }
782                 else if(i == 3) // cloth edge: 2-3; coll edge: 1-2
783                 {
784                         edgecollpair.p11 = collpair->ap2;
785                         edgecollpair.p12 = collpair->ap3;
786                         
787                         edgecollpair.p21 = collpair->bp1;
788                         edgecollpair.p22 = collpair->bp2;
789                 }
790                 else if(i == 4) // cloth edge: 2-3; coll edge: 2-3
791                 {
792                         edgecollpair.p11 = collpair->ap2;
793                         edgecollpair.p12 = collpair->ap3;
794                         
795                         edgecollpair.p21 = collpair->bp2;
796                         edgecollpair.p22 = collpair->bp3;
797                 }
798                 else if(i == 5) // cloth edge: 2-3; coll edge: 1-3
799                 {
800                         edgecollpair.p11 = collpair->ap2;
801                         edgecollpair.p12 = collpair->ap3;
802                         
803                         edgecollpair.p21 = collpair->bp1;
804                         edgecollpair.p22 = collpair->bp3;
805                 }
806                 else if(i ==6) // cloth edge: 1-3; coll edge: 1-2
807                 {
808                         edgecollpair.p11 = collpair->ap1;
809                         edgecollpair.p12 = collpair->ap3;
810                         
811                         edgecollpair.p21 = collpair->bp1;
812                         edgecollpair.p22 = collpair->bp2;
813                 }
814                 else if(i ==7) // cloth edge: 1-3; coll edge: 2-3
815                 {
816                         edgecollpair.p11 = collpair->ap1;
817                         edgecollpair.p12 = collpair->ap3;
818                         
819                         edgecollpair.p21 = collpair->bp2;
820                         edgecollpair.p22 = collpair->bp3;
821                 }
822                 else if(i == 8) // cloth edge: 1-3; coll edge: 1-3
823                 {
824                         edgecollpair.p11 = collpair->ap1;
825                         edgecollpair.p12 = collpair->ap3;
826                         
827                         edgecollpair.p21 = collpair->bp1;
828                         edgecollpair.p22 = collpair->bp3;
829                 }
830                 
831                 if ( !cloth_are_edges_adjacent ( clmd, collmd, &edgecollpair ) )
832                 {
833                         // always put coll points in p21/p22
834                         VECSUB ( a, verts1[edgecollpair.p12].txold, verts1[edgecollpair.p11].txold );
835                         VECSUB ( b, verts1[edgecollpair.p12].tv, verts1[edgecollpair.p11].tv );
836                         VECSUB ( c, verts2[edgecollpair.p21].co, verts1[edgecollpair.p11].txold );
837                         VECSUB ( d, velocity2[edgecollpair.p21].co, verts1[edgecollpair.p11].tv );
838                         VECSUB ( e, verts2[edgecollpair.p22].co, verts1[edgecollpair.p11].txold );
839                         VECSUB ( f, velocity2[edgecollpair.p22].co, verts1[edgecollpair.p11].v );
840         
841                         numsolutions = cloth_get_collision_time ( a, b, c, d, e, f, solution );
842         
843                         for ( k = 0; k < numsolutions; k++ )
844                         {
845                                 if ( ( solution[k] >= 0.0 ) && ( solution[k] <= 1.0 ) )
846                                 {
847                                         //float out_collisionTime = solution[k];
848         
849                                         // TODO: check for collisions
850         
851                                         // TODO: put into (edge) collision list
852                                         
853                                         mintime = MIN2(mintime, solution[k]);
854         
855                                         printf("Moving edge found!, mintime: %f\n", mintime);
856                                         break;
857                                 }
858                         }
859                 }
860         }
861 }
862
863 void cloth_collision_moving_tris ( ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2 )
864 {
865         CollPair collpair;
866         Cloth *cloth1=NULL, *cloth2=NULL;
867         MFace *face1=NULL, *face2=NULL;
868         ClothVertex *verts1=NULL, *verts2=NULL;
869         unsigned int i = 0, j = 0, k = 0;
870         int numsolutions = 0;
871         float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
872
873         for ( i = 0; i < 2; i++ )
874         {
875                 cloth1 = clmd->clothObject;
876                 cloth2 = coll_clmd->clothObject;
877
878                 verts1 = cloth1->verts;
879                 verts2 = cloth2->verts;
880
881                 face1 = & ( cloth1->mfaces[tree1->tri_index] );
882                 face2 = & ( cloth2->mfaces[tree2->tri_index] );
883
884                 // check all possible pairs of triangles
885                 if ( i == 0 )
886                 {
887                         collpair.ap1 = face1->v1;
888                         collpair.ap2 = face1->v2;
889                         collpair.ap3 = face1->v3;
890
891                         collpair.pointsb[0] = face2->v1;
892                         collpair.pointsb[1] = face2->v2;
893                         collpair.pointsb[2] = face2->v3;
894                         collpair.pointsb[3] = face2->v4;
895                 }
896
897                 if ( i == 1 )
898                 {
899                         if ( face1->v4 )
900                         {
901                                 collpair.ap1 = face1->v3;
902                                 collpair.ap2 = face1->v4;
903                                 collpair.ap3 = face1->v1;
904
905                                 collpair.pointsb[0] = face2->v1;
906                                 collpair.pointsb[1] = face2->v2;
907                                 collpair.pointsb[2] = face2->v3;
908                                 collpair.pointsb[3] = face2->v4;
909                         }
910                         else
911                                 i++;
912                 }
913
914                 // calc SIPcode (?)
915
916                 if ( i < 2 )
917                 {
918                         VECSUB ( a, verts1[collpair.ap2].xold, verts1[collpair.ap1].xold );
919                         VECSUB ( b, verts1[collpair.ap2].v, verts1[collpair.ap1].v );
920                         VECSUB ( c, verts1[collpair.ap3].xold, verts1[collpair.ap1].xold );
921                         VECSUB ( d, verts1[collpair.ap3].v, verts1[collpair.ap1].v );
922
923                         for ( j = 0; j < 4; j++ )
924                         {
925                                 if ( ( j==3 ) && ! ( face2->v4 ) )
926                                         break;
927
928                                 VECSUB ( e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold );
929                                 VECSUB ( f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v );
930
931                                 numsolutions = cloth_get_collision_time ( a, b, c, d, e, f, solution );
932
933                                 for ( k = 0; k < numsolutions; k++ )
934                                 {
935                                         if ( ( solution[k] >= 0.0 ) && ( solution[k] <= 1.0 ) )
936                                         {
937                                                 //float out_collisionTime = solution[k];
938
939                                                 // TODO: check for collisions
940
941                                                 // TODO: put into (point-face) collision list
942
943                                                 // printf("Moving found!\n");
944
945                                         }
946                                 }
947
948                                 // TODO: check borders for collisions
949                         }
950
951                 }
952         }
953 }
954
955 /*
956 void cloth_collision_moving ( ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2 )
957 {
958         // TODO: check for adjacent
959         cloth_collision_moving_edges ( clmd, coll_clmd, tree1, tree2 );
960
961         cloth_collision_moving_tris ( clmd, coll_clmd, tree1, tree2 );
962         cloth_collision_moving_tris ( coll_clmd, clmd, tree2, tree1 );
963 }
964 */
965
966 int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
967 {
968         int result = 0;
969         Cloth *cloth1;
970         float w1, w2, w3, u1, u2, u3;
971         float v1[3], v2[3], relativeVelocity[3];
972         float magrelVel;
973         float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree );
974
975         cloth1 = clmd->clothObject;
976
977         for ( ; collpair != collision_end; collpair++ )
978         {
979                 // only handle moving collisions here
980                 if (!( collpair->flag & COLLISION_IN_FUTURE ))
981                         continue;
982                 
983                 cloth_collision_moving_edges ( clmd, collmd, collpair);
984         }
985 }
986
987 int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData *collmd, float step, float dt )
988 {
989         Cloth *cloth = clmd->clothObject;
990         BVHTree *cloth_bvh= ( BVHTree * ) cloth->bvhtree;
991         long i=0, j = 0, numfaces = 0, numverts = 0;
992         ClothVertex *verts = NULL;
993         CollPair *collisions = NULL, *collisions_index = NULL;
994         int ret = 0;
995         int result = 0;
996         float tnull[3] = {0,0,0};
997         BVHTreeOverlap *overlap = NULL;
998
999
1000         numfaces = clmd->clothObject->numfaces;
1001         numverts = clmd->clothObject->numverts;
1002
1003         verts = cloth->verts;
1004
1005         if ( collmd->bvhtree )
1006         {
1007                 /* get pointer to bounding volume hierarchy */
1008                 BVHTree *coll_bvh = collmd->bvhtree;
1009
1010                 /* move object to position (step) in time */
1011                 collision_move_object ( collmd, step + dt, step );
1012
1013                 /* search for overlapping collision pairs */
1014                 overlap = BLI_bvhtree_overlap ( cloth_bvh, coll_bvh, &result );
1015
1016                 collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * result*4, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision
1017                 collisions_index = collisions;
1018
1019                 for ( i = 0; i < result; i++ )
1020                 {
1021                         collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, overlap+i, collisions_index );
1022                 }
1023
1024                 if ( overlap )
1025                         MEM_freeN ( overlap );
1026         }
1027         else
1028         {
1029                 if ( G.rt > 0 )
1030                         printf ( "cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n" );
1031         }
1032
1033         // process all collisions (calculate impulses, TODO: also repulses if distance too short)
1034         result = 1;
1035         for ( j = 0; j < 5; j++ ) // 5 is just a value that ensures convergence
1036         {
1037                 result = 0;
1038
1039                 if ( collmd->bvhtree )
1040                 {
1041                         result += cloth_collision_response_static ( clmd, collmd, collisions, collisions_index );
1042                         result += cloth_collision_moving ( clmd, collmd, collisions, collisions_index );
1043                 }
1044
1045                 // apply impulses in parallel
1046                 if ( result )
1047                 {
1048                         for ( i = 0; i < numverts; i++ )
1049                         {
1050                                 // calculate "velocities" (just xnew = xold + v; no dt in v)
1051                                 if ( verts[i].impulse_count )
1052                                 {
1053                                         VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count );
1054                                         VECCOPY ( verts[i].impulse, tnull );
1055                                         verts[i].impulse_count = 0;
1056
1057                                         ret++;
1058                                 }
1059                         }
1060                 }
1061         }
1062
1063         if ( collisions ) MEM_freeN ( collisions );
1064
1065         return ret;
1066 }
1067
1068 // cloth - object collisions
1069 int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt )
1070 {
1071         Base *base=NULL;
1072         CollisionModifierData *collmd=NULL;
1073         Cloth *cloth=NULL;
1074         Object *coll_ob=NULL;
1075         BVHTree *cloth_bvh=NULL;
1076         long i=0, j = 0, numfaces = 0, numverts = 0;
1077         unsigned int result = 0, rounds = 0; // result counts applied collisions; ic is for debug output;
1078         ClothVertex *verts = NULL;
1079         int ret = 0;
1080         ClothModifierData *tclmd;
1081         int collisions = 0, count = 0;
1082
1083         if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) || ! ( ( ( Cloth * ) clmd->clothObject )->bvhtree ) )
1084         {
1085                 return 0;
1086         }
1087
1088         cloth = clmd->clothObject;
1089         verts = cloth->verts;
1090         cloth_bvh = ( BVHTree * ) cloth->bvhtree;
1091         numfaces = clmd->clothObject->numfaces;
1092         numverts = clmd->clothObject->numverts;
1093
1094         ////////////////////////////////////////////////////////////
1095         // static collisions
1096         ////////////////////////////////////////////////////////////
1097
1098         // update cloth bvh
1099         bvhtree_update_from_cloth ( clmd, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function)
1100
1101         do
1102         {
1103                 result = 0;
1104
1105                 // check all collision objects
1106                 for ( base = G.scene->base.first; base; base = base->next )
1107                 {
1108                         coll_ob = base->object;
1109                         collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
1110
1111                         if ( !collmd )
1112                         {
1113                                 if ( coll_ob->dup_group )
1114                                 {
1115                                         GroupObject *go;
1116                                         Group *group = coll_ob->dup_group;
1117
1118                                         for ( go= group->gobject.first; go; go= go->next )
1119                                         {
1120                                                 coll_ob = go->ob;
1121
1122                                                 collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
1123
1124                                                 if ( !collmd )
1125                                                         continue;
1126
1127                                                 tclmd = ( ClothModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Cloth );
1128                                                 if ( tclmd == clmd )
1129                                                         continue;
1130
1131                                                 ret += cloth_bvh_objcollisions_do ( clmd, collmd, step, dt );
1132                                         }
1133                                 }
1134                         }
1135                         else
1136                         {
1137                                 tclmd = ( ClothModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Cloth );
1138                                 if ( tclmd == clmd )
1139                                         continue;
1140
1141                                 ret += cloth_bvh_objcollisions_do ( clmd, collmd, step, dt );
1142                         }
1143                 }
1144                 rounds++;
1145
1146                 ////////////////////////////////////////////////////////////
1147                 // update positions
1148                 // this is needed for bvh_calc_DOP_hull_moving() [kdop.c]
1149                 ////////////////////////////////////////////////////////////
1150
1151                 // verts come from clmd
1152                 for ( i = 0; i < numverts; i++ )
1153                 {
1154                         if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
1155                         {
1156                                 if ( verts [i].flags & CLOTH_VERT_FLAG_PINNED )
1157                                 {
1158                                         continue;
1159                                 }
1160                         }
1161
1162                         VECADD ( verts[i].tx, verts[i].txold, verts[i].tv );
1163                 }
1164                 ////////////////////////////////////////////////////////////
1165
1166
1167                 ////////////////////////////////////////////////////////////
1168                 // Test on *simple* selfcollisions
1169                 ////////////////////////////////////////////////////////////
1170                 if ( clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF )
1171                 {
1172
1173                         MFace *mface = clmd->clothObject->mfaces;
1174
1175                         collisions = 1;
1176                         verts = cloth->verts; // needed for openMP
1177
1178
1179
1180                         /*
1181                         for ( count = 0; count < clmd->coll_parms->self_loop_count; count++ )
1182                         {
1183                         if ( collisions )
1184                         {
1185                         collisions = 0;
1186                         #pragma omp parallel for private(i,j, collisions) shared(verts, ret)
1187                         for ( i = 0; i < cloth->numverts; i++ )
1188                         {
1189                         for ( j = i + 1; j < cloth->numverts; j++ )
1190                         {
1191                         float temp[3];
1192                         float length = 0;
1193                         float mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len );
1194
1195                         if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
1196                         {
1197                         if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
1198                         && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) )
1199                         {
1200                         continue;
1201                         }
1202                         }
1203
1204                         VECSUB ( temp, verts[i].tx, verts[j].tx );
1205
1206                         if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue;
1207
1208                                                         // check for adjacent points (i must be smaller j)
1209                         if ( BLI_edgehash_haskey ( cloth->edgehash, i, j ) )
1210                         {
1211                         continue;
1212                         }
1213
1214                         length = Normalize ( temp );
1215
1216                         if ( length < mindistance )
1217                         {
1218                         float correction = mindistance - length;
1219
1220                         if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
1221                         {
1222                         VecMulf ( temp, -correction );
1223                         VECADD ( verts[j].tx, verts[j].tx, temp );
1224                         }
1225                         else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED )
1226                         {
1227                         VecMulf ( temp, correction );
1228                         VECADD ( verts[i].tx, verts[i].tx, temp );
1229                         }
1230                         else
1231                         {
1232                         VecMulf ( temp, -correction*0.5 );
1233                         VECADD ( verts[j].tx, verts[j].tx, temp );
1234
1235                         VECSUB ( verts[i].tx, verts[i].tx, temp );
1236                         }
1237
1238                         collisions = 1;
1239
1240                         if ( !ret )
1241                         {
1242                         #pragma omp critical
1243                         {
1244                         ret = 1;
1245                         }
1246                         }
1247                         }
1248                         }
1249                         }
1250                         }
1251                         }
1252                         */
1253                         ////////////////////////////////////////////////////////////
1254
1255                         ////////////////////////////////////////////////////////////
1256                         // SELFCOLLISIONS: update velocities
1257                         ////////////////////////////////////////////////////////////
1258                         if ( ret )
1259                         {
1260                                 for ( i = 0; i < cloth->numverts; i++ )
1261                                 {
1262                                         if ( ! ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) )
1263                                                 VECSUB ( verts[i].tv, verts[i].tx, verts[i].txold );
1264                                 }
1265                         }
1266                         ////////////////////////////////////////////////////////////
1267                 }
1268         }
1269         while ( result && ( clmd->coll_parms->loop_count>rounds ) );
1270
1271         return MIN2 ( ret, 1 );
1272 }