Restructured many collision things again, GUI cleanup
authorDaniel Genrich <daniel.genrich@gmx.net>
Mon, 21 Jan 2008 02:23:03 +0000 (02:23 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Mon, 21 Jan 2008 02:23:03 +0000 (02:23 +0000)
source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/BKE_collisions.h
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/kdop.c
source/blender/blenkernel/intern/modifier.c
source/blender/makesdna/DNA_cloth_types.h
source/blender/src/buttons_object.c

index eb1f33ae6005429d14acfd0a97ef9b28558f370d..592c34ad28ed810d143ea3857510928bbac06f0b 100644 (file)
@@ -129,38 +129,39 @@ void implicit_set_positions ( ClothModifierData *clmd );
 void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, float ( *vertexCos ) [3], int numverts );
 
 // used in collision.c
-typedef struct Tree
+typedef struct CollisionTree
 {
-       struct Tree *nodes[4]; // 4 children --> quad-tree
-       struct Tree *parent;
-       struct Tree *nextLeaf;
-       struct Tree *prevLeaf;
+       struct CollisionTree *nodes[4]; // 4 children --> quad-tree
+       struct CollisionTree *parent;
+       struct CollisionTree *nextLeaf;
+       struct CollisionTree *prevLeaf;
        float   bv[26]; // Bounding volume of all nodes / we have 7 axes on a 14-DOP
        unsigned int tri_index; // this saves the index of the face
+       // int point_index[4]; // supports up to 4 points in a leaf
        int     count_nodes; // how many nodes are used
        int     traversed;  // how many nodes already traversed until this level?
        int     isleaf;
 }
-Tree;
-
-typedef struct Tree TreeNode;
+CollisionTree;
 
 typedef struct BVH
 {
        unsigned int    numfaces;
        unsigned int    numverts;
-       ClothVertex     *verts; // just a pointer to the original datastructure
+       // ClothVertex  *verts; // just a pointer to the original datastructure
+       MVert           *current_x; // e.g. txold in clothvertex
+       MVert           *current_xold; // e.g. tx in clothvertex
        MFace           *mfaces; // just a pointer to the original datastructure
        struct LinkNode *tree;
-       TreeNode        *root; // TODO: saving the root --> is this really needed? YES!
-       TreeNode        *leaf_tree; /* Tail of the leaf linked list.    */
-       TreeNode        *leaf_root;     /* Head of the leaf linked list.        */
+       CollisionTree   *root; // TODO: saving the root --> is this really needed? YES!
+       CollisionTree   *leaf_tree; /* Tail of the leaf linked list.    */
+       CollisionTree   *leaf_root;     /* Head of the leaf linked list.        */
        float           epsilon; /* epslion is used for inflation of the k-dop     */
        int             flags; /* bvhFlags */
 }
 BVH;
 
-typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2 );
+typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree * tree1, CollisionTree * tree2 );
 
 
 /////////////////////////////////////////////////
@@ -168,9 +169,15 @@ typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, ClothModifier
 ////////////////////////////////////////////////
 
 // needed for implicit.c
-void bvh_collision_response ( ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2 );
+void bvh_collision_response ( ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree * tree1, CollisionTree * tree2 );
 int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt );
 
+// needed for modifier.c
+BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon);
+
+// needed for collision.c
+void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving);
+
 ////////////////////////////////////////////////
 
 
@@ -180,13 +187,12 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt );
 
 // needed for cloth.c
 void bvh_free ( BVH * bvh );
-BVH *bvh_build ( ClothModifierData *clmd, float epsilon );
+void bvh_build (BVH *bvh);
 LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr );
 
 // needed for collision.c
-int bvh_traverse ( ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * tree1, Tree * tree2, float step, CM_COLLISION_RESPONSE collision_response );
-void bvh_update ( ClothModifierData * clmd, BVH * bvh, int moving );
-
+int bvh_traverse ( ClothModifierData * clmd, ClothModifierData * coll_clmd, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response );
+void bvh_update(BVH * bvh, int moving);
 ////////////////////////////////////////////////
 
 
@@ -199,6 +205,9 @@ void cloth_init ( ClothModifierData *clmd );
 void cloth_deform_verts ( struct Object *ob, float framenr, float ( *vertexCos ) [3], int numVerts, void *derivedData, ClothModifierData *clmd );
 void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int totface );
 
+// needed for collision.c
+void bvh_update_from_cloth(ClothModifierData *clmd, int moving);
+
 ////////////////////////////////////////////////
 
 
index e38662fdf95d332358c21974a8b454ae3f9942ad..f0f6212d3f52ea9a2335c6e2fdc489df89b1f6d3 100644 (file)
@@ -79,6 +79,7 @@ typedef struct BVH
 }
 BVH;
 
+
 /* used for collisions in kdop.c and also collision.c*/
 typedef struct CollisionPair
 {
index fef932174a1f8e46781d314aff3713aa311c490a..c68fb983fc955ce0b41a025bc1bef26fdbc20675 100644 (file)
@@ -160,6 +160,7 @@ void cloth_init ( ClothModifierData *clmd )
        clmd->sim_parms.maxspringlen = 10;
        clmd->sim_parms.firstframe = 1;
        clmd->sim_parms.lastframe = 250;
+       clmd->sim_parms.vgroup_mass = 0;
        clmd->coll_parms.self_friction = 5.0;
        clmd->coll_parms.friction = 10.0;
        clmd->coll_parms.loop_count = 1;
@@ -175,13 +176,91 @@ void cloth_init ( ClothModifierData *clmd )
        // also from softbodies
        clmd->sim_parms.maxgoal = 1.0f;
        clmd->sim_parms.mingoal = 0.0f;
-       clmd->sim_parms.defgoal = 0.7f;
+       clmd->sim_parms.defgoal = 0.0f;
        clmd->sim_parms.goalspring = 100.0f;
        clmd->sim_parms.goalfrict = 0.0f;
 
        clmd->sim_parms.cache = NULL;
 }
 
+
+BVH *bvh_build_from_cloth (ClothModifierData *clmd, float epsilon)
+{
+       unsigned int i = 0;
+       BVH     *bvh=NULL;
+       Cloth *cloth = clmd->clothObject;
+       ClothVertex *verts = NULL;
+
+       if(!clmd)
+               return NULL;
+
+       cloth = clmd->clothObject;
+
+       if(!cloth)
+               return NULL;
+       
+       verts = cloth->verts;
+       
+       bvh = MEM_callocN(sizeof(BVH), "BVH");
+       if (bvh == NULL) 
+       {
+               printf("bvh: Out of memory.\n");
+               return NULL;
+       }
+       
+       // springs = cloth->springs;
+       // numsprings = cloth->numsprings;
+       
+       bvh->flags = 0;
+       bvh->leaf_tree = NULL;
+       bvh->leaf_root = NULL;
+       bvh->tree = NULL;
+
+       bvh->epsilon = epsilon;
+       bvh->numfaces = cloth->numfaces;
+       bvh->mfaces = cloth->mfaces;
+
+       bvh->numverts = cloth->numverts;
+       
+       bvh->current_x = MEM_callocN ( sizeof ( MVert ) * bvh->numverts, "bvh->current_x" );
+       bvh->current_xold = MEM_callocN ( sizeof ( MVert ) * bvh->numverts, "bvh->current_xold" );
+       
+       for(i = 0; i < bvh->numverts; i++)
+       {
+               VECCOPY(bvh->current_x[i].co, verts[i].tx);
+               VECCOPY(bvh->current_xold[i].co, verts[i].txold);
+       }
+       
+       bvh_build (bvh);
+       
+       return bvh;
+}
+
+void bvh_update_from_cloth(ClothModifierData *clmd, int moving)
+{
+       unsigned int i = 0;
+       Cloth *cloth = clmd->clothObject;
+       BVH *bvh = cloth->tree;
+       ClothVertex *verts = cloth->verts;
+       
+       if(!bvh)
+               return;
+       
+       if(cloth->numverts!=bvh->numverts)
+               return;
+       
+       if(cloth->verts)
+       {
+               for(i = 0; i < bvh->numverts; i++)
+               {
+                       VECCOPY(bvh->current_x[i].co, verts[i].tx);
+                       VECCOPY(bvh->current_xold[i].co, verts[i].txold);
+               }
+       }
+       
+       bvh_update(bvh, moving);
+}
+
 // unused in the moment, cloth needs quads from mesh
 DerivedMesh *CDDM_convert_to_triangle ( DerivedMesh *dm )
 {
@@ -433,9 +512,9 @@ static void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr
        
        for(a = 0; a < cloth->numverts; a++)
        {
-               fwrite(&cloth->verts[a].x, sizeof(float),4,fp);
-               fwrite(&cloth->verts[a].xconst, sizeof(float),4,fp);
-               fwrite(&cloth->verts[a].v, sizeof(float),4,fp);
+               fwrite(&cloth->verts[a].x, sizeof(float),3,fp);
+               fwrite(&cloth->verts[a].xconst, sizeof(float),3,fp);
+               fwrite(&cloth->verts[a].v, sizeof(float),3,fp);
        }
        
        fclose(fp);
@@ -458,17 +537,17 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
        else {
                for(a = 0; a < cloth->numverts; a++)
                {
-                       if(fread(&cloth->verts[a].x, sizeof(float), 4, fp) != 4
+                       if(fread(&cloth->verts[a].x, sizeof(float), 3, fp) != 3
                        {
                                ret = 0;
                                break;
                        }
-                       if(fread(&cloth->verts[a].xconst, sizeof(float), 4, fp) != 4
+                       if(fread(&cloth->verts[a].xconst, sizeof(float), 3, fp) != 3
                        {
                                ret = 0;
                                break;
                        }
-                       if(fread(&cloth->verts[a].v, sizeof(float), 4, fp) != 4
+                       if(fread(&cloth->verts[a].v, sizeof(float), 3, fp) != 3
                        {
                                ret = 0;
                                break;
@@ -656,7 +735,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
                                        solvers [clmd->sim_parms.solver_type].solver ( ob, framenr, clmd, effectors );
 
                                tend();
-                               printf ( "Cloth simulation time: %f\n", ( float ) tval() );
+                               // printf ( "Cloth simulation time: %f\n", ( float ) tval() );
 
                                cloth_write_cache(ob, clmd, framenr);
 
@@ -830,7 +909,13 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short
                                        {
                                                verts->goal = dvert->dw [j].weight;
 
-                                               goalfac= ABS ( clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal );
+                                               goalfac= 1.0f;
+                                               
+                                               /*
+                                               // Kicking goal factor to simplify things...who uses that anyway?
+                                               // ABS ( clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal );
+                                               */
+                                               
                                                verts->goal  = ( float ) pow ( verts->goal , 4.0f );
 
                                                if ( dvert->dw [j].weight >=SOFTGOALSNAP )
@@ -905,7 +990,7 @@ static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMes
                                        verts->impulse_count = 0;
                                        VECCOPY ( verts->impulse, tnull );
                                }
-                               clmd->clothObject->tree =  bvh_build ( clmd,clmd->coll_parms.epsilon );
+                               clmd->clothObject->tree =  bvh_build_from_cloth ( clmd,clmd->coll_parms.epsilon );
 
                        }
 
@@ -1012,7 +1097,7 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh
                                if ( solvers [clmd->sim_parms.solver_type].init )
                                        solvers [clmd->sim_parms.solver_type].init ( ob, clmd );
 
-                               clmd->clothObject->tree = bvh_build ( clmd, clmd->coll_parms.epsilon );
+                               clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms.epsilon );
 
                                cloth_write_cache(ob, clmd, framenr-1);
                        }
index 4a03f579fe84fa29692fe0278d4285ef1a3083c8..4ab436b2936d7485187319d9a083e14171f0fdcd 100644 (file)
 
 #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 prevstep)
+{
+       float tv[3] = {0,0,0};
+       unsigned int i = 0;
+       
+       for ( i = 0; i < collmd->numverts; i++ )
+       {
+               VECSUB(tv, collmd->xnew[i].co, collmd->x[i].co);
+               VECADDS(collmd->current_x[i].co, collmd->x[i].co, tv, prevstep);
+               VECADDS(collmd->current_xnew[i].co, collmd->x[i].co, tv, step);
+               VECSUB(collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co);
+       }
+}
 
+BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon)
+{
+       BVH *bvh=NULL;
+       
+       bvh = MEM_callocN(sizeof(BVH), "BVH");
+       if (bvh == NULL) 
+       {
+               printf("bvh: Out of memory.\n");
+               return NULL;
+       }
+       
+       bvh->flags = 0;
+       bvh->leaf_tree = NULL;
+       bvh->leaf_root = NULL;
+       bvh->tree = NULL;
+
+       bvh->epsilon = epsilon;
+       bvh->numfaces = numfaces;
+       bvh->mfaces = mfaces;
+       
+       // we have no faces, we save seperate points
+       if(!mfaces)
+       {
+               bvh->numfaces = numverts;
+       }
+
+       bvh->numverts = numverts;
+       bvh->current_x = MEM_dupallocN(x);      
+       bvh->current_xold = MEM_dupallocN(x);   
+       
+       bvh_build(bvh);
+       
+       return bvh;
+}
+
+void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving)
+{
+       if(!bvh)
+               return;
+       
+       if(numverts!=bvh->numverts)
+               return;
+       
+       if(x)
+               memcpy(bvh->current_xold, x, sizeof(MVert) * numverts);
+       
+       if(xnew)
+               memcpy(bvh->current_x, xnew, sizeof(MVert) * numverts);
+       
+       bvh_update(bvh, moving);
+}
 
 /**
  * gsl_poly_solve_cubic -
@@ -519,7 +584,7 @@ int cloth_collision_response_moving_edges(ClothModifierData *clmd, ClothModifier
        
 }
 
-void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
+void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
 {
        CollPair *collpair = NULL;
        Cloth *cloth1=NULL, *cloth2=NULL;
@@ -667,7 +732,7 @@ int cloth_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_cl
        return 0;
 }
 
-void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
+void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
 {
        EdgeCollPair edgecollpair;
        Cloth *cloth1=NULL, *cloth2=NULL;
@@ -802,7 +867,7 @@ void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *co
        }               
 }
 
-void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
+void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
 {
        CollPair collpair;
        Cloth *cloth1=NULL, *cloth2=NULL;
@@ -896,7 +961,7 @@ void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *col
        }
 }
 
-void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
+void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
 {
        // TODO: check for adjacent
        cloth_collision_moving_edges(clmd, coll_clmd, tree1, tree2);
@@ -943,7 +1008,7 @@ void cloth_update_collision_objects(float step)
                                }
                                
                                // update BVH of collision object
-                               bvh_update(coll_clmd, coll_bvh, 0); // 0 means STATIC, 1 means MOVING 
+                               bvh_update_from_cloth(coll_clmd, 0); // 0 means STATIC, 1 means MOVING 
                        }
                        else
                                printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
@@ -972,6 +1037,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
        {
                return 0;
        }
+       
        cloth = clmd->clothObject;
        verts = cloth->verts;
        cloth_bvh = (BVH *) cloth->tree;
@@ -983,7 +1049,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
        ////////////////////////////////////////////////////////////
 
        // update cloth bvh
-       bvh_update(clmd, cloth_bvh, 0); // 0 means STATIC, 1 means MOVING (see later in this function)
+       bvh_update_from_cloth(clmd, 0); // 0 means STATIC, 1 means MOVING (see later in this function)
        
        // update collision objects
        cloth_update_collision_objects(step);
@@ -1075,12 +1141,12 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
                        clmd->coll_parms.collision_list = NULL;
                }
                
-               printf("ic: %d\n", ic);
+               // printf("ic: %d\n", ic);
                rounds++;
        }
        while(result && (CLOTH_MAX_THRESHOLD>rounds));
        
-       printf("\n");
+       // printf("\n");
                        
        ////////////////////////////////////////////////////////////
        // update positions
@@ -1100,7 +1166,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
 
        
        // update cloth bvh
-       bvh_update(clmd, cloth_bvh, 1);  // 0 means STATIC, 1 means MOVING 
+       bvh_update_from_cloth(clmd, 1);  // 0 means STATIC, 1 means MOVING 
        
        // update moving bvh for collision object once
        for (base = G.scene->base.first; base; base = base->next)
@@ -1119,7 +1185,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
                {
                        BVH *coll_bvh = coll_clmd->clothObject->tree;
                        
-                       bvh_update(coll_clmd, coll_bvh, 1);  // 0 means STATIC, 1 means MOVING  
+                       bvh_update_from_cloth(coll_clmd, 1);  // 0 means STATIC, 1 means MOVING         
                }
        }
        
@@ -1204,7 +1270,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
                }
                
                // update cloth bvh
-               bvh_update(clmd, cloth_bvh, 1);  // 0 means STATIC, 1 means MOVING 
+               bvh_update_from_cloth(clmd, 1);  // 0 means STATIC, 1 means MOVING 
                
                
                // free collision list
@@ -1223,7 +1289,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
                        clmd->coll_parms.collision_list = NULL;
                }
                
-               printf("ic: %d\n", ic);
+               // printf("ic: %d\n", ic);
                rounds++;
        }
        while(result && (CLOTH_MAX_THRESHOLD>rounds));
index 74b5b3d7b7f79be5c16f051b5f64e16d6ac6f351..ed1da4d19f98c7d8e8800eebf0091f411e5b6a8a 100644 (file)
@@ -1,4 +1,4 @@
-/*  collision.c      
+/*  kdop.c      
 * 
 *
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
@@ -38,6 +38,7 @@
 #include "DNA_curve_types.h"
 #include "DNA_object_types.h"
 #include "DNA_object_force.h"
+#include "DNA_cloth_types.h"   
 #include "DNA_key_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
@@ -58,7 +59,7 @@
 #include "BKE_key.h"
 #include "BKE_mesh.h"
 #include "BKE_object.h"
-#include "BKE_collisions.h"
+#include "BKE_cloth.h"
 #include "BKE_modifier.h"
 #include "BKE_utildefines.h"
 #include "BKE_DerivedMesh.h"
@@ -164,13 +165,13 @@ static int size_threshold = 16;
 /*
 * Common methods for all algorithms
 */
-void bvh_exchange(CollisionTree **a, int i, int j)
+DO_INLINE void bvh_exchange(CollisionTree **a, int i, int j)
 {
        CollisionTree *t=a[i];
        a[i]=a[j];
        a[j]=t;
 }
-int floor_lg(int a)
+DO_INLINE int floor_lg(int a)
 {
        return (int)(floor(log(a)/log(2)));
 }
@@ -195,7 +196,7 @@ static void bvh_insertionsort(CollisionTree **a, int lo, int hi, int axis)
        }
 }
 
-static int bvh_partition(CollisionTree **a, int lo, int hi, CollisionTree *x, int axis)
+static int bvh_partition(CollisionTree **a, int lo, int hi, CollisionTree * x, int axis)
 {
        int i=lo, j=hi;
        while (1)
@@ -215,7 +216,7 @@ static int bvh_partition(CollisionTree **a, int lo, int hi, CollisionTree *x, in
 */
 static void bvh_downheap(CollisionTree **a, int i, int n, int lo, int axis)
 {
-       CollisionTree *d = a[lo+i-1];
+       CollisionTree * d = a[lo+i-1];
        int child;
        while (i<=n/2)
        {
@@ -293,7 +294,7 @@ static void bvh_introsort_loop (CollisionTree **a, int lo, int hi, int depth_lim
        }
 }
 
-void bvh_sort(CollisionTree **a0, int begin, int end, int axis)
+DO_INLINE void bvh_sort(CollisionTree **a0, int begin, int end, int axis)
 {
        if (begin < end)
        {
@@ -302,7 +303,7 @@ void bvh_sort(CollisionTree **a0, int begin, int end, int axis)
                bvh_insertionsort(a, begin, end, axis);
        }
 }
-void bvh_sort_along_axis(CollisionTree **face_list, int start, int end, int axis)
+DO_INLINE void bvh_sort_along_axis(CollisionTree **face_list, int start, int end, int axis)
 {
        bvh_sort(face_list, start, end, axis);
 }
@@ -330,11 +331,11 @@ void bvh_free(BVH * bvh)
                BLI_linklist_free(bvh->tree,NULL); 
                bvh->tree = NULL;
                
-               if(bvh->x)
-                       MEM_freeN(bvh->x);
-               if(bvh->xnew)
-                       MEM_freeN(bvh->xnew);
-               
+               if(bvh->current_x)
+                       MEM_freeN(bvh->current_x);
+               if(bvh->current_xold)
+                       MEM_freeN(bvh->current_xold);
+
                MEM_freeN(bvh);
                bvh = NULL;
        }
@@ -342,7 +343,7 @@ void bvh_free(BVH * bvh)
 
 // only supports x,y,z axis in the moment
 // but we should use a plain and simple function here for speed sake
-int bvh_largest_axis(float *bv)
+DO_INLINE int bvh_largest_axis(float *bv)
 {
        float middle_point[3];
 
@@ -366,7 +367,7 @@ int bvh_largest_axis(float *bv)
 }
 
 // depends on the fact that the BVH's for each face is already build
-void bvh_calc_DOP_hull_from_faces(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
+DO_INLINE void bvh_calc_DOP_hull_from_faces(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
 {
        float newmin,newmax;
        int i, j;
@@ -390,62 +391,79 @@ void bvh_calc_DOP_hull_from_faces(BVH * bvh, CollisionTree **tri, int numfaces,
        }
 }
 
-void bvh_calc_DOP_hull_static(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
+DO_INLINE void bvh_calc_DOP_hull_static(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
 {
-       MVert *tempMVert = bvh->x;
+       MFace *tempMFace = bvh->mfaces;
        float *tempBV = bv;
        float newminmax;
        int i, j, k;
        for (j = 0; j < numfaces; j++)
        {
-               // 1 up to 4 vertices per leaf. 
+               tempMFace = bvh->mfaces + (tri [j])->tri_index;
+               // 3 or 4 vertices per face.
                for (k = 0; k < 4; k++)
                {
-                       int temp = tri[j]->point_index[k];
-                       
-                       if(temp < 0)
+                       int temp = 0;  
+                       // If this is a triangle.
+                       if (k == 3 && !tempMFace->v4)
                                continue;
-                       
+                       // TODO: other name for "temp" this gets all vertices of a face
+                       if (k == 0)
+                               temp = tempMFace->v1;
+                       else if (k == 1)
+                               temp = tempMFace->v2;
+                       else if (k == 2)
+                               temp = tempMFace->v3;
+                       else if (k == 3)
+                               temp = tempMFace->v4;
                        // for all Axes.
                        for (i = KDOP_START; i < KDOP_END; i++)
                        {                               
-                               newminmax = INPR(tempMVert[temp].co, KDOP_AXES[i]);
+                               newminmax = INPR(bvh->current_xold[temp].co, KDOP_AXES[i]);
                                if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0))
                                        tempBV[(2 * i)] = newminmax;
                                if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0))
                                        tempBV[(2 * i) + 1] = newminmax;
-                       }                       
+                       }
                }
        }
 }
 
-void bvh_calc_DOP_hull_moving(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
+DO_INLINE void bvh_calc_DOP_hull_moving(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
 {
-       MVert *tempMVert = bvh->x;
-       MVert *tempMVert2 = bvh->xnew;
+       MFace *tempMFace = bvh->mfaces;
        float *tempBV = bv;
        float newminmax;
        int i, j, k;
        for (j = 0; j < numfaces; j++)
        {
+               tempMFace = bvh->mfaces + (tri [j])->tri_index;
                // 3 or 4 vertices per face.
                for (k = 0; k < 4; k++)
                {
-                       int temp = tri[j]->point_index[k];
-                       
-                       if(temp < 0)
+                       int temp = 0;  
+                       // If this is a triangle.
+                       if (k == 3 && !tempMFace->v4)
                                continue;
-                       
+                       // TODO: other name for "temp" this gets all vertices of a face
+                       if (k == 0)
+                               temp = tempMFace->v1;
+                       else if (k == 1)
+                               temp = tempMFace->v2;
+                       else if (k == 2)
+                               temp = tempMFace->v3;
+                       else if (k == 3)
+                               temp = tempMFace->v4;
                        // for all Axes.
                        for (i = KDOP_START; i < KDOP_END; i++)
                        {                               
-                               newminmax = INPR(tempMVert[temp].co, KDOP_AXES[i]);
+                               newminmax = INPR(bvh->current_xold[temp].co, KDOP_AXES[i]);
                                if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0))
                                        tempBV[(2 * i)] = newminmax;
                                if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0))
                                        tempBV[(2 * i) + 1] = newminmax;
                                
-                               newminmax = INPR(tempMVert2[temp].co, KDOP_AXES[i]);
+                               newminmax = INPR(bvh->current_x[temp].co, KDOP_AXES[i]);
                                if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0))
                                        tempBV[(2 * i)] = newminmax;
                                if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0))
@@ -455,7 +473,7 @@ void bvh_calc_DOP_hull_moving(BVH * bvh, CollisionTree **tri, int numfaces, floa
        }
 }
 
-static void bvh_div_env_node(BVH * bvh, TreeNode *tree, CollisionTree **face_list, unsigned int start, unsigned int end, int lastaxis, LinkNode *nlink)
+static void bvh_div_env_node(BVH *bvh, CollisionTree *tree, CollisionTree **face_list, unsigned int start, unsigned int end, int lastaxis, LinkNode *nlink)
 {
        int             i = 0;
        CollisionTree *newtree = NULL;
@@ -523,17 +541,26 @@ static void bvh_div_env_node(BVH * bvh, TreeNode *tree, CollisionTree **face_lis
        return;
 }
 
-// mfaces is allowed to be null
-// just vertexes are used if mfaces=NULL
-BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces)
+/* function cannot be directly called - needs alloced bvh */
+void bvh_build (BVH *bvh)
 {
-       unsigned int i = 0, j = 0;
+       unsigned int i = 0, j = 0, k = 0;
        CollisionTree **face_list=NULL;
        CollisionTree *tree=NULL;
        LinkNode *nlink = NULL;
        
+       tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
+       // TODO: check succesfull alloc
+       BLI_linklist_append(&bvh->tree, tree);
+
        nlink = bvh->tree;
 
+       if (tree == NULL) 
+       {
+               printf("bvh_build: Out of memory for nodes.\n");
+               bvh_free(bvh);
+               return;
+       }
        bvh->root = bvh->tree->link;
        bvh->root->isleaf = 0;
        bvh->root->parent = NULL;
@@ -541,25 +568,7 @@ BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces)
 
        if(bvh->numfaces<=1)
        {
-               // Why that? --> only one face there
-               if(bvh->mfaces)
-               {
-                       bvh->root->point_index[0] = mfaces[0].v1;
-                       bvh->root->point_index[1] = mfaces[0].v2;
-                       bvh->root->point_index[2] = mfaces[0].v3;
-                       if(mfaces[0].v4)
-                               bvh->root->point_index[3] = mfaces[0].v4;
-                       else
-                               bvh->root->point_index[3] = -1;
-               }
-               else
-               {
-                       bvh->root->point_index[0] = 0;
-                       bvh->root->point_index[1] = -1;
-                       bvh->root->point_index[2] = -1;
-                       bvh->root->point_index[3] = -1;
-               }
-               
+               bvh->root->tri_index = 0;       // Why that? --> only one face there 
                bvh->root->isleaf = 1;
                bvh->root->traversed = 0;
                bvh->root->count_nodes = 0;
@@ -569,46 +578,28 @@ BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces)
                bvh->root->prevLeaf = NULL;
        }
        else
-       {       
+       {
                // create face boxes            
                face_list = MEM_callocN (bvh->numfaces * sizeof (CollisionTree *), "CollisionTree");
                if (face_list == NULL) 
                {
                        printf("bvh_build: Out of memory for face_list.\n");
                        bvh_free(bvh);
-                       return NULL;
+                       return;
                }
 
                // create face boxes
-               for(i = 0; i < bvh->numfaces; i++)
+               for(i = 0, k = 0; i < bvh->numfaces; i++)
                {
-                       LinkNode *tnlink = NULL;
-                       
+                       LinkNode *tnlink;
+
                        tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
                        // TODO: check succesfull alloc
 
                        tnlink = BLI_linklist_append_fast(&nlink->next, tree);
 
                        face_list[i] = tree;
-                       
-                       if(bvh->mfaces)
-                       {
-                               tree->point_index[0] = mfaces[i].v1; 
-                               tree->point_index[1] = mfaces[i].v2;
-                               tree->point_index[2] = mfaces[i].v3;
-                               if(mfaces[i].v4)
-                                       tree->point_index[3] = mfaces[i].v4;
-                               else
-                                       tree->point_index[3] = -1;
-                       }
-                       else
-                       {
-                               tree->point_index[0] = i; 
-                               tree->point_index[1] = -1;
-                               tree->point_index[2] = -1;
-                               tree->point_index[3] = -1;
-                       }
-                       
+                       tree->tri_index = i;
                        tree->isleaf = 1;
                        tree->nextLeaf = NULL;
                        tree->prevLeaf = bvh->leaf_tree;
@@ -641,170 +632,18 @@ BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces)
                
                // build root bvh
                bvh_calc_DOP_hull_from_faces(bvh, face_list, bvh->numfaces, bvh->root->bv);
-               
+
                // This is the traversal function. 
                bvh_div_env_node(bvh, bvh->root, face_list, 0, bvh->numfaces-1, 0, nlink);
                if (face_list)
                        MEM_freeN(face_list);
                
-               // BLI_edgehash_free(edgehash, NULL);
-       }
-       
-
-       return bvh;
-}
-
-BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon)
-{
-       BVH *bvh=NULL;
-       CollisionTree *tree=NULL;
-       
-       bvh = MEM_callocN(sizeof(BVH), "BVH");
-       if (bvh == NULL) 
-       {
-               printf("bvh: Out of memory.\n");
-               return NULL;
-       }
-       
-       bvh->flags = 0;
-       bvh->leaf_tree = NULL;
-       bvh->leaf_root = NULL;
-       bvh->tree = NULL;
-
-       bvh->epsilon = epsilon;
-       bvh->numfaces = numfaces;
-       bvh->mfaces = mfaces;
-       
-       // we have no faces, we save seperate points
-       if(!mfaces)
-       {
-               bvh->numfaces = numverts;
-       }
-
-       bvh->numverts = numverts;
-       bvh->xnew = MEM_dupallocN(x);   
-       bvh->x = MEM_dupallocN(x);      
-       tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
-       
-       if (tree == NULL) 
-       {
-               printf("bvh_build: Out of memory for nodes.\n");
-               bvh_free(bvh);
-               return NULL;
-       }
-       
-       BLI_linklist_append(&bvh->tree, tree);
-       
-       return bvh_build(bvh, mfaces, numfaces);
-}
-
-
-BVH *bvh_build_from_float3 (MFace *mfaces, unsigned int numfaces, float (*x)[3], unsigned int numverts, float epsilon)
-{
-       BVH *bvh=NULL;
-       CollisionTree *tree=NULL;
-       unsigned int i = 0;
-       
-       bvh = MEM_callocN(sizeof(BVH), "BVH");
-       if (bvh == NULL) 
-       {
-               printf("bvh: Out of memory.\n");
-               return NULL;
-       }
-       
-       bvh->flags = 0;
-       bvh->leaf_tree = NULL;
-       bvh->leaf_root = NULL;
-       bvh->tree = NULL;
-
-       bvh->epsilon = epsilon;
-       bvh->numfaces = numfaces;
-       bvh->mfaces = mfaces;
-       
-       // we have no faces, we save seperate points
-       if(!mfaces)
-       {
-               bvh->numfaces = numverts;
-       }
-
-       bvh->numverts = numverts;
-       bvh->xnew = (MVert *)MEM_callocN(sizeof(MVert)*numverts, "BVH MVert");
-       
-       for(i = 0; i < numverts; i++)
-       {
-               VECCOPY(bvh->xnew[i].co, x[i]);
-       }
-       
-       bvh->x = MEM_dupallocN(bvh->xnew);      
-       
-       tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
-       
-       if (tree == NULL) 
-       {
-               printf("bvh_build: Out of memory for nodes.\n");
-               bvh_free(bvh);
-               return NULL;
-       }
-       
-       BLI_linklist_append(&bvh->tree, tree);
-       
-       return bvh_build(bvh, mfaces, numfaces);
-}
-
-BVH *bvh_build_from_float4 (MFace *mfaces, unsigned int numfaces, float (*x)[4], unsigned int numverts, float epsilon)
-{
-       BVH *bvh=NULL;
-       CollisionTree *tree=NULL;
-       unsigned int i = 0;
-       
-       bvh = MEM_callocN(sizeof(BVH), "BVH");
-       if (bvh == NULL) 
-       {
-               printf("bvh: Out of memory.\n");
-               return NULL;
-       }
-       
-       bvh->flags = 0;
-       bvh->leaf_tree = NULL;
-       bvh->leaf_root = NULL;
-       bvh->tree = NULL;
-
-       bvh->epsilon = epsilon;
-       bvh->numfaces = numfaces;
-       bvh->mfaces = mfaces;
-       
-       // we have no faces, we save seperate points
-       if(!mfaces)
-       {
-               bvh->numfaces = numverts;
-       }
-
-       bvh->numverts = numverts;
-       bvh->xnew = (MVert *)MEM_callocN(sizeof(MVert)*numverts, "BVH MVert");
-       
-       for(i = 0; i < numverts; i++)
-       {
-               VECCOPY(bvh->xnew[i].co, x[i]);
        }
        
-       bvh->x = MEM_dupallocN(bvh->xnew);      
-       
-       tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
-       
-       if (tree == NULL) 
-       {
-               printf("bvh_build: Out of memory for nodes.\n");
-               bvh_free(bvh);
-               return NULL;
-       }
-       
-       BLI_linklist_append(&bvh->tree, tree);
-       
-       return bvh_build(bvh, mfaces, numfaces);
 }
 
 // bvh_overlap - is it possbile for 2 bv's to collide ?
-int bvh_overlap(float *bv1, float *bv2)
+DO_INLINE int bvh_overlap(float *bv1, float *bv2)
 {
        int i = 0;
        for (i = KDOP_START; i < KDOP_END; i++)
@@ -823,6 +662,7 @@ int bvh_overlap(float *bv1, float *bv2)
        
        return 1;
 }
+
 /**
  * bvh_traverse - traverse two bvh trees looking for potential collisions.
  *
@@ -830,9 +670,18 @@ int bvh_overlap(float *bv1, float *bv2)
  * every other triangle that doesn't require any realloc, but uses
  * much memory
  */
-int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collision_list)
+int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response)
 {
-       int i = 0, ret = 0;
+       int i = 0, ret=0;
+       
+       /*
+       // Shouldn't be possible
+       if(!tree1 || !tree2)
+       {
+       printf("Error: no tree there\n");
+       return 0;
+       }
+       */      
        if (bvh_overlap(tree1->bv, tree2->bv)) 
        {               
                // Check if this node in the first tree is a leaf
@@ -841,85 +690,11 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio
                        // Check if this node in the second tree a leaf
                        if (tree2->isleaf) 
                        {
-                               //////////////////////////////////
-                               // TODO: check for 3rd point if zero (triangle)!!!
-                               //////////////////////////////////
-                               
-                               CollisionPair *collpair = NULL;
+                               // Provide the collision response.
                                
-                               if(tree1 != tree2) // do not collide same points
-                               {
-                                       ////////////////////////////////////////
-                                       // FIRST FACE
-                                       ////////////////////////////////////////
-                                       
-                                       // save potential colliding triangles
-                                       collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair");
-                                       
-                                       VECCOPY(collpair->point_indexA, tree1->point_index);
-                                       VECCOPY(collpair->point_indexB, tree2->point_index);
-                                       
-                                       // we use prepend because lots of insertions at end
-                                       // of list are horrible slow!
-                                       BLI_linklist_prepend(&collision_list[0], collpair);
-                                       
-                                       ////////////////////////////////////////
-                                       // SECOND FACE
-                                       ////////////////////////////////////////
-                                       if(tree1->point_index[3]) // check for quad face
-                                       {
-                                               // save potential colliding triangles
-                                               collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair");
-                                               
-                                               VECCOPY(collpair->point_indexA, tree1->point_index);
-                                               collpair->point_indexA[2] = tree1->point_index[3];
-                                               
-                                               VECCOPY(collpair->point_indexB, tree2->point_index);
-                                               
-                                               // we use prepend because lots of insertions at end
-                                               // of list are horrible slow!
-                                               BLI_linklist_prepend(&collision_list[0], collpair);
-                                       }
-                                       ////////////////////////////////////////
-                                       // THIRD FACE
-                                       ////////////////////////////////////////
-                                       if(tree2->point_index[3]) // check for quad face
-                                       {
-                                               // save potential colliding triangles
-                                               collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair");
-                                               
-                                               VECCOPY(collpair->point_indexA, tree1->point_index);
-                                               
-                                               VECCOPY(collpair->point_indexB, tree2->point_index);
-                                               collpair->point_indexB[2] = tree2->point_index[3];
-                                               
-                                               // we use prepend because lots of insertions at end
-                                               // of list are horrible slow!
-                                               BLI_linklist_prepend(&collision_list[0], collpair);
-                                       }
-                                       ////////////////////////////////////////
-                                       // FOURTH FACE
-                                       ////////////////////////////////////////
-                                       if(tree1->point_index[3] && tree1->point_index[3]) // check for quad face
-                                       {
-                                               // save potential colliding triangles
-                                               collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair");
-                                               
-                                               VECCOPY(collpair->point_indexA, tree1->point_index);
-                                               collpair->point_indexA[2] = tree1->point_index[3];
-                                               
-                                               VECCOPY(collpair->point_indexB, tree2->point_index);
-                                               collpair->point_indexB[2] = tree2->point_index[3];
-                                               
-                                               // we use prepend because lots of insertions at end
-                                               // of list are horrible slow!
-                                               BLI_linklist_prepend(&collision_list[0], collpair);
-                                       }
-                                       
-                                       return 1;
-                               }
-                               else
-                                       return 0;
+                               if(collision_response)
+                                       collision_response (clmd, coll_clmd, tree1, tree2);
+                               return 1;
                        }
                        else 
                        {
@@ -927,7 +702,7 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio
                                for (i = 0; i < 4; i++)
                                {
                                        // Only traverse nodes that exist.
-                                       if (tree2->nodes[i] && (bvh_traverse (tree1, tree2->nodes[i], collision_list)))
+                                       if (tree2->nodes[i] && bvh_traverse (clmd, coll_clmd, tree1, tree2->nodes[i], step, collision_response))
                                                ret = 1;
                                }
                        }
@@ -938,7 +713,7 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio
                        for (i = 0; i < 4; i++)
                        {
                                // Only traverse nodes that exist.
-                               if (tree1->nodes [i] && (bvh_traverse (tree1->nodes[i], tree2, collision_list)))
+                               if (tree1->nodes [i] && bvh_traverse (clmd, coll_clmd, tree1->nodes[i], tree2, step, collision_response))
                                        ret = 1;
                        }
                }
@@ -949,7 +724,7 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio
 
 // bottom up update of bvh tree:
 // join the 4 children here
-void bvh_join(CollisionTree *tree)
+void bvh_join(CollisionTree * tree)
 {
        int     i = 0, j = 0;
        if (!tree)
@@ -979,10 +754,10 @@ void bvh_join(CollisionTree *tree)
 }
 
 // update static bvh
-// needs new positions in bvh->x, bvh->xnew
+/* you have to update the bvh position before calling this function */
 void bvh_update(BVH * bvh, int moving)
 {
-       TreeNode *leaf, *parent;
+       CollisionTree *leaf, *parent;
        int traversecheck = 1;  // if this is zero we don't go further 
        unsigned int j = 0;
        
@@ -993,7 +768,6 @@ void bvh_update(BVH * bvh, int moving)
                {                       
                        leaf->parent->traversed = 0;
                }
-               
                if(!moving)
                        bvh_calc_DOP_hull_static(bvh, &leaf, 1, leaf->bv);
                else
@@ -1034,70 +808,3 @@ void bvh_update(BVH * bvh, int moving)
        }       
 }
 
-void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving)
-{
-       if(!bvh)
-               return;
-       
-       if(numverts!=bvh->numverts)
-               return;
-       
-       if(x)
-               memcpy(bvh->x, x, sizeof(MVert) * numverts);
-       
-       if(xnew)
-               memcpy(bvh->xnew, xnew, sizeof(MVert) * numverts);
-       
-       bvh_update(bvh, moving);
-}
-
-void bvh_update_from_float3(BVH * bvh, float (*x)[3], unsigned int numverts, float (*xnew)[3], int moving)
-{
-       unsigned int i = 0;
-       
-       if(!bvh)
-               return;
-       
-       if(numverts!=bvh->numverts)
-               return;
-       
-       if(x)
-       {
-               for(i = 0; i < numverts; i++)
-                       VECCOPY(bvh->x[i].co, x[i]);
-       }
-       
-       if(xnew)
-       {
-               for(i = 0; i < numverts; i++)
-                       VECCOPY(bvh->xnew[i].co, xnew[i]);
-       }
-       
-       bvh_update(bvh, moving);
-}
-
-void bvh_update_from_float4(BVH * bvh, float (*x)[4], unsigned int numverts, float (*xnew)[4], int moving)
-{
-       unsigned int i = 0;
-       
-       if(!bvh)
-               return;
-       
-       if(numverts!=bvh->numverts)
-               return;
-       
-       if(x)
-       {
-               for(i = 0; i < numverts; i++)
-                       VECCOPY(bvh->x[i].co, x[i]);
-       }
-       
-       if(xnew)
-       {
-               for(i = 0; i < numverts; i++)
-                       VECCOPY(bvh->xnew[i].co, xnew[i]);
-       }
-       
-       bvh_update(bvh, moving);
-}
-
index 3b69f47b1f4f9e9171c24f2944f86187c64a2004..8fdfbb71dc9422a66a3b1c56d8dbbd158fbcb991 100644 (file)
@@ -75,6 +75,7 @@
 #include "BKE_main.h"
 #include "BKE_anim.h"
 #include "BKE_bad_level_calls.h"
+#include "BKE_cloth.h"
 #include "BKE_curve.h"
 #include "BKE_customdata.h"
 #include "BKE_global.h"
@@ -5031,6 +5032,145 @@ static void clothModifier_freeData(ModifierData *md)
        }
 }
 
+/* Collision */
+
+static void collisionModifier_initData(ModifierData *md) 
+{
+       CollisionModifierData *collmd = (CollisionModifierData*) md;
+       
+       collmd->x = NULL;
+       collmd->xnew = NULL;
+       collmd->current_x = NULL;
+       collmd->current_xnew = NULL;
+       collmd->current_v = NULL;
+       collmd->time = -1;
+       collmd->numverts = 0;
+       collmd->tree = NULL;
+}
+
+static void collisionModifier_freeData(ModifierData *md)
+{
+       CollisionModifierData *collmd = (CollisionModifierData*) md;
+       
+       if (collmd) 
+       {
+               if(collmd->tree)
+                       bvh_free(collmd->tree);
+               if(collmd->x)
+                       MEM_freeN(collmd->x);
+               if(collmd->xnew)
+                       MEM_freeN(collmd->xnew);
+               if(collmd->current_x)
+                       MEM_freeN(collmd->current_x);
+               if(collmd->current_xnew)
+                       MEM_freeN(collmd->current_xnew);
+               if(collmd->current_v)
+                       MEM_freeN(collmd->current_v);
+               
+               collmd->x = NULL;
+               collmd->xnew = NULL;
+               collmd->current_x = NULL;
+               collmd->current_xnew = NULL;
+               collmd->current_v = NULL;
+               collmd->time = -1;
+               collmd->numverts = 0;
+               collmd->tree = NULL;
+       }
+}
+
+static int collisionModifier_dependsOnTime(ModifierData *md)
+{
+       return 1;
+}
+
+static void collisionModifier_deformVerts(
+       ModifierData *md, Object *ob, DerivedMesh *derivedData,
+       float (*vertexCos)[3], int numVerts)
+{
+       CollisionModifierData *collmd = (CollisionModifierData*) md;
+       DerivedMesh *dm = NULL;
+       float current_time = 0;
+       unsigned int numverts = 0, i = 0;
+       MVert *tempVert = NULL;
+
+       // if possible use/create DerivedMesh
+       
+       if(derivedData) dm = CDDM_copy(derivedData);
+       else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
+       
+       if(!ob->pd)
+       {
+               printf("collisionModifier_deformVerts: Should not happen!\n");
+               return;
+       }
+       
+       if(dm)
+       {
+               CDDM_apply_vert_coords(dm, vertexCos);
+               CDDM_calc_normals(dm);
+       
+       
+               current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 );
+               
+               if(current_time > collmd->time)
+               {
+                       numverts = dm->getNumVerts ( dm );
+                       
+                       // check if mesh has changed
+                       if(collmd->x && (numverts != collmd->numverts))
+                               collisionModifier_freeData((ModifierData *)collmd);
+                       
+                       if(collmd->time == -1) // first time
+                       {
+                               collmd->x = dm->dupVertArray(dm); // frame start position
+                               
+                               for ( i = 0; i < numverts; i++ )
+                               {
+                                       // we save global positions
+                                       Mat4MulVecfl ( ob->obmat, collmd->x[i].co );
+                               }
+                               
+                               collmd->xnew = MEM_dupallocN(collmd->x); // frame end position
+                               collmd->current_x = MEM_dupallocN(collmd->x); // inter-frame
+                               collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame
+                               collmd->current_v = MEM_dupallocN(collmd->x); // inter-frame
+
+                               collmd->numverts = numverts;
+                               
+                               // TODO: epsilon
+                               // create bounding box hierarchy
+                               collmd->tree = bvh_build_from_mvert(dm->getFaceArray(dm), dm->getNumFaces(dm), collmd->current_x, numverts, ob->pd->pdef_sbift);
+                       }
+                       else if(numverts == collmd->numverts)
+                       {
+                               // put positions to old positions
+                               tempVert = collmd->x;
+                               collmd->x = collmd->xnew;
+                               collmd->xnew = tempVert;
+                               
+                               memcpy(collmd->xnew, dm->getVertArray(dm), numverts*sizeof(MVert));
+                               
+                               for ( i = 0; i < numverts; i++ )
+                               {
+                                       // we save global positions
+                                       Mat4MulVecfl ( ob->obmat, collmd->xnew[i].co );
+                               }
+                               
+                               memcpy(collmd->current_xnew, dm->getVertArray(dm), numverts*sizeof(MVert));
+                               memcpy(collmd->current_x, dm->getVertArray(dm), numverts*sizeof(MVert));
+                               
+                               // recalc static bounding boxes
+                               bvh_update_from_mvert(collmd->tree, collmd->current_x, numverts, NULL, 0);
+                       }
+                       
+                       collmd->time = current_time;
+               }
+       }
+       
+       if(dm)
+               dm->release(dm);
+}
+
 /* Boolean */
 
 static void booleanModifier_copyData(ModifierData *md, ModifierData *target)
@@ -6855,6 +6995,16 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                // mti->copyData = clothModifier_copyData;
                mti->deformVerts = clothModifier_deformVerts;
                mti->updateDepgraph = clothModifier_updateDepgraph;
+               
+               mti = INIT_TYPE(Collision);
+               mti->type = eModifierTypeType_OnlyDeform;
+               mti->initData = collisionModifier_initData;
+               mti->flags = eModifierTypeFlag_AcceptsMesh 
+                               | eModifierTypeFlag_RequiresOriginalData;
+               mti->dependsOnTime = collisionModifier_dependsOnTime;
+               mti->freeData = collisionModifier_freeData; 
+               mti->deformVerts = collisionModifier_deformVerts;
+               // mti->copyData = collisionModifier_copyData;
 
                mti = INIT_TYPE(Boolean);
                mti->type = eModifierTypeType_Nonconstructive;
index 2bbe328d170b68002544d39bb67d4746a69fa95b..ce942f5bbb0a0f873bf13d6eeee617da4595b87e 100644 (file)
@@ -106,7 +106,7 @@ typedef struct SimulationSettings
        float   bending;        /* Flexion spring stiffness.                    */
        float   sim_time;
        int     flags;          /* flags, see CSIMSETT_FLAGS enum above.        */
-       short   solver_type;    /* which solver should be used?                         */
+       short   solver_type;    /* which solver should be used?         txold           */
        short   pad2;
        float   maxgoal;        /* see SB */
        float   eff_force_scale;/* Scaling of effector forces (see softbody_calc_forces).*/
index 581ff63a98716e8b22adfb10510b2b6a9e622b40..abc45e701836cf68e0e58648c8cfa54650eb4157 100644 (file)
@@ -3184,7 +3184,7 @@ static void object_panel_deflection(Object *ob)
                PartDeflect *pd= ob->pd;
                
                but = uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision");
-               // uiButSetFunc(but, object_collision__enabletoggle, ob, NULL);
+               uiButSetFunc(but, object_collision__enabletoggle, ob, NULL);
                
                if(pd->deflect) {
                        uiDefBut(block, LABEL, 0, "Particles",                  160,140,75,20, NULL, 0.0, 0, 0, 0, "");
@@ -4928,7 +4928,7 @@ static void object_panel_cloth(Object *ob)
                        Cloth *cloth = clmd->clothObject;
                        int defCount;
                        char *clvg1, *clvg2;
-                       char clmvg [] = "Mass Vertex Group%t|None%x0|";
+                       char clmvg [] = "Weight Paint Groups%t|";
        
                        val2=0;
        
@@ -4938,12 +4938,12 @@ static void object_panel_cloth(Object *ob)
                        uiClearButLock();
                        uiBlockBeginAlign(block);
                        uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:",       10,170,150,20, &clmd->sim_parms.structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure");
-                       uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:",         160,170,150,20, &clmd->sim_parms.bending, 0.0, 10000.0, 1000, 0, "Wrinkle possibility");
-                       uiDefButI(block, NUM, B_CLOTH_RENEW, "Steps per Frame:",           10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)");
+                       uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:",         160,170,150,20, &clmd->sim_parms.bending, 0.0, 10000.0, 1000, 0, "Wrinkle coefficient (higher = less smaller but more big wrinkles)");
+                       uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:",           10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)");
                        uiBlockEndAlign(block);
                        uiBlockBeginAlign(block);
                        uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:",       160,150,150,20, &clmd->sim_parms.Cdis, 0.0, 10.0, 10, 0, "Spring damping");
-                       uiDefButF(block, NUM, B_DIFF, "Air Damp:",         10,130,150,20, &clmd->sim_parms.Cvi, 0.0, 10.0, 10, 0, "Apply gravitation to point movement");
+                       uiDefButF(block, NUM, B_DIFF, "Air Damp:",         10,130,150,20, &clmd->sim_parms.Cvi, 0.0, 10.0, 10, 0, "Air has normaly some thickness which slows falling things down");
                        uiBlockEndAlign(block);                 
                        
                        uiClearButLock();
@@ -4959,7 +4959,7 @@ static void object_panel_cloth(Object *ob)
                        
                        /* GOAL STUFF */
                        uiBlockBeginAlign(block);
-                       uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Use Goal", 10,70,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
+                       uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Pinning of cloth", 10,70,150,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
                        if (clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
                        {
                                if(ob->type==OB_MESH) 
@@ -4977,26 +4977,15 @@ static void object_panel_cloth(Object *ob)
                                        {
                                                clmd->sim_parms.vgroup_mass = 0;
                                        }
+                                       else
+                                               if(!clmd->sim_parms.vgroup_mass)
+                                                       clmd->sim_parms.vgroup_mass = 1;
+                                                               
                                        sprintf (clvg2, "%s%s", clmvg, clvg1);
                                        
-                                       uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2,    140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups");      
+                                       uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2,    160,70,150,20, &clmd->sim_parms.vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups");
                                        MEM_freeN (clvg1);
                                        MEM_freeN (clvg2);
-                                       
-                                       if(clmd->sim_parms.vgroup_mass) 
-                                       {
-                                               bDeformGroup *defGroup = BLI_findlink(&ob->defbase, clmd->sim_parms.vgroup_mass-1);
-                                               if(defGroup)
-                                                       uiDefBut(block, BUT, B_DIFF, defGroup->name,    160,70,130,20, NULL, 0.0, 0.0, 0, 0, "Name of current vertex group");
-                                               else
-                                                       uiDefBut(block, BUT, B_DIFF, "(no group)",      160,70,130,20, NULL, 0.0, 0.0, 0, 0, "Vertex Group doesn't exist anymore");
-                                               
-                                               uiDefIconBut(block, BUT, B_CLOTH_DEL_VG, ICON_X, 290,70,20,20, 0, 0, 0, 0, 0, "Disable use of vertex group");
-                                               
-                                       }
-                                       else
-                                               uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:",   160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
-                               
                                }
                                else 
                                {
@@ -5004,10 +4993,13 @@ static void object_panel_cloth(Object *ob)
                                        uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:",   160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
                                }
                                
-                               uiDefButF(block, NUM, B_CLOTH_RENEW, "G Stiff:",        10,50,150,20, &clmd->sim_parms.goalspring, 0.0, 500.0, 10, 0, "Goal (vertex target position) spring stiffness");
+                               uiDefButF(block, NUM, B_CLOTH_RENEW, "Pin Stiff:",      10,50,150,20, &clmd->sim_parms.goalspring, 0.0, 500.0, 10, 0, "Pin (vertex target position) spring stiffness");
+                               /*
+                               // nobody is changing these ones anyway
                                uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms.goalfrict  , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction");
                                uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:",          10,30,150,20, &clmd->sim_parms.mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range");
                                uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:",          160,30,150,20, &clmd->sim_parms.maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range");
+                               */
                        }
                        uiBlockEndAlign(block);