WIP commit, (just in case my HD breaks down). Don't expect anything to work. Code...
[blender.git] / source / blender / blenkernel / intern / collision.c
index a89cd3dc4b9b12046344c5ff743a8362da9dda61..f4b0ce7312b918372c30f6f3b0f65355770c2177 100644 (file)
@@ -49,6 +49,7 @@
 #include "BLI_arithb.h"
 #include "BLI_edgehash.h"
 #include "BLI_linklist.h"
+#include "BKE_collisions.h"
 #include "BKE_curve.h"
 #include "BKE_deform.h"
 #include "BKE_DerivedMesh.h"
 #include "Bullet-C-Api.h"
 
 
+// step is limited from 0 (frame start position) to 1 (frame end position)
+void collision_move_object(CollisionModifierData *collmd, float step)
+{
+       float tv[3] = {0,0,0};
+       unsigned int i = 0;
+       MVert *tempVert = collmd->current_x;
+       collmd->current_x = collmd->current_xnew;
+       collmd->current_xnew = tempVert;
+                       
+       for ( i = 0; i < collmd->numverts; i++ )
+       {
+               VECSUB(tv, collmd->xnew[i].co, collmd->x[i].co);
+               VECADDS(collmd->current_xnew[i].co, collmd->x[i].co, tv, step);
+       }
+}
+
 
 /**
  * gsl_poly_solve_cubic -
  *
  * copied from SOLVE_CUBIC.C --> GSL
  */
-#define mySWAP(a,b) do { float tmp = b ; b = a ; a = tmp ; } while(0)
+#define mySWAP(a,b) { float tmp = b ; b = a ; a = tmp ; }
 
 int gsl_poly_solve_cubic (float a, float b, float c, float *x0, float *x1, float *x2)
 {
@@ -217,7 +234,7 @@ int gsl_poly_solve_quadratic (float a, float b, float c,  float *x0, float *x1)
  *     page 4, left column
  */
 
-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]) 
+int collisions_get_collision_time(float a[3], float b[3], float c[3], float d[3], float e[3], float f[3], float solution[3]) 
 {
        int num_sols = 0;
        
@@ -318,7 +335,7 @@ int cloth_get_collision_time(float a[3], float b[3], float c[3], float d[3], flo
 }
 
 // w3 is not perfect
-void cloth_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3)
+void collisions_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3)
 {
        double  tempV1[3], tempV2[3], tempV4[3];
        double  a,b,c,d,e,f;
@@ -361,877 +378,3 @@ DO_INLINE void interpolateOnTriangle(float to[3], float v1[3], float v2[3], floa
        VECADDMUL(to, v3, w3);
 }
 
-
-
-// unused in the moment, has some bug in
-DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal[3], double normalVelocity,
-                                       double frictionConstant, double delta_V_n) 
-{
-       float vrel_t_pre[3];
-       float vrel_t[3];
-       VECSUBS(vrel_t_pre, vrel, normal, normalVelocity);
-       VECCOPY(to, vrel_t_pre);
-       VecMulf(to, MAX2(1.0f - frictionConstant * delta_V_n / INPR(vrel_t_pre,vrel_t_pre), 0.0f));
-}
-
-int cloth_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd)
-{
-       unsigned int i = 0;
-       int result = 0;
-       LinkNode *search = NULL;
-       CollPair *collpair = NULL;
-       Cloth *cloth1, *cloth2;
-       float w1, w2, w3, u1, u2, u3;
-       float v1[3], v2[3], relativeVelocity[3];
-       float magrelVel;
-       
-       cloth1 = clmd->clothObject;
-       cloth2 = coll_clmd->clothObject;
-
-       search = clmd->coll_parms.collision_list;
-       
-       while(search)
-       {
-               collpair = search->link;
-               
-               // compute barycentric coordinates for both collision points
-               cloth_compute_barycentric(collpair->pa,
-                                       cloth1->verts[collpair->ap1].txold,
-                                       cloth1->verts[collpair->ap2].txold,
-                                       cloth1->verts[collpair->ap3].txold, 
-                                       &w1, &w2, &w3);
-       
-               cloth_compute_barycentric(collpair->pb,
-                                       cloth2->verts[collpair->bp1].txold,
-                                       cloth2->verts[collpair->bp2].txold,
-                                       cloth2->verts[collpair->bp3].txold,
-                                       &u1, &u2, &u3);
-       
-               // Calculate relative "velocity".
-               interpolateOnTriangle(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3);
-               
-               interpolateOnTriangle(v2, cloth2->verts[collpair->bp1].tv, cloth2->verts[collpair->bp2].tv, cloth2->verts[collpair->bp3].tv, u1, u2, u3);
-               
-               VECSUB(relativeVelocity, v1, v2);
-                       
-               // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
-               magrelVel = INPR(relativeVelocity, collpair->normal);
-               
-               // printf("magrelVel: %f\n", magrelVel);
-                               
-               // Calculate masses of points.
-               
-               // If v_n_mag < 0 the edges are approaching each other.
-               if(magrelVel < -ALMOST_ZERO) 
-               {
-                       // Calculate Impulse magnitude to stop all motion in normal direction.
-                       // const double I_mag = v_n_mag / (1/m1 + 1/m2);
-                       float magnitude_i = magrelVel / 2.0f; // TODO implement masses
-                       float tangential[3], magtangent, magnormal, collvel[3];
-                       float vrel_t_pre[3];
-                       float vrel_t[3];
-                       double impulse;
-                       float epsilon = clmd->coll_parms.epsilon;
-                       float overlap = (epsilon + ALMOST_ZERO-collpair->distance);
-                       
-                       // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel);
-                       
-                       // magtangent = INPR(tangential, tangential);
-                       
-                       // Apply friction impulse.
-                       if (magtangent < -ALMOST_ZERO) 
-                       {
-                               
-                               // printf("friction applied: %f\n", magtangent);
-                               // TODO check original code 
-                               /*
-                               VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,tangential);
-                               VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v2].tv,tangential);
-                               VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v3].tv,tangential);
-                               VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v4].tv,tangential);
-                               */
-                       }
-                       
-
-                       impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
-                       
-                       // printf("impulse: %f\n", impulse);
-                       
-                       VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); 
-                       cloth1->verts[collpair->ap1].impulse_count++;
-                       
-                       VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse); 
-                       cloth1->verts[collpair->ap2].impulse_count++;
-                       
-                       VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); 
-                       cloth1->verts[collpair->ap3].impulse_count++;
-                       
-                       result = 1;
-                       
-                       /*
-                       if (overlap > ALMOST_ZERO) {
-                       double I_mag  = overlap * 0.1;
-                               
-                       impulse = -I_mag / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
-                               
-                       VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); 
-                       cloth1->verts[collpair->ap1].impulse_count++;
-                                                       
-                       VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse); 
-                       cloth1->verts[collpair->ap2].impulse_count++;
-                       
-                       VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); 
-                       cloth1->verts[collpair->ap3].impulse_count++;
-               }
-                       */
-               
-                       // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case
-                       
-                       // Apply the impulse and increase impulse counters.
-
-                       /*                      
-                       // calculateFrictionImpulse(tangential, collvel, collpair->normal, magtangent, clmd->coll_parms.friction*0.01, magtangent);
-                       VECSUBS(vrel_t_pre, collvel, collpair->normal, magnormal);
-                       // VecMulf(vrel_t_pre, clmd->coll_parms.friction*0.01f/INPR(vrel_t_pre,vrel_t_pre));
-                       magtangent = Normalize(vrel_t_pre);
-                       VecMulf(vrel_t_pre, MIN2(clmd->coll_parms.friction*0.01f*magnormal,magtangent));
-                       
-                       VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,vrel_t_pre);
-                       */
-                       
-                       
-                       
-               }
-               
-               search = search->next;
-       }
-       
-               
-       return result;
-}
-
-void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
-{
-       CollPair *collpair = NULL;
-       Cloth *cloth1=NULL, *cloth2=NULL;
-       MFace *face1=NULL, *face2=NULL;
-       ClothVertex *verts1=NULL, *verts2=NULL;
-       double distance = 0;
-       float epsilon = clmd->coll_parms.epsilon;
-       unsigned int i = 0;
-
-       for(i = 0; i < 4; i++)
-       {
-               collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair");                
-               
-               cloth1 = clmd->clothObject;
-               cloth2 = coll_clmd->clothObject;
-               
-               verts1 = cloth1->verts;
-               verts2 = cloth2->verts;
-       
-               face1 = &(cloth1->mfaces[tree1->tri_index]);
-               face2 = &(cloth2->mfaces[tree2->tri_index]);
-               
-               // check all possible pairs of triangles
-               if(i == 0)
-               {
-                       collpair->ap1 = face1->v1;
-                       collpair->ap2 = face1->v2;
-                       collpair->ap3 = face1->v3;
-                       
-                       collpair->bp1 = face2->v1;
-                       collpair->bp2 = face2->v2;
-                       collpair->bp3 = face2->v3;
-                       
-               }
-               
-               if(i == 1)
-               {
-                       if(face1->v4)
-                       {
-                               collpair->ap1 = face1->v3;
-                               collpair->ap2 = face1->v4;
-                               collpair->ap3 = face1->v1;
-                               
-                               collpair->bp1 = face2->v1;
-                               collpair->bp2 = face2->v2;
-                               collpair->bp3 = face2->v3;
-                       }
-                       else
-                               i++;
-               }
-               
-               if(i == 2)
-               {
-                       if(face2->v4)
-                       {
-                               collpair->ap1 = face1->v1;
-                               collpair->ap2 = face1->v2;
-                               collpair->ap3 = face1->v3;
-                               
-                               collpair->bp1 = face2->v3;
-                               collpair->bp2 = face2->v4;
-                               collpair->bp3 = face2->v1;
-                       }
-                       else
-                               i+=2;
-               }
-               
-               if(i == 3)
-               {
-                       if((face1->v4)&&(face2->v4))
-                       {
-                               collpair->ap1 = face1->v3;
-                               collpair->ap2 = face1->v4;
-                               collpair->ap3 = face1->v1;
-                               
-                               collpair->bp1 = face2->v3;
-                               collpair->bp2 = face2->v4;
-                               collpair->bp3 = face2->v1;
-                       }
-                       else
-                               i++;
-               }
-               
-               // calc SIPcode (?)
-               
-               if(i < 4)
-               {
-                       // calc distance + normal       
-                       distance = plNearestPoints(
-                                       verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, verts2[collpair->bp1].txold, verts2[collpair->bp2].txold, verts2[collpair->bp3].txold, collpair->pa,collpair->pb,collpair->vector);
-                       
-                       if (distance <= (epsilon + ALMOST_ZERO))
-                       {
-                               // printf("dist: %f\n", (float)distance);
-                               
-                               // collpair->face1 = tree1->tri_index;
-                               // collpair->face2 = tree2->tri_index;
-                               
-                               VECCOPY(collpair->normal, collpair->vector);
-                               Normalize(collpair->normal);
-                               
-                               collpair->distance = distance;
-                               BLI_linklist_append(&clmd->coll_parms.collision_list, collpair);
-                       }
-                       else
-                       {
-                               MEM_freeN(collpair);
-                       }
-               }
-               else
-               {
-                       MEM_freeN(collpair);
-               }
-       }
-}
-
-int cloth_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair)
-{
-       Cloth *cloth1, *cloth2;
-       ClothVertex *verts1, *verts2;
-       float temp[3];
-        
-       cloth1 = clmd->clothObject;
-       cloth2 = coll_clmd->clothObject;
-       
-       verts1 = cloth1->verts;
-       verts2 = cloth2->verts;
-       
-       VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].xold);
-       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
-               return 1;
-       
-       VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].xold);
-       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
-               return 1;
-       
-       VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].xold);
-       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
-               return 1;
-       
-       VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].xold);
-       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
-               return 1;
-               
-       return 0;
-}
-
-void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
-{
-       EdgeCollPair edgecollpair;
-       Cloth *cloth1=NULL, *cloth2=NULL;
-       MFace *face1=NULL, *face2=NULL;
-       ClothVertex *verts1=NULL, *verts2=NULL;
-       double distance = 0;
-       float epsilon = clmd->coll_parms.epsilon;
-       unsigned int i = 0, j = 0, k = 0;
-       int numsolutions = 0;
-       float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
-       
-       cloth1 = clmd->clothObject;
-       cloth2 = coll_clmd->clothObject;
-       
-       verts1 = cloth1->verts;
-       verts2 = cloth2->verts;
-
-       face1 = &(cloth1->mfaces[tree1->tri_index]);
-       face2 = &(cloth2->mfaces[tree2->tri_index]);
-       
-       for( i = 0; i < 5; i++)
-       {
-               if(i == 0) 
-               {
-                       edgecollpair.p11 = face1->v1;
-                       edgecollpair.p12 = face1->v2;
-               }
-               else if(i == 1) 
-               {
-                       edgecollpair.p11 = face1->v2;
-                       edgecollpair.p12 = face1->v3;
-               }
-               else if(i == 2) 
-               {
-                       if(face1->v4) 
-                       {
-                               edgecollpair.p11 = face1->v3;
-                               edgecollpair.p12 = face1->v4;
-                       }
-                       else 
-                       {
-                               edgecollpair.p11 = face1->v3;
-                               edgecollpair.p12 = face1->v1;
-                               i+=5; // get out of here!
-                       }
-               }
-               else if(i == 3) 
-               {
-                       if(face1->v4) 
-                       {
-                               edgecollpair.p11 = face1->v4;
-                               edgecollpair.p12 = face1->v1;
-                       }       
-                       else
-                               continue;
-               }
-               else
-               {
-                       edgecollpair.p11 = face1->v3;
-                       edgecollpair.p12 = face1->v1;
-               }
-
-               
-               for( j = 0; j < 5; j++)
-               {
-                       if(j == 0)
-                       {
-                               edgecollpair.p21 = face2->v1;
-                               edgecollpair.p22 = face2->v2;
-                       }
-                       else if(j == 1)
-                       {
-                               edgecollpair.p21 = face2->v2;
-                               edgecollpair.p22 = face2->v3;
-                       }
-                       else if(j == 2)
-                       {
-                               if(face2->v4) 
-                               {
-                                       edgecollpair.p21 = face2->v3;
-                                       edgecollpair.p22 = face2->v4;
-                               }
-                               else 
-                               {
-                                       edgecollpair.p21 = face2->v3;
-                                       edgecollpair.p22 = face2->v1;
-                               }
-                       }
-                       else if(j == 3)
-                       {
-                               if(face2->v4) 
-                               {
-                                       edgecollpair.p21 = face2->v4;
-                                       edgecollpair.p22 = face2->v1;
-                               }
-                               else
-                                       continue;
-                       }
-                       else
-                       {
-                               edgecollpair.p21 = face2->v3;
-                               edgecollpair.p22 = face2->v1;
-                       }
-                       
-                       
-                       if(!cloth_are_edges_adjacent(clmd, coll_clmd, &edgecollpair))
-                       {
-                               VECSUB(a, verts1[edgecollpair.p12].xold, verts1[edgecollpair.p11].xold);
-                               VECSUB(b, verts1[edgecollpair.p12].v, verts1[edgecollpair.p11].v);
-                               VECSUB(c, verts1[edgecollpair.p21].xold, verts1[edgecollpair.p11].xold);
-                               VECSUB(d, verts1[edgecollpair.p21].v, verts1[edgecollpair.p11].v);
-                               VECSUB(e, verts2[edgecollpair.p22].xold, verts1[edgecollpair.p11].xold);
-                               VECSUB(f, verts2[edgecollpair.p22].v, verts1[edgecollpair.p11].v);
-                               
-                               numsolutions = cloth_get_collision_time(a, b, c, d, e, f, solution);
-                               
-                               for (k = 0; k < numsolutions; k++) 
-                               {                                                               
-                                       if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) 
-                                       {
-                                               float out_collisionTime = solution[k];
-                                               
-                                               // TODO: check for collisions 
-                                               
-                                               // TODO: put into collision list
-                                               
-                                               printf("Moving edge found!\n");
-                                       }
-                               }
-                       }
-               }
-       }
-               
-               
-       
-}
-
-void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
-{
-       CollPair collpair;
-       Cloth *cloth1=NULL, *cloth2=NULL;
-       MFace *face1=NULL, *face2=NULL;
-       ClothVertex *verts1=NULL, *verts2=NULL;
-       double distance = 0;
-       float epsilon = clmd->coll_parms.epsilon;
-       unsigned int i = 0, j = 0, k = 0;
-       int numsolutions = 0;
-       float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
-
-       for(i = 0; i < 2; i++)
-       {               
-               cloth1 = clmd->clothObject;
-               cloth2 = coll_clmd->clothObject;
-               
-               verts1 = cloth1->verts;
-               verts2 = cloth2->verts;
-       
-               face1 = &(cloth1->mfaces[tree1->tri_index]);
-               face2 = &(cloth2->mfaces[tree2->tri_index]);
-               
-               // check all possible pairs of triangles
-               if(i == 0)
-               {
-                       collpair.ap1 = face1->v1;
-                       collpair.ap2 = face1->v2;
-                       collpair.ap3 = face1->v3;
-                       
-                       collpair.pointsb[0] = face2->v1;
-                       collpair.pointsb[1] = face2->v2;
-                       collpair.pointsb[2] = face2->v3;
-                       collpair.pointsb[3] = face2->v4;
-               }
-               
-               if(i == 1)
-               {
-                       if(face1->v4)
-                       {
-                               collpair.ap1 = face1->v3;
-                               collpair.ap2 = face1->v4;
-                               collpair.ap3 = face1->v1;
-                               
-                               collpair.pointsb[0] = face2->v1;
-                               collpair.pointsb[1] = face2->v2;
-                               collpair.pointsb[2] = face2->v3;
-                               collpair.pointsb[3] = face2->v4;
-                       }
-                       else
-                               i++;
-               }
-               
-               // calc SIPcode (?)
-               
-               if(i < 2)
-               {
-                       VECSUB(a, verts1[collpair.ap2].xold, verts1[collpair.ap1].xold);
-                       VECSUB(b, verts1[collpair.ap2].v, verts1[collpair.ap1].v);
-                       VECSUB(c, verts1[collpair.ap3].xold, verts1[collpair.ap1].xold);
-                       VECSUB(d, verts1[collpair.ap3].v, verts1[collpair.ap1].v);
-                               
-                       for(j = 0; j < 4; j++)
-                       {                                       
-                               if((j==3) && !(face2->v4))
-                                       break;
-                               
-                               VECSUB(e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold);
-                               VECSUB(f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v);
-                               
-                               numsolutions = cloth_get_collision_time(a, b, c, d, e, f, solution);
-                               
-                               for (k = 0; k < numsolutions; k++) 
-                               {                                                               
-                                       if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) 
-                                       {
-                                               float out_collisionTime = solution[k];
-                                               
-                                               // TODO: check for collisions 
-                                               
-                                               // TODO: put into collision list
-                                               
-                                               printf("Moving found!\n");
-                                       }
-                               }
-                               
-                               // TODO: check borders for collisions
-                       }
-                       
-               }
-       }
-}
-
-void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
-{
-       // TODO: check for adjacent
-       cloth_collision_moving_edges(clmd, coll_clmd, tree1, tree2);
-       
-       cloth_collision_moving_tris(clmd, coll_clmd, tree1, tree2);
-       // cloth_collision_moving_tris(coll_clmd, clmd, tree2, tree1);
-}
-
-// move collision objects forward in time and update static bounding boxes
-void cloth_update_collision_objects(float step)
-{
-       Base *base=NULL;
-       ClothModifierData *coll_clmd=NULL;
-       Object *coll_ob=NULL;
-       unsigned int i=0;
-       
-       // search all objects for collision object
-       for (base = G.scene->base.first; base; base = base->next)
-       {
-
-               coll_ob = base->object;
-               coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
-               if (!coll_clmd)
-                       continue;
-
-               // if collision object go on
-               if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)
-               {
-                       if (coll_clmd->clothObject && coll_clmd->clothObject->tree) 
-                       {
-                               Cloth *coll_cloth = coll_clmd->clothObject;
-                               BVH *coll_bvh = coll_clmd->clothObject->tree;
-                               unsigned int coll_numverts = coll_cloth->numverts;
-
-                               // update position of collision object
-                               for(i = 0; i < coll_numverts; i++)
-                               {
-                                       VECCOPY(coll_cloth->verts[i].txold, coll_cloth->verts[i].tx);
-
-                                       VECADDS(coll_cloth->verts[i].tx, coll_cloth->verts[i].xold, coll_cloth->verts[i].v, step);
-                                       
-                                       // no dt here because of float rounding errors
-                                       VECSUB(coll_cloth->verts[i].tv, coll_cloth->verts[i].tx, coll_cloth->verts[i].txold);
-                               }
-                               
-                               // update BVH of collision object
-                               bvh_update(coll_clmd, coll_bvh, 0); // 0 means STATIC, 1 means MOVING 
-                       }
-                       else
-                               printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
-               }
-       }
-}
-
-// CLOTH_MAX_THRESHOLD defines how much collision rounds/loops should be taken
-#define CLOTH_MAX_THRESHOLD 10
-
-// cloth - object collisions
-int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
-{
-       Base *base=NULL;
-       ClothModifierData *coll_clmd=NULL;
-       Cloth *cloth=NULL;
-       Object *coll_ob=NULL;
-       BVH *cloth_bvh=NULL;
-       unsigned int i=0, j = 0, numfaces = 0, numverts = 0;
-       unsigned int result = 0, ic = 0, rounds = 0; // result counts applied collisions; ic is for debug output; 
-       ClothVertex *verts = NULL;
-       float tnull[3] = {0,0,0};
-       int ret = 0;
-
-       if ((clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree))
-       {
-               return 0;
-       }
-       cloth = clmd->clothObject;
-       verts = cloth->verts;
-       cloth_bvh = (BVH *) cloth->tree;
-       numfaces = clmd->clothObject->numfaces;
-       numverts = clmd->clothObject->numverts;
-       
-       ////////////////////////////////////////////////////////////
-       // static collisions
-       ////////////////////////////////////////////////////////////
-
-       // update cloth bvh
-       bvh_update(clmd, cloth_bvh, 0); // 0 means STATIC, 1 means MOVING (see later in this function)
-       
-       // update collision objects
-       cloth_update_collision_objects(step);
-       
-       do
-       {
-               result = 0;
-               ic = 0;
-               clmd->coll_parms.collision_list = NULL; 
-               
-               // check all collision objects
-               for (base = G.scene->base.first; base; base = base->next)
-               {
-                       coll_ob = base->object;
-                       coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
-                       
-                       if (!coll_clmd)
-                               continue;
-                       
-                       // if collision object go on
-                       if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)
-                       {
-                               if (coll_clmd->clothObject && coll_clmd->clothObject->tree) 
-                               {
-                                       BVH *coll_bvh = coll_clmd->clothObject->tree;
-                                       
-                                       bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_static);
-                               }
-                               else
-                                       printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
-                       }
-               }
-               
-               // process all collisions (calculate impulses, TODO: also repulses if distance too short)
-               result = 1;
-               for(j = 0; j < 50; j++) // 50 is just a value that ensures convergence
-               {
-                       result = 0;
-                       
-                       // handle all collision objects
-                       for (base = G.scene->base.first; base; base = base->next)
-                       {
-               
-                               coll_ob = base->object;
-                               coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
-                               if (!coll_clmd)
-                                       continue;
-               
-                               // if collision object go on
-                               if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)
-                               {
-                                       if (coll_clmd->clothObject) 
-                                               result += cloth_collision_response_static(clmd, coll_clmd);
-                                       else
-                                               printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
-                               }
-                       }
-                       
-                       // apply impulses in parallel
-                       ic=0;
-                       for(i = 0; i < numverts; i++)
-                       {
-                               // calculate "velocities" (just xnew = xold + v; no dt in v)
-                               if(verts[i].impulse_count)
-                               {
-                                       VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count);
-                                       VECCOPY(verts[i].impulse, tnull);
-                                       verts[i].impulse_count = 0;
-                               
-                                       ic++;
-                                       ret++;
-                               }
-                       }
-               }
-               
-               // free collision list
-               if(clmd->coll_parms.collision_list)
-               {
-                       LinkNode *search = clmd->coll_parms.collision_list;
-                       while(search)
-                       {
-                               CollPair *coll_pair = search->link;
-                                                       
-                               MEM_freeN(coll_pair);
-                               search = search->next;
-                       }
-                       BLI_linklist_free(clmd->coll_parms.collision_list,NULL);
-                       
-                       clmd->coll_parms.collision_list = NULL;
-               }
-               
-               printf("ic: %d\n", ic);
-               rounds++;
-       }
-       while(result && (CLOTH_MAX_THRESHOLD>rounds));
-       
-       printf("\n");
-                       
-       ////////////////////////////////////////////////////////////
-       // update positions
-       // this is needed for bvh_calc_DOP_hull_moving() [kdop.c]
-       ////////////////////////////////////////////////////////////
-       
-       // verts come from clmd
-       for(i = 0; i < numverts; i++)
-       {
-               VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
-       }
-       ////////////////////////////////////////////////////////////
-
-       ////////////////////////////////////////////////////////////
-       // moving collisions
-       ////////////////////////////////////////////////////////////
-
-       
-       // update cloth bvh
-       bvh_update(clmd, cloth_bvh, 1);  // 0 means STATIC, 1 means MOVING 
-       
-       // update moving bvh for collision object once
-       for (base = G.scene->base.first; base; base = base->next)
-       {
-               
-               coll_ob = base->object;
-               coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
-               if (!coll_clmd)
-                       continue;
-               
-               if(!coll_clmd->clothObject)
-                       continue;
-               
-                               // if collision object go on
-               if (coll_clmd->clothObject && coll_clmd->clothObject->tree) 
-               {
-                       BVH *coll_bvh = coll_clmd->clothObject->tree;
-                       
-                       bvh_update(coll_clmd, coll_bvh, 1);  // 0 means STATIC, 1 means MOVING  
-               }
-       }
-       
-       
-       do
-       {
-               result = 0;
-               ic = 0;
-               clmd->coll_parms.collision_list = NULL; 
-               
-               // check all collision objects
-               for (base = G.scene->base.first; base; base = base->next)
-               {
-                       coll_ob = base->object;
-                       coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
-                       
-                       if (!coll_clmd)
-                               continue;
-                       
-                       // if collision object go on
-                       if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)
-                       {
-                               if (coll_clmd->clothObject && coll_clmd->clothObject->tree) 
-                               {
-                                       BVH *coll_bvh = coll_clmd->clothObject->tree;
-                                       
-                                       bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_moving);
-                               }
-                               else
-                                       printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
-                       }
-               }
-               /*
-               // process all collisions (calculate impulses, TODO: also repulses if distance too short)
-               result = 1;
-               for(j = 0; j < 50; j++) // 50 is just a value that ensures convergence
-               {
-               result = 0;
-                       
-                       // handle all collision objects
-               for (base = G.scene->base.first; base; base = base->next)
-               {
-               
-               coll_ob = base->object;
-               coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
-                               
-               if (!coll_clmd)
-               continue;
-               
-                               // if collision object go on
-               if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)
-               {
-               if (coll_clmd->clothObject) 
-               result += cloth_collision_response_moving_tris(clmd, coll_clmd);
-               else
-               printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
-       }
-       }
-                       
-                       // apply impulses in parallel
-               ic=0;
-               for(i = 0; i < numverts; i++)
-               {
-                               // calculate "velocities" (just xnew = xold + v; no dt in v)
-               if(verts[i].impulse_count)
-               {
-               VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count);
-               VECCOPY(verts[i].impulse, tnull);
-               verts[i].impulse_count = 0;
-                               
-               ic++;
-               ret++;
-       }
-       }
-       }
-               */
-               
-               // verts come from clmd
-               for(i = 0; i < numverts; i++)
-               {
-                       VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
-               }
-               
-               // update cloth bvh
-               bvh_update(clmd, cloth_bvh, 1);  // 0 means STATIC, 1 means MOVING 
-               
-               
-               // free collision list
-               if(clmd->coll_parms.collision_list)
-               {
-                       LinkNode *search = clmd->coll_parms.collision_list;
-                       while(search)
-                       {
-                               CollPair *coll_pair = search->link;
-                                                       
-                               MEM_freeN(coll_pair);
-                               search = search->next;
-                       }
-                       BLI_linklist_free(clmd->coll_parms.collision_list,NULL);
-                       
-                       clmd->coll_parms.collision_list = NULL;
-               }
-               
-               printf("ic: %d\n", ic);
-               rounds++;
-       }
-       while(result && (CLOTH_MAX_THRESHOLD>rounds));
-       
-       
-       ////////////////////////////////////////////////////////////
-       // update positions + velocities
-       ////////////////////////////////////////////////////////////
-       
-       // verts come from clmd
-       for(i = 0; i < numverts; i++)
-       {
-               VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
-       }
-       ////////////////////////////////////////////////////////////
-
-       return MIN2(ret, 1);
-}