Disabled Cloth collision detection because of almost complete rewrite/seperation...
authorDaniel Genrich <daniel.genrich@gmx.net>
Sun, 21 Oct 2007 16:38:13 +0000 (16:38 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Sun, 21 Oct 2007 16:38:13 +0000 (16:38 +0000)
source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/implicit.c
source/blender/blenkernel/intern/kdop.c
source/blender/blenkernel/intern/modifier.c
source/blender/makesdna/DNA_cloth_types.h
source/blender/makesdna/DNA_modifier_types.h
source/blender/src/buttons_editing.c
source/blender/src/buttons_object.c
source/blender/src/transform_generics.c

index 692692dbf5a3ebb51583bb683aaed458c955f132..1c5310c10d162e1f6dd1626c3e67f2fb4ea4af35 100644 (file)
@@ -124,69 +124,9 @@ void implicit_set_positions ( ClothModifierData *clmd );
 // from cloth.c, needed for modifier.c
 void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, float ( *vertexCos ) [3], int numverts );
 
-// used in collision.c
-typedef struct Tree
-{
-       struct Tree *nodes[4]; // 4 children --> quad-tree
-       struct Tree *parent;
-       struct Tree *nextLeaf;
-       struct Tree *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     count_nodes; // how many nodes are used
-       int     traversed;  // how many nodes already traversed until this level?
-       int     isleaf;
-}
-Tree;
-
-typedef struct Tree TreeNode;
-
-typedef struct BVH
-{
-       unsigned int    numfaces;
-       unsigned int    numverts;
-       ClothVertex     *verts; // just a pointer to the original datastructure
-       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.        */
-       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 );
-
-
-/////////////////////////////////////////////////
-// collision.c
-////////////////////////////////////////////////
-
-// needed for implicit.c
-void bvh_collision_response ( ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2 );
-int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt );
-
-////////////////////////////////////////////////
-
-
-/////////////////////////////////////////////////
-// kdop.c
-////////////////////////////////////////////////
-
-// needed for cloth.c
-void bvh_free ( BVH * bvh );
-BVH *bvh_build ( ClothModifierData *clmd, float epsilon );
-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 );
-
 ////////////////////////////////////////////////
 
 
-
 /////////////////////////////////////////////////
 // cloth.c
 ////////////////////////////////////////////////
@@ -200,7 +140,7 @@ void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int tot
 
 /* Typedefs for function pointers we need for solvers and collision detection. */
 typedef void ( *CM_COLLISION_SELF ) ( ClothModifierData *clmd, int step );
-typedef void ( *CM_COLLISION_OBJ ) ( ClothModifierData *clmd, int step, CM_COLLISION_RESPONSE collision_response );
+// typedef void ( *CM_COLLISION_OBJ ) ( ClothModifierData *clmd, int step, CM_COLLISION_RESPONSE collision_response );
 
 
 /* This enum provides the IDs for our solvers. */
@@ -239,6 +179,7 @@ typedef struct Frame
 Frame;
 
 /* used for collisions in collision.c */
+/*
 typedef struct CollPair
 {
        unsigned int face1; // cloth face
@@ -253,6 +194,7 @@ typedef struct CollPair
        unsigned int pointsb[4];
 }
 CollPair;
+*/
 
 /* used for collisions in collision.c */
 typedef struct EdgeCollPair
index eb7454ccd42980ab1b19b650bdc55b6bac9d4a6c..d83c7bcb7f0c49c076e2b7879dd3a13efa26d0ca 100644 (file)
@@ -65,6 +65,7 @@
 #include "BKE_mesh.h"
 #include "BKE_object.h"
 #include "BKE_cloth.h"
+#include "BKE_collisions.h"
 #include "BKE_modifier.h"
 #include "BKE_utildefines.h"
 #include "BKE_DerivedMesh.h"
@@ -845,11 +846,11 @@ void cloth_free_modifier ( ClothModifierData *clmd )
 
                        cloth->springs = NULL;
                        cloth->numsprings = 0;
-
+/*
                        // free BVH collision tree
                        if ( cloth->tree )
                                bvh_free ( ( BVH * ) cloth->tree );
-
+*/
                        // we save our faces for collision objects
                        if ( cloth->mfaces )
                                MEM_freeN ( cloth->mfaces );
@@ -1011,7 +1012,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 ( dm, clmd->coll_parms.epsilon );
 
                        }
 
@@ -1020,20 +1021,6 @@ static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMes
        }
 }
 
-/*
-helper function to get proper spring length
-when object is rescaled
-*/
-float cloth_globallen ( float *v1,float *v2,Object *ob )
-{
-       float p1[3],p2[3];
-       VECCOPY ( p1,v1 );
-       Mat4MulVecfl ( ob->obmat, p1 );
-       VECCOPY ( p2,v2 );
-       Mat4MulVecfl ( ob->obmat, p2 );
-       return VecLenf ( p1,p2 );
-}
-
 // only meshes supported at the moment
 static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts )
 {
@@ -1082,7 +1069,7 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh
                                        return 0;
                                }
 
-                               mvert = CDDM_get_verts ( dm );
+                               mvert = dm->getVertArray ( dm ); // CDDM_get_verts ( dm );
                                verts = clmd->clothObject->verts;
 
                                /* set initial values */
@@ -1116,7 +1103,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 ( dm, clmd->coll_parms.epsilon );
 
                                cloth_cache_set_frame ( clmd, 1 );
                        }
index a5a382f7624b27aa55ab0d2cc20c4fc5189c99c1..41823b0ad3974d91ec3232d5ede473e97ffc83f5 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"
@@ -217,7 +218,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 +319,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;
@@ -372,8 +373,9 @@ DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal
        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)
+int collisions_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd)
 {
+       /*
        unsigned int i = 0;
        int result = 0;
        LinkNode *search = NULL;
@@ -386,20 +388,20 @@ int cloth_collision_response_static(ClothModifierData *clmd, ClothModifierData *
        cloth1 = clmd->clothObject;
        cloth2 = coll_clmd->clothObject;
 
-       search = clmd->coll_parms.collision_list;
+       // search = clmd->coll_parms.collision_list;
        
        while(search)
        {
                collpair = search->link;
                
                // compute barycentric coordinates for both collision points
-               cloth_compute_barycentric(collpair->pa,
+               collisions_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,
+               collisions_compute_barycentric(collpair->pb,
                                        cloth2->verts[collpair->bp1].txold,
                                        cloth2->verts[collpair->bp2].txold,
                                        cloth2->verts[collpair->bp3].txold,
@@ -442,12 +444,6 @@ int cloth_collision_response_static(ClothModifierData *clmd, ClothModifierData *
                                
                                // 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);
-                               */
                        }
                        
 
@@ -455,6 +451,7 @@ int cloth_collision_response_static(ClothModifierData *clmd, ClothModifierData *
                        
                        // printf("impulse: %f\n", impulse);
                        
+                       // face A
                        VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); 
                        cloth1->verts[collpair->ap1].impulse_count++;
                        
@@ -464,63 +461,50 @@ int cloth_collision_response_static(ClothModifierData *clmd, ClothModifierData *
                        VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); 
                        cloth1->verts[collpair->ap3].impulse_count++;
                        
-                       result = 1;
+                       // face B
+                       VECADDMUL(cloth2->verts[collpair->bp1].impulse, collpair->normal, u1 * impulse); 
+                       cloth2->verts[collpair->bp1].impulse_count++;
                        
-                       /*
-                       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(cloth2->verts[collpair->bp2].impulse, collpair->normal, u2 * impulse); 
+                       cloth2->verts[collpair->bp2].impulse_count++;
                        
-                       VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); 
-                       cloth1->verts[collpair->ap3].impulse_count++;
-               }
-                       */
+                       VECADDMUL(cloth2->verts[collpair->bp3].impulse, collpair->normal, u3 * impulse); 
+                       cloth2->verts[collpair->bp3].impulse_count++;
+                       
+                       
+                       result = 1;     
                
                        // 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;
+       */
+       return 0;
 }
 
-int cloth_collision_response_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd)
+
+int collisions_collision_response_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd)
 {
        
 }
 
 
-int cloth_collision_response_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd)
+int collisions_collision_response_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd)
 {
        
 }
 
 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;
@@ -618,11 +602,11 @@ void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clm
                                // collpair->face1 = tree1->tri_index;
                                // collpair->face2 = tree2->tri_index;
                                
-                               VECCOPY(collpair->normal, collpair->vector);
-                               Normalize(collpair->normal);
+                               // VECCOPY(collpair->normal, collpair->vector);
+                               // Normalize(collpair->normal);
+                               
+                               // collpair->distance = distance;
                                
-                               collpair->distance = distance;
-                               BLI_linklist_append(&clmd->coll_parms.collision_list, collpair);
                        }
                        else
                        {
@@ -634,9 +618,10 @@ void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clm
                        MEM_freeN(collpair);
                }
        }
+       */
 }
 
-int cloth_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair)
+int collisions_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair)
 {
        Cloth *cloth1, *cloth2;
        ClothVertex *verts1, *verts2;
@@ -667,7 +652,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 collisions_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
 {
        EdgeCollPair edgecollpair;
        Cloth *cloth1=NULL, *cloth2=NULL;
@@ -773,7 +758,7 @@ void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *co
                        }
                        
                        
-                       if(!cloth_are_edges_adjacent(clmd, coll_clmd, &edgecollpair))
+                       if(!collisions_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);
@@ -782,7 +767,7 @@ void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *co
                                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);
+                               numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution);
                                
                                for (k = 0; k < numsolutions; k++) 
                                {                                                               
@@ -802,8 +787,9 @@ void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *co
        }               
 }
 
-void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
+void collisions_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
 {
+       /*
        CollPair collpair;
        Cloth *cloth1=NULL, *cloth2=NULL;
        MFace *face1=NULL, *face2=NULL;
@@ -872,7 +858,7 @@ void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *col
                                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);
+                               numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution);
                                
                                for (k = 0; k < numsolutions; k++) 
                                {                                                               
@@ -894,19 +880,22 @@ void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *col
                        
                }
        }
+       */
 }
 
-void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
+void collisions_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
 {
+       /*
        // TODO: check for adjacent
-       cloth_collision_moving_edges(clmd, coll_clmd, tree1, tree2);
+       collisions_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);
+       collisions_collision_moving_tris(clmd, coll_clmd, tree1, tree2);
+       collisions_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)
+void collisions_update_collision_objects(float step)
 {
        Base *base=NULL;
        ClothModifierData *coll_clmd=NULL;
@@ -943,15 +932,15 @@ 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(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");
+                               printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
                }
        }
 }
 
-// CLOTH_MAX_THRESHOLD defines how much collision rounds/loops should be taken
+// collisions_MAX_THRESHOLD defines how much collision rounds/loops should be taken
 #define CLOTH_MAX_THRESHOLD 10
 
 // cloth - object collisions
@@ -961,12 +950,13 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
        ClothModifierData *coll_clmd=NULL;
        Cloth *cloth=NULL;
        Object *coll_ob=NULL;
-       BVH *cloth_bvh=NULL;
+       BVH *collisions_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;
+       LinkNode *collision_list = NULL; 
 
        if ((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree))
        {
@@ -974,7 +964,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
        }
        cloth = clmd->clothObject;
        verts = cloth->verts;
-       cloth_bvh = (BVH *) cloth->tree;
+       collisions_bvh = (BVH *) cloth->tree;
        numfaces = clmd->clothObject->numfaces;
        numverts = clmd->clothObject->numverts;
        
@@ -983,16 +973,15 @@ 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(clmd, collisions_bvh, 0); // 0 means STATIC, 1 means MOVING (see later in this function)
        
        // update collision objects
-       cloth_update_collision_objects(step);
+       collisions_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)
@@ -1010,69 +999,55 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
                                {
                                        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 < 10; j++) // 10 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 & CLOTH_SIMSETTINGS_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");
-                               }
-                       }
+                                       // fill collision list 
+                                       bvh_traverse(collisions_bvh->root, coll_bvh->root, collision_list);
+                                       
+                                       // process all collisions (calculate impulses, TODO: also repulses if distance too short)
+                                       result = 1;
+                                       for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence
+                                       {
+                                               result = 0;
+                                               
+                                               // result += collisions_collision_response_static_tris(clmd, coll_clmd, collision_list, 0);
                        
-                       // 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;
+                                               // result += collisions_collision_response_static_tris(coll_clmd, clmd, collision_list, 1);
+                                       
+                                               // 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;
+                                                               ic++;
+                                                               ret++;
+                                                       }
+                                               }
+                                       }
+                                       
+                                       // free collision list
+                                       if(collision_list)
+                                       {
+                                               LinkNode *search = collision_list;
+                                               while(search)
+                                               {
+                                                       CollisionPair *coll_pair = search->link;
                                                        
-                               MEM_freeN(coll_pair);
-                               search = search->next;
-                       }
-                       BLI_linklist_free(clmd->coll_parms.collision_list,NULL);
+                                                       MEM_freeN(coll_pair);
+                                                       search = search->next;
+                                               }
+                                               BLI_linklist_free(collision_list,NULL);
                        
-                       clmd->coll_parms.collision_list = NULL;
+                                               collision_list = NULL;
+                                       }
+                               }
+                               else
+                                       printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
+                       }
                }
                
                printf("ic: %d\n", ic);
@@ -1100,7 +1075,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(clmd, collisions_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)
@@ -1119,7 +1094,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(coll_clmd, coll_bvh, 1);  // 0 means STATIC, 1 means MOVING       
                }
        }
        
@@ -1128,7 +1103,6 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
        {
                result = 0;
                ic = 0;
-               clmd->coll_parms.collision_list = NULL; 
                
                // check all collision objects
                for (base = G.scene->base.first; base; base = base->next)
@@ -1146,83 +1120,72 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
                                {
                                        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 < 10; j++) // 10 is just a value that ensures convergence
-               {
-                       result = 0;
+                                       bvh_traverse(collisions_bvh->root, coll_bvh->root, collision_list);
+                                       
+                                       // process all collisions (calculate impulses, TODO: also repulses if distance too short)
+                                       result = 1;
+                                       for(j = 0; j < 10; j++) // 10 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);
+                                               // handle all collision objects
                                                
-                               if (!coll_clmd)
-                               continue;
-                               
-                               // if collision object go on
-                               if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_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");
-                               }
-                       }
+                                               /*
+                                               if (coll_clmd->clothObject) 
+                                               result += collisions_collision_response_moving_tris(clmd, coll_clmd);
+                                               else
+                                               printf ("collisions_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;
+                                               // 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++;
-                               }
-                       }
-               }
+                                                               ic++;
+                                                               ret++;
+                                                       }
+                                               }
+                                       }
                
                
-               // verts come from clmd
-               for(i = 0; i < numverts; i++)
-               {
-                       VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
-               }
+                                       // 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 
+                                       // update cloth bvh
+                                       // bvh_update(clmd, collisions_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;
+                                       // free collision list
+                                       if(collision_list)
+                                       {
+                                               LinkNode *search = collision_list;
+                                               while(search)
+                                               {
+                                                       CollisionPair *coll_pair = search->link;
                                                        
-                               MEM_freeN(coll_pair);
-                               search = search->next;
-                       }
-                       BLI_linklist_free(clmd->coll_parms.collision_list,NULL);
+                                                       MEM_freeN(coll_pair);
+                                                       search = search->next;
+                                               }
+                                               BLI_linklist_free(collision_list,NULL);
                        
-                       clmd->coll_parms.collision_list = NULL;
+                                               collision_list = NULL;
+                                       }
+                               }
+                               else
+                                       printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
+                       }
                }
-               
+                               
                printf("ic: %d\n", ic);
                rounds++;
        }
index 1ee4475a6ccbcd7682fe09d4682b3b9c1c78e24f..2ce00d0e38c28c4aca37ac500dca5a726e1be614 100644 (file)
@@ -1492,7 +1492,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
                        }
        
                        // call collision function
-                       result = cloth_bvh_objcollision(clmd, step + dt, dt);
+                       result = 0; // cloth_bvh_objcollision(clmd, step + dt, dt);
        
                        // copy corrected positions back to simulation
                        for(i = 0; i < numverts; i++)
index b487f9a3b26386ea45cb87b6b8ea0e84feeb764e..8b2540c7d8ad4b2b6d41d73b370b527a657e7907 100644 (file)
@@ -38,7 +38,6 @@
 #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"
@@ -59,7 +58,7 @@
 #include "BKE_key.h"
 #include "BKE_mesh.h"
 #include "BKE_object.h"
-#include "BKE_cloth.h"
+#include "BKE_collisions.h"
 #include "BKE_modifier.h"
 #include "BKE_utildefines.h"
 #include "BKE_DerivedMesh.h"
@@ -165,13 +164,13 @@ static int size_threshold = 16;
 /*
 * Common methods for all algorithms
 */
-DO_INLINE void bvh_exchange(Tree **a, int i, int j)
+void bvh_exchange(Tree **a, int i, int j)
 {
        Tree *t=a[i];
        a[i]=a[j];
        a[j]=t;
 }
-DO_INLINE int floor_lg(int a)
+int floor_lg(int a)
 {
        return (int)(floor(log(a)/log(2)));
 }
@@ -294,7 +293,7 @@ static void bvh_introsort_loop (Tree **a, int lo, int hi, int depth_limit, int a
        }
 }
 
-DO_INLINE void bvh_sort(Tree **a0, int begin, int end, int axis)
+void bvh_sort(Tree **a0, int begin, int end, int axis)
 {
        if (begin < end)
        {
@@ -303,7 +302,7 @@ DO_INLINE void bvh_sort(Tree **a0, int begin, int end, int axis)
                bvh_insertionsort(a, begin, end, axis);
        }
 }
-DO_INLINE void bvh_sort_along_axis(Tree **face_list, int start, int end, int axis)
+void bvh_sort_along_axis(Tree **face_list, int start, int end, int axis)
 {
        bvh_sort(face_list, start, end, axis);
 }
@@ -330,7 +329,7 @@ void bvh_free(BVH * bvh)
 
                BLI_linklist_free(bvh->tree,NULL); 
                bvh->tree = NULL;
-
+               
                MEM_freeN(bvh);
                bvh = NULL;
        }
@@ -338,7 +337,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
-DO_INLINE int bvh_largest_axis(float *bv)
+int bvh_largest_axis(float *bv)
 {
        float middle_point[3];
 
@@ -362,7 +361,7 @@ DO_INLINE int bvh_largest_axis(float *bv)
 }
 
 // depends on the fact that the BVH's for each face is already build
-DO_INLINE void bvh_calc_DOP_hull_from_faces(BVH * bvh, Tree **tri, int numfaces, float *bv)
+void bvh_calc_DOP_hull_from_faces(BVH * bvh, Tree **tri, int numfaces, float *bv)
 {
        float newmin,newmax;
        int i, j;
@@ -386,9 +385,9 @@ DO_INLINE void bvh_calc_DOP_hull_from_faces(BVH * bvh, Tree **tri, int numfaces,
        }
 }
 
-DO_INLINE void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, float *bv)
+void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, float *bv)
 {
-       ClothVertex *tempMVert = bvh->verts;
+       MVert *tempMVert = bvh->xold;
        MFace *tempMFace = bvh->mfaces;
        float *tempBV = bv;
        float newminmax;
@@ -415,7 +414,7 @@ DO_INLINE void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, flo
                        // for all Axes.
                        for (i = KDOP_START; i < KDOP_END; i++)
                        {                               
-                               newminmax = INPR(tempMVert[temp].txold, KDOP_AXES[i]);
+                               newminmax = INPR(tempMVert[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))
@@ -425,9 +424,10 @@ DO_INLINE void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, flo
        }
 }
 
-DO_INLINE void bvh_calc_DOP_hull_moving(BVH * bvh, Tree **tri, int numfaces, float *bv)
+void bvh_calc_DOP_hull_moving(BVH * bvh, Tree **tri, int numfaces, float *bv)
 {
-       ClothVertex *tempMVert = bvh->verts;
+       MVert *tempMVert = bvh->xold;
+       MVert *tempMVert2 = bvh->x;
        MFace *tempMFace = bvh->mfaces;
        float *tempBV = bv;
        float newminmax;
@@ -454,13 +454,13 @@ DO_INLINE void bvh_calc_DOP_hull_moving(BVH * bvh, Tree **tri, int numfaces, flo
                        // for all Axes.
                        for (i = KDOP_START; i < KDOP_END; i++)
                        {                               
-                               newminmax = INPR(tempMVert[temp].txold, KDOP_AXES[i]);
+                               newminmax = INPR(tempMVert[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(tempMVert[temp].tx, KDOP_AXES[i]);
+                               newminmax = INPR(tempMVert2[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))
@@ -538,25 +538,18 @@ static void bvh_div_env_node(BVH * bvh, TreeNode *tree, Tree **face_list, unsign
        return;
 }
 
-BVH *bvh_build (ClothModifierData *clmd, float epsilon)
+BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xold, unsigned int numverts, float epsilon)
 {
        unsigned int i = 0, j = 0, k = 0;
        Tree **face_list=NULL;
        BVH     *bvh=NULL;
-       Cloth *cloth = NULL;
        Tree *tree=NULL;
        LinkNode *nlink = NULL;
        EdgeHash *edgehash = NULL;
-       LinkNode *springs = NULL;
        unsigned int numsprings = 0;
        MFace *mface = NULL;
 
-       if(!clmd)
-               return NULL;
-
-       cloth = clmd->clothObject;
-
-       if(!cloth)
+       if(!dm)
                return NULL;
        
        bvh = MEM_callocN(sizeof(BVH), "BVH");
@@ -566,20 +559,18 @@ BVH *bvh_build (ClothModifierData *clmd, float epsilon)
                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;
-       mface = bvh->mfaces = cloth->mfaces;
+       bvh->numfaces = dm->getNumFaces(dm);
+       mface = bvh->mfaces = dm->getFaceArray(dm);
 
-       bvh->numverts = cloth->numverts;
-       bvh->verts = cloth->verts;      
+       bvh->numverts = numverts;
+       bvh->x = x;     
+       bvh->xold = xold;       
        tree = (Tree *)MEM_callocN(sizeof(Tree), "Tree");
        // TODO: check succesfull alloc
        BLI_linklist_append(&bvh->tree, tree);
@@ -610,21 +601,6 @@ BVH *bvh_build (ClothModifierData *clmd, float epsilon)
        }
        else
        {       
-               // create spring tearing hash
-               /*
-               edgehash = BLI_edgehash_new();
-               if(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)
-               for(i = 0; i < numsprings; i++)
-               {
-                       if((springs[i].flags & CSPRING_FLAG_DEACTIVATE)
-                       &&(!BLI_edgehash_haskey(edgehash, springs[i].ij, springs[i].kl)))
-                       {
-                               BLI_edgehash_insert(edgehash, springs[i].ij, springs[i].kl, NULL);
-                               BLI_edgehash_insert(edgehash, springs[i].kl, springs[i].ij, NULL);
-                       }
-               }       
-               */
-               
                // create face boxes            
                face_list = MEM_callocN (bvh->numfaces * sizeof (Tree *), "Tree");
                if (face_list == NULL) 
@@ -637,50 +613,43 @@ BVH *bvh_build (ClothModifierData *clmd, float epsilon)
                // create face boxes
                for(i = 0, k = 0; i < bvh->numfaces; i++)
                {
-                       LinkNode *tnlink;
-                       /*
-                       if((!BLI_edgehash_haskey(edgehash, mface[i].v1, mface[i].v2))
-                       &&(!BLI_edgehash_haskey(edgehash, mface[i].v2, mface[i].v3))
-                       &&(!BLI_edgehash_haskey(edgehash, mface[i].v3, mface[i].v4))
-                       &&(!BLI_edgehash_haskey(edgehash, mface[i].v4, mface[i].v1))) 
-                       */
+                       LinkNode *tnlink = NULL;
+                       
+                       tree = (Tree *)MEM_callocN(sizeof(Tree), "Tree");
+                       // TODO: check succesfull alloc
+
+                       tnlink = BLI_linklist_append_fast(&nlink->next, tree);
+
+                       face_list[i] = tree;
+                       tree->tri_index = i;
+                       tree->isleaf = 1;
+                       tree->nextLeaf = NULL;
+                       tree->prevLeaf = bvh->leaf_tree;
+                       tree->parent = NULL;
+                       tree->count_nodes = 0;
+
+                       if(i==0)
                        {
-                               tree = (Tree *)MEM_callocN(sizeof(Tree), "Tree");
-                               // TODO: check succesfull alloc
-       
-                               tnlink = BLI_linklist_append_fast(&nlink->next, tree);
-       
-                               face_list[i] = tree;
-                               tree->tri_index = i;
-                               tree->isleaf = 1;
-                               tree->nextLeaf = NULL;
-                               tree->prevLeaf = bvh->leaf_tree;
-                               tree->parent = NULL;
-                               tree->count_nodes = 0;
-       
-                               if(i==0)
-                               {
-                                       bvh->leaf_tree = bvh->leaf_root = tree;
-                               }
-                               else
-                               {
-                                       bvh->leaf_tree->nextLeaf = tree;
-                                       bvh->leaf_tree = bvh->leaf_tree->nextLeaf;
-                               }               
-       
-                               tree->nodes[0] = tree->nodes[1] = tree->nodes[2] = tree->nodes[3] = NULL;               
-       
-                               bvh_calc_DOP_hull_static(bvh, &face_list[i], 1, tree->bv);
-       
-                               // inflate the bv with some epsilon
-                               for (j = KDOP_START; j < KDOP_END; j++)
-                               {
-                                       tree->bv[(2 * j)] -= bvh->epsilon; // minimum 
-                                       tree->bv[(2 * j) + 1] += bvh->epsilon;  // maximum 
-                               }
-                               
-                               nlink = tnlink;
+                               bvh->leaf_tree = bvh->leaf_root = tree;
+                       }
+                       else
+                       {
+                               bvh->leaf_tree->nextLeaf = tree;
+                               bvh->leaf_tree = bvh->leaf_tree->nextLeaf;
+                       }               
+
+                       tree->nodes[0] = tree->nodes[1] = tree->nodes[2] = tree->nodes[3] = NULL;               
+
+                       bvh_calc_DOP_hull_static(bvh, &face_list[i], 1, tree->bv);
+
+                       // inflate the bv with some epsilon
+                       for (j = KDOP_START; j < KDOP_END; j++)
+                       {
+                               tree->bv[(2 * j)] -= bvh->epsilon; // minimum 
+                               tree->bv[(2 * j) + 1] += bvh->epsilon;  // maximum 
                        }
+                       
+                       nlink = tnlink;
                }
                
                // build root bvh
@@ -699,7 +668,7 @@ BVH *bvh_build (ClothModifierData *clmd, float epsilon)
 }
 
 // bvh_overlap - is it possbile for 2 bv's to collide ?
-DO_INLINE int bvh_overlap(float *bv1, float *bv2)
+int bvh_overlap(float *bv1, float *bv2)
 {
        int i = 0;
        for (i = KDOP_START; i < KDOP_END; i++)
@@ -725,18 +694,10 @@ DO_INLINE int bvh_overlap(float *bv1, float *bv2)
  * every other triangle that doesn't require any realloc, but uses
  * much memory
  */
-int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * tree1, Tree * tree2, float step, CM_COLLISION_RESPONSE collision_response)
+int bvh_traverse(Tree * tree1, Tree * tree2, LinkNode *collision_list)
 {
-       int i = 0, ret=0;
-       
-       /*
-       // Shouldn't be possible
-       if(!tree1 || !tree2)
-       {
-       printf("Error: no tree there\n");
-       return 0;
-}
-       */      
+       int i = 0, ret = 0;
+               
        if (bvh_overlap(tree1->bv, tree2->bv)) 
        {               
                // Check if this node in the first tree is a leaf
@@ -745,10 +706,14 @@ int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree *
                        // Check if this node in the second tree a leaf
                        if (tree2->isleaf) 
                        {
-                               // Provide the collision response.
+                               // save potential colliding triangles
+                               CollisionPair *collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair");
+                               
+                               collpair->indexA = tree1->tri_index;
+                               collpair->indexB = tree2->tri_index;
+                               
+                               BLI_linklist_append(&collision_list, collpair);
                                
-                               if(collision_response)
-                                       collision_response (clmd, coll_clmd, tree1, tree2);
                                return 1;
                        }
                        else 
@@ -757,7 +722,7 @@ int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree *
                                for (i = 0; i < 4; i++)
                                {
                                        // Only traverse nodes that exist.
-                                       if (tree2->nodes[i] && bvh_traverse (clmd, coll_clmd, tree1, tree2->nodes[i], step, collision_response))
+                                       if (tree2->nodes[i] && bvh_traverse (tree1, tree2->nodes[i], collision_list))
                                                ret = 1;
                                }
                        }
@@ -768,7 +733,7 @@ int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree *
                        for (i = 0; i < 4; i++)
                        {
                                // Only traverse nodes that exist.
-                               if (tree1->nodes [i] && bvh_traverse (clmd, coll_clmd, tree1->nodes[i], tree2, step, collision_response))
+                               if (tree1->nodes [i] && bvh_traverse (tree1->nodes[i], tree2, collision_list))
                                        ret = 1;
                        }
                }
@@ -809,12 +774,18 @@ void bvh_join(Tree * tree)
 }
 
 // update static bvh
-void bvh_update(ClothModifierData *clmd, BVH * bvh, int moving)
+// needs new positions in bvh->x, bvh->xold
+void bvh_update(DerivedMesh *dm, BVH * bvh, int moving)
 {
        TreeNode *leaf, *parent;
        int traversecheck = 1;  // if this is zero we don't go further 
        unsigned int j = 0;
        
+       if(bvh->numfaces != dm->getNumFaces(dm))
+               return;
+       
+       bvh->mfaces = dm->getFaceArray(dm);
+       
        for (leaf = bvh->leaf_root; leaf; leaf = leaf->nextLeaf)
        {
                traversecheck = 1;
index bb6297361fe67d690d2b5b53c82832e206281995..59bd4b8253d049d45368b23c057d98d4da719c4b 100644 (file)
@@ -72,6 +72,7 @@
 #include "BKE_main.h"
 #include "BKE_anim.h"
 #include "BKE_bad_level_calls.h"
+#include "BKE_collisions.h"
 #include "BKE_customdata.h"
 #include "BKE_global.h"
 #include "BKE_utildefines.h"
@@ -4920,7 +4921,7 @@ static void clothModifier_updateDepgraph(
 
 CustomDataMask clothModifier_requiredDataMask(ModifierData *md)
 {
-       ClothModifierData *clmd = (HookModifierData *)md;
+       ClothModifierData *clmd = (ClothModifierData *)md;
        CustomDataMask dataMask = 0;
 
        /* ask for vertexgroups if we need them */
@@ -4948,6 +4949,113 @@ static void clothModifier_freeData(ModifierData *md)
        }
 }
 
+/* Collision */
+
+static void collisionModifier_initData(ModifierData *md) 
+{
+       CollisionModifierData *collmd = (CollisionModifierData*) md;
+       
+       collmd->x = NULL;
+       collmd->xold = 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->xold)
+                       MEM_freeN(collmd->xold);
+               
+               collmd->x = NULL;
+               collmd->xold = NULL;
+               collmd->time = -1;
+               collmd->numverts = 0;
+               collmd->tree = NULL;
+       }
+}
+
+static void collisionModifier_deformVerts(
+                                     ModifierData *md, Object *ob, DerivedMesh *derivedData,
+         float (*vertexCos)[3], int numVerts)
+{
+       CollisionModifierData *collmd = (CollisionModifierData*) md;
+       DerivedMesh *dm = NULL;
+       MVert *mvert = 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(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(collmd);
+                       
+                       if(collmd->time == -1) // first time
+                       {
+                               collmd->x = dm->dupVertArray(dm);
+                               collmd->xold = dm->dupVertArray(dm);
+                               collmd->numverts = numverts;
+                               
+                               // TODO: epsilon
+                               // create bounding box hierarchy
+                               collmd->tree = bvh_build(dm, collmd->x, collmd->xold,  numverts, 0.01);
+                       }
+                       else if(numverts == collmd->numverts)
+                       {
+                               // put positions to old positions
+                               tempVert = collmd->xold;
+                               collmd->xold = collmd->x;
+                               collmd->x = tempVert;
+                               
+                               memcpy(collmd->x, dm->getVertArray(dm), numverts*sizeof(MVert));
+                               
+                               for ( i = 0; i < numverts; i++ )
+                               {
+                                       // we save global positions
+                                       Mat4MulVecfl ( ob->obmat, collmd->x[i].co );
+                               }
+                               
+                               bvh_update(dm, collmd->tree, 0); // recalc static bounding boxes
+                       }
+                       
+                       collmd->time = current_time;
+               }
+       }
+       
+       if(dm)
+               dm->release(dm);
+}
+
+static int collisionModifier_dependsOnTime(ModifierData *md)
+{
+       return 1;
+}
+
 /* Boolean */
 
 static void booleanModifier_copyData(ModifierData *md, ModifierData *target)
@@ -5247,6 +5355,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;
@@ -5449,7 +5567,7 @@ int modifiers_isSoftbodyEnabled(Object *ob)
        return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
 }
 
-ModifierData * modifiers_isClothEnabled(Object *ob)
+ModifierData *modifiers_isClothEnabled(Object *ob)
 {
        ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth);
 
index 7f5527466e4762ffbce597a93d1749448531ce00..27f7431a9cff2cd76ae11ac141b93023ab50b99f 100644 (file)
@@ -130,7 +130,6 @@ typedef struct CollisionSettings
        float   friction;               /* Friction/damping applied on contact with other object.*/
        short   collision_type;         /* which collision system is used.                      */
        short   loop_count;             /* How many iterations for the collision loop.          */
-       struct  LinkNode *collision_list;       /* e.g. pointer to temp memory for collisions */
        int     flags;                  /* collision flags defined in BKE_cloth.h */
        int     pad;
 }
index 4c9fbdcc7b74191838e8d9104fea6a457f604f5c..e6e73ea7d0785c30ff9c7f7c771682d81839dd27 100644 (file)
@@ -31,6 +31,7 @@ typedef enum ModifierType {
        eModifierType_Smooth,
        eModifierType_Cast,
        eModifierType_Cloth,
+       eModifierType_Collision,
        NUM_MODIFIER_TYPES
 } ModifierType;
 
@@ -346,6 +347,17 @@ typedef struct ClothModifierData {
    CollisionSettings   coll_parms;     /* definition is in DNA_cloth_types.h                   */
 } ClothModifierData;
 
+typedef struct CollisionModifierData {
+       ModifierData            modifier;
+       
+       struct MVert *x;
+       struct MVert *xold;
+       
+       unsigned int numverts;
+       float time;
+       void *tree;     /* collision tree for this cloth object */
+} CollisionModifierData;
+
 typedef enum {
        eBooleanModifierOp_Intersect,
        eBooleanModifierOp_Union,
index 194241c438048230f3545602d4040eba369ab84f..13aae38810667f3956c830d08d5f3cd8ff5687c7 100644 (file)
@@ -950,7 +950,9 @@ static uiBlock *modifiers_add_menu(void *ob_v)
                ModifierTypeInfo *mti = modifierType_getInfo(i);
 
                /* Only allow adding through appropriate other interfaces */
-               if(ELEM3(i, eModifierType_Softbody, eModifierType_Hook, eModifierType_Cloth)) continue;
+               if(ELEM(i, eModifierType_Softbody, eModifierType_Hook)) continue;
+               
+               if(ELEM(i, eModifierType_Cloth, eModifierType_Collision)) continue;
 
                if((mti->flags&eModifierTypeFlag_AcceptsCVs) ||
                   (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
@@ -1483,7 +1485,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
        uiBlockSetCol(block, TH_AUTO);
        
        /* open/close icon */
-       if (!isVirtual) {
+       if (!isVirtual && md->type!=eModifierType_Collision) {
                uiBlockSetEmboss(block, UI_EMBOSSN);
                uiDefIconButBitI(block, ICONTOG, eModifierMode_Expanded, B_MODIFIER_REDRAW, VICON_DISCLOSURE_TRI_RIGHT, x-10, y-2, 20, 20, &md->mode, 0.0, 0.0, 0.0, 0.0, "Collapse/Expand Modifier");
        }
@@ -1500,8 +1502,8 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
                uiBlockBeginAlign(block);
                uiDefBut(block, TEX, B_MODIFIER_REDRAW, "", x+10, y-1, buttonWidth-60, 19, md->name, 0.0, sizeof(md->name)-1, 0.0, 0.0, "Modifier name"); 
 
-                       /* Softbody not allowed in this situation, enforce! */
-               if (md->type!=eModifierType_Softbody || !(ob->pd && ob->pd->deflect)) {
+               /* Softbody not allowed in this situation, enforce! */
+               if ((md->type!=eModifierType_Softbody && md->type!=eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) {
                        uiDefIconButBitI(block, TOG, eModifierMode_Render, B_MODIFIER_RECALC, ICON_SCENE, x+10+buttonWidth-60, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering");
                        uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_MODIFIER_RECALC, VICON_VIEW3D, x+10+buttonWidth-40, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display");
                        if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
@@ -1540,9 +1542,13 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
                uiButSetFunc(but, modifiers_moveDown, ob, md);
                
                uiBlockSetEmboss(block, UI_EMBOSSN);
-
-               but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, VICON_X, x+width-70+40, y, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Delete modifier");
-               uiButSetFunc(but, modifiers_del, ob, md);
+               
+               // deletion over the deflection panel
+               if(md->type!=eModifierType_Collision)
+               {
+                       but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, VICON_X, x+width-70+40, y, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Delete modifier");
+                       uiButSetFunc(but, modifiers_del, ob, md);
+               }
                uiBlockSetCol(block, TH_AUTO);
        }
 
@@ -1603,6 +1609,8 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
                        height = 26;
                } else if (md->type==eModifierType_Cloth) {
                        height = 26;
+               } else if (md->type==eModifierType_Collision) {
+                       height = 19;
                } else if (md->type==eModifierType_Boolean) {
                        height = 48;
                } else if (md->type==eModifierType_Array) {
@@ -1614,7 +1622,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
 
                y -= 18;
 
-               if (!isVirtual) {
+               if (!isVirtual && (md->type!=eModifierType_Collision)) {
                        uiBlockBeginAlign(block);
                        but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Apply",  lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Apply the current modifier and remove from the stack");
                        uiButSetFunc(but, modifiers_applyModifier, ob, md);
index 10d4d544e8695988ed727cb927299349de3e6f8f..3b232f49001a8f22236feb0a1ede2c8dca5547b2 100644 (file)
@@ -2741,10 +2741,29 @@ void do_effects_panels(unsigned short event)
 
 }
 
+/* Panel for collision */
+static void object_collision__enabletoggle(void *ob_v, void *arg2)
+{
+       Object *ob = ob_v;
+       ModifierData *md = modifiers_findByType(ob, eModifierType_Collision);
+
+       if (!md) {
+               md = modifier_new(eModifierType_Collision);
+               BLI_addhead(&ob->modifiers, md);
+       }
+       else {
+               BLI_remlink(&ob->modifiers, md);
+               modifier_free(md);
+       }
+
+       allqueue(REDRAWBUTSEDIT, 0);
+}
+
 /* Panel for particle interaction settings */
 static void object_panel_fields(Object *ob)
 {
        uiBlock *block;
+       uiBut *but;
 
        block= uiNewBlock(&curarea->uiblocks, "object_panel_fields", UI_EMBOSS, UI_HELV, curarea->win);
        if(uiNewPanel(curarea, block, "Fields and Deflection", "Physics", 0, 0, 318, 204)==0) return;
@@ -2804,7 +2823,8 @@ static void object_panel_fields(Object *ob)
                        
                /* only meshes collide now */
                if(ob->type==OB_MESH) {
-                       uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision");
+                       but = uiDefButBitS(block, TOG, 1, B_REDR, "Deflection/Collision",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Make object collision object for dynamics");
+                       uiButSetFunc(but, object_collision__enabletoggle, ob, NULL);
                        if(pd->deflect) {
                                uiDefBut(block, LABEL, 0, "Particles",                  160,140,150,20, NULL, 0.0, 0, 0, 0, "");
                                
@@ -3129,7 +3149,7 @@ static void object_panel_cloth(Object *ob)
                        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)");
+                       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");
index 9031ce48707b7a7144db6dd075aa73261f9f0c4c..9f45bd7aaa06b74408422328cba3c8d7a7b0e6fe 100644 (file)
@@ -426,8 +426,8 @@ void recalcData(TransInfo *t)
                                        if(modifiers_isSoftbodyEnabled(base->object)) {
                                                base->object->softflag |= OB_SB_REDO;
                                        }
-                                       else if(modifiers_isClothEnabled(ob)) {
-                                               cloth_free_modifier(modifiers_isClothEnabled(ob));
+                                       else if((clmd = (ClothModifierData *)modifiers_isClothEnabled(ob))) {
+                                               cloth_free_modifier(clmd);
                                        }
                                        
                                }
@@ -470,8 +470,8 @@ void recalcData(TransInfo *t)
                                if(modifiers_isSoftbodyEnabled(ob)) {
                                                ob->softflag |= OB_SB_REDO;
                                }
-                               else if(modifiers_isClothEnabled(ob)) {
-                                       cloth_free_modifier(modifiers_isClothEnabled(ob));
+                               else if((clmd = (ClothModifierData *)modifiers_isClothEnabled(ob))) {
+                                       cloth_free_modifier(clmd);
                                }
                        }