WIP commit, (just in case my HD breaks down). Don't expect anything to work. Code...
authorDaniel Genrich <daniel.genrich@gmx.net>
Mon, 22 Oct 2007 22:50:32 +0000 (22:50 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Mon, 22 Oct 2007 22:50:32 +0000 (22:50 +0000)
13 files changed:
source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/BKE_collisions.h
source/blender/blenkernel/BKE_modifier.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/blenloader/intern/readfile.c
source/blender/makesdna/DNA_cloth_types.h
source/blender/makesdna/DNA_modifier_types.h
source/blender/makesdna/DNA_object_force.h
source/blender/src/editobject.c

index 1c5310c10d162e1f6dd1626c3e67f2fb4ea4af35..19851321b30b079ee19b4e070941a2e0c75a564c 100644 (file)
@@ -122,7 +122,7 @@ void cloth_free_modifier ( ClothModifierData *clmd );
 void implicit_set_positions ( ClothModifierData *clmd );
 
 // from cloth.c, needed for modifier.c
 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 );
+DerivedMesh *clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm);
 
 ////////////////////////////////////////////////
 
 
 ////////////////////////////////////////////////
 
@@ -132,9 +132,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, fl
 ////////////////////////////////////////////////
 void cloth_free_modifier ( ClothModifierData *clmd );
 void cloth_init ( ClothModifierData *clmd );
 ////////////////////////////////////////////////
 void cloth_free_modifier ( ClothModifierData *clmd );
 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 );
 void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int totface );
-
 ////////////////////////////////////////////////
 
 
 ////////////////////////////////////////////////
 
 
index 0536a72d74b334fcbe7cc7e016e050e06f3b895c..8c7933f3434cd525e3db1da225d6d5389cb08b41 100644 (file)
 #include "BKE_DerivedMesh.h"
 
 // used in kdop.c and collision.c
 #include "BKE_DerivedMesh.h"
 
 // used in kdop.c and 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
        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;
 }
        int     count_nodes; // how many nodes are used
        int     traversed;  // how many nodes already traversed until this level?
        int     isleaf;
 }
-Tree;
+CollisionTree;
 
 
-typedef struct Tree TreeNode;
+typedef struct CollisionTree TreeNode;
 
 typedef struct BVH
 {
 
 typedef struct BVH
 {
@@ -79,7 +79,7 @@ BVH;
 /* used for collisions in kdop.c and also collision.c*/
 typedef struct CollisionPair
 {
 /* used for collisions in kdop.c and also collision.c*/
 typedef struct CollisionPair
 {
-       unsigned int indexA, indexB;
+       int point_indexA[4], point_indexB[4];
 }
 CollisionPair;
 
 }
 CollisionPair;
 
@@ -89,18 +89,21 @@ CollisionPair;
 /////////////////////////////////////////////////
 
 // builds bounding volume hierarchy
 /////////////////////////////////////////////////
 
 // builds bounding volume hierarchy
-BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xold, unsigned int numverts, float epsilon);
+BVH *bvh_build (MFace *mfaces, unsigned int numfaces, MVert *x, MVert *xnew, unsigned int numverts, float epsilon);
 // frees the same
 void bvh_free ( BVH *bvh );
 
 // checks two bounding volume hierarchies for potential collisions and returns some list with those
 // frees the same
 void bvh_free ( BVH *bvh );
 
 // checks two bounding volume hierarchies for potential collisions and returns some list with those
-int bvh_traverse(Tree *tree1, Tree *tree2, LinkNode *collision_list);
+int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision_list);
 
 // update bounding volumes, needs updated positions in bvh->x
 
 // update bounding volumes, needs updated positions in bvh->x
-void bvh_update(DerivedMesh *dm, BVH * bvh, int moving);
+void bvh_update(BVH * bvh, int moving);
 
 
-LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr );
+LinkNode *BLI_linklist_append_fast (LinkNode **listp, void *ptr);
 
 
+// move Collision modifier object inter-frame with step = [0,1]
+// defined in collisions.c
+void collision_move_object(CollisionModifierData *collmd, float step);
 
 /////////////////////////////////////////////////
 
 
 /////////////////////////////////////////////////
 
index 365381f5cdd3e17d01961a6ede245d592ab46dff..644c3dd32f40db36ceb8c8e4eb56a822007ea8ad 100644 (file)
@@ -277,7 +277,7 @@ int           modifiers_getCageIndex(struct Object *ob,
                                      int *lastPossibleCageIndex_r);
 
 int           modifiers_isSoftbodyEnabled(struct Object *ob);
                                      int *lastPossibleCageIndex_r);
 
 int           modifiers_isSoftbodyEnabled(struct Object *ob);
-struct ModifierData  *modifiers_isClothEnabled(struct Object *ob);
+struct ClothModifierData *modifiers_isClothEnabled(Object *ob);
 struct Object *modifiers_isDeformedByArmature(struct Object *ob);
 struct Object *modifiers_isDeformedByLattice(struct Object *ob);
 int           modifiers_usesArmature(struct Object *ob, struct bArmature *arm);
 struct Object *modifiers_isDeformedByArmature(struct Object *ob);
 struct Object *modifiers_isDeformedByLattice(struct Object *ob);
 int           modifiers_usesArmature(struct Object *ob, struct bArmature *arm);
index dce36f543eeddb5ecbfafaf680e9249b8eb99114..4c4bac7bbf9806aa0d6a3958503558813b4b23e9 100644 (file)
@@ -120,10 +120,9 @@ static CM_SOLVER_DEF       solvers [] =
 /* ********** cloth engine ******* */
 /* Prototypes for internal functions.
 */
 /* ********** cloth engine ******* */
 /* Prototypes for internal functions.
 */
-static void cloth_to_object ( Object *ob, ClothModifierData *clmd, float ( *vertexCos ) [3], unsigned int numverts );
+static void cloth_to_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm );
 static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm );
 static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm );
-static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts );
-static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts );
+static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm );
 int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm );
 static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup );
 
 int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm );
 static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup );
 
@@ -603,69 +602,63 @@ void cloth_cache_free ( ClothModifierData *clmd, float time )
 * cloth_deform_verts - simulates one step, framenr is in frames.
 *
 **/
 * cloth_deform_verts - simulates one step, framenr is in frames.
 *
 **/
-void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
-                        float ( *vertexCos ) [3], int numverts )
+DerivedMesh *clothModifier_do(ClothModifierData *clmd,
+                                        Object *ob, DerivedMesh *dm)
 {
        unsigned int i;
 {
        unsigned int i;
-       unsigned int numedges = -1;
-       unsigned int numfaces = -1;
-       MVert *mvert = NULL;
-       MEdge *medge = NULL;
-       MFace *mface = NULL;
-       DerivedMesh *result = NULL, *result2 = NULL;
+       DerivedMesh *result = NULL;
        Cloth *cloth = clmd->clothObject;
        unsigned int framenr = ( float ) G.scene->r.cfra;
        float current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 );
        Cloth *cloth = clmd->clothObject;
        unsigned int framenr = ( float ) G.scene->r.cfra;
        float current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 );
-       ListBase        *effectors = NULL;
-       ClothVertex *newframe= NULL, *verts;
+       ListBase *effectors = NULL;
+       ClothVertex *verts = NULL;
        Frame *frame = NULL;
        LinkNode *search = NULL;
        float deltaTime = current_time - clmd->sim_parms.sim_time;
        Frame *frame = NULL;
        LinkNode *search = NULL;
        float deltaTime = current_time - clmd->sim_parms.sim_time;
+       MVert *mverts = NULL;
+       
+       result = CDDM_copy(dm);
        
        // only be active during a specific period:
        // that's "first frame" and "last frame" on GUI
        
        // only be active during a specific period:
        // that's "first frame" and "last frame" on GUI
-       if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) )
+       if ( clmd->clothObject )
        {
        {
-               if ( clmd->clothObject )
+               if ( clmd->sim_parms.cache )
                {
                {
-                       if ( clmd->sim_parms.cache )
+                       if ( current_time < clmd->sim_parms.firstframe )
                        {
                        {
-                               if ( current_time < clmd->sim_parms.firstframe )
+                               int frametime = cloth_cache_first_frame ( clmd );
+                               if ( cloth_cache_search_frame ( clmd, frametime ) )
                                {
                                {
-                                       int frametime = cloth_cache_first_frame ( clmd );
-                                       if ( cloth_cache_search_frame ( clmd, frametime ) )
-                                       {
-                                               cloth_cache_get_frame ( clmd, frametime );
-                                               cloth_to_object ( ob, clmd, vertexCos, numverts );
-                                       }
-                                       return;
+                                       cloth_cache_get_frame ( clmd, frametime );
+                                       cloth_to_object ( ob, clmd, result );
                                }
                                }
-                               else if ( current_time > clmd->sim_parms.lastframe )
+                               return;
+                       }
+                       else if ( current_time > clmd->sim_parms.lastframe )
+                       {
+                               int frametime = cloth_cache_last_frame ( clmd );
+                               if ( cloth_cache_search_frame ( clmd, frametime ) )
                                {
                                {
-                                       int frametime = cloth_cache_last_frame ( clmd );
-                                       if ( cloth_cache_search_frame ( clmd, frametime ) )
-                                       {
-                                               cloth_cache_get_frame ( clmd, frametime );
-                                               cloth_to_object ( ob, clmd, vertexCos, numverts );
-                                       }
-                                       return;
+                                       cloth_cache_get_frame ( clmd, frametime );
+                                       cloth_to_object ( ob, clmd, result );
                                }
                                }
-                               else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed
+                               return;
+                       }
+                       else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed
+                       {
+                               if ( cloth_cache_search_frame ( clmd, framenr ) )
                                {
                                {
-                                       if ( cloth_cache_search_frame ( clmd, framenr ) )
-                                       {
-                                               cloth_cache_get_frame ( clmd, framenr );
-                                               cloth_to_object ( ob, clmd, vertexCos, numverts );
-                                       }
-                                       clmd->sim_parms.sim_time = current_time;
-                                       return;
+                                       cloth_cache_get_frame ( clmd, framenr );
+                                       cloth_to_object ( ob, clmd, result );
                                }
                                }
+                               clmd->sim_parms.sim_time = current_time;
+                               return;
                        }
                        }
-
                }
                }
-       }
-
 
 
+       }
+       
        // unused in the moment, calculated seperately in implicit.c
        clmd->sim_parms.dt = 1.0f / clmd->sim_parms.stepsPerFrame;
 
        // unused in the moment, calculated seperately in implicit.c
        clmd->sim_parms.dt = 1.0f / clmd->sim_parms.stepsPerFrame;
 
@@ -673,9 +666,9 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
        
        if ( deltaTime == 1.0f )
        {
        
        if ( deltaTime == 1.0f )
        {
-               if ( ( clmd->clothObject == NULL ) || ( numverts != clmd->clothObject->numverts ) )
+               if ( ( clmd->clothObject == NULL ) || ( dm->getNumVerts(dm) != clmd->clothObject->numverts ) )
                {
                {
-                       if ( !cloth_from_object ( ob, clmd, dm, vertexCos, numverts ) )
+                       if ( !cloth_from_object ( ob, clmd, dm ) )
                                return;
 
                        if ( clmd->clothObject == NULL )
                                return;
 
                        if ( clmd->clothObject == NULL )
@@ -692,6 +685,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
                        if ( !cloth_cache_search_frame ( clmd, framenr ) )
                        {
                                verts = cloth->verts;
                        if ( !cloth_cache_search_frame ( clmd, framenr ) )
                        {
                                verts = cloth->verts;
+                               mverts = dm->getVertArray(dm);
 
                                // Force any pinned verts to their constrained location.
                                for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ )
 
                                // Force any pinned verts to their constrained location.
                                for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ )
@@ -699,9 +693,8 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
                                        // Save the previous position.
                                        VECCOPY ( verts->xold, verts->xconst );
                                        VECCOPY ( verts->txold, verts->x );
                                        // Save the previous position.
                                        VECCOPY ( verts->xold, verts->xconst );
                                        VECCOPY ( verts->txold, verts->x );
-
                                        // Get the current position.
                                        // Get the current position.
-                                       VECCOPY ( verts->xconst, vertexCos[i] );
+                                       VECCOPY ( verts->xconst, mverts[i].co );
                                        Mat4MulVecfl ( ob->obmat, verts->xconst );
                                }
 
                                        Mat4MulVecfl ( ob->obmat, verts->xconst );
                                }
 
@@ -723,7 +716,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
                        }
 
                        // Copy the result back to the object.
                        }
 
                        // Copy the result back to the object.
-                       cloth_to_object ( ob, clmd, vertexCos, numverts );
+                       cloth_to_object ( ob, clmd, result );
 
                        // bvh_free(clmd->clothObject->tree);
                        // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon);
 
                        // bvh_free(clmd->clothObject->tree);
                        // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon);
@@ -737,11 +730,12 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
                        if ( cloth_cache_search_frame ( clmd, framenr ) )
                        {
                                cloth_cache_get_frame ( clmd, framenr );
                        if ( cloth_cache_search_frame ( clmd, framenr ) )
                        {
                                cloth_cache_get_frame ( clmd, framenr );
-                               cloth_to_object ( ob, clmd, vertexCos, numverts );
+                               cloth_to_object ( ob, clmd, result );
                        }
                }
        }
                        }
                }
        }
-
+       
+       return result;
 }
 
 /* frees all */
 }
 
 /* frees all */
@@ -771,6 +765,14 @@ void cloth_free_modifier ( ClothModifierData *clmd )
                        // Free the verts.
                        if ( cloth->verts != NULL )
                                MEM_freeN ( cloth->verts );
                        // Free the verts.
                        if ( cloth->verts != NULL )
                                MEM_freeN ( cloth->verts );
+                       
+                       // Free the verts.
+                       if ( cloth->x != NULL )
+                               MEM_freeN ( cloth->x );
+                       
+                       // Free the verts.
+                       if ( cloth->xnew != NULL )
+                               MEM_freeN ( cloth->xnew );
 
                        cloth->verts = NULL;
                        cloth->numverts = 0;
 
                        cloth->verts = NULL;
                        cloth->numverts = 0;
@@ -823,22 +825,24 @@ void cloth_free_modifier ( ClothModifierData *clmd )
 *
 * This function is a modified version of the softbody.c:softbody_to_object() function.
 **/
 *
 * This function is a modified version of the softbody.c:softbody_to_object() function.
 **/
-static void cloth_to_object ( Object *ob, ClothModifierData *clmd, float ( *vertexCos ) [3], unsigned int numverts )
+static void cloth_to_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm )
 {
        ClothVertex     *verts = NULL;
        unsigned int    i = 0;
 {
        ClothVertex     *verts = NULL;
        unsigned int    i = 0;
+       MVert           *mvert = NULL;
 
        if ( clmd->clothObject )
        {
                verts = clmd->clothObject->verts;
 
        if ( clmd->clothObject )
        {
                verts = clmd->clothObject->verts;
+               mvert = dm->getVertArray(dm);
 
                /* inverse matrix is not uptodate... */
                Mat4Invert ( ob->imat, ob->obmat );
 
 
                /* inverse matrix is not uptodate... */
                Mat4Invert ( ob->imat, ob->obmat );
 
-               for ( i = 0; i < numverts; i++, verts++ )
+               for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ )
                {
                {
-                       VECCOPY ( vertexCos[i], verts->x );
-                       Mat4MulVecfl ( ob->imat, vertexCos[i] );        /* softbody is in global coords */
+                       VECCOPY ( mvert[i].co, verts->x );
+                       Mat4MulVecfl ( ob->imat, mvert[i].co ); /* softbody is in global coords */
                }
        }
 }
                }
        }
 }
@@ -903,7 +907,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short
 }
 
 // only meshes supported at the moment
 }
 
 // only meshes supported at the moment
-static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts )
+static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm )
 {
        unsigned int i = 0;
        // dm->getNumVerts(dm);
 {
        unsigned int i = 0;
        // dm->getNumVerts(dm);
@@ -954,7 +958,7 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh
                                verts = clmd->clothObject->verts;
 
                                /* set initial values */
                                verts = clmd->clothObject->verts;
 
                                /* set initial values */
-                               for ( i = 0; i < numverts; i++, verts++ )
+                               for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ )
                                {
                                        VECCOPY ( verts->x, mvert[i].co );
                                        Mat4MulVecfl ( ob->obmat, verts->x );
                                {
                                        VECCOPY ( verts->x, mvert[i].co );
                                        Mat4MulVecfl ( ob->obmat, verts->x );
@@ -1021,6 +1025,22 @@ static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *
                modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->verts." );
                return;
        }
                modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->verts." );
                return;
        }
+       
+       clmd->clothObject->x = MEM_callocN ( sizeof ( MVert ) * clmd->clothObject->numverts, "Cloth MVert_x" );
+       if ( clmd->clothObject->x == NULL )
+       {
+               cloth_free_modifier ( clmd );
+               modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->x." );
+               return;
+       }
+       
+       clmd->clothObject->xnew = MEM_callocN ( sizeof ( MVert ) * clmd->clothObject->numverts, "Cloth MVert_xnew" );
+       if ( clmd->clothObject->xnew == NULL )
+       {
+               cloth_free_modifier ( clmd );
+               modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->xnew." );
+               return;
+       }
 
        // save face information
        clmd->clothObject->numfaces = numfaces;
 
        // save face information
        clmd->clothObject->numfaces = numfaces;
@@ -1067,7 +1087,10 @@ int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned in
                cloth->numsprings++;
        
                BLI_linklist_append ( &cloth->springs, spring );
                cloth->numsprings++;
        
                BLI_linklist_append ( &cloth->springs, spring );
+               
+               return 1;
        }
        }
+       return 0;
 }
 
 int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm )
 }
 
 int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm )
index 41823b0ad3974d91ec3232d5ede473e97ffc83f5..f4b0ce7312b918372c30f6f3b0f65355770c2177 100644 (file)
 #include "Bullet-C-Api.h"
 
 
 #include "Bullet-C-Api.h"
 
 
+// step is limited from 0 (frame start position) to 1 (frame end position)
+void collision_move_object(CollisionModifierData *collmd, float step)
+{
+       float tv[3] = {0,0,0};
+       unsigned int i = 0;
+       MVert *tempVert = collmd->current_x;
+       collmd->current_x = collmd->current_xnew;
+       collmd->current_xnew = tempVert;
+                       
+       for ( i = 0; i < collmd->numverts; i++ )
+       {
+               VECSUB(tv, collmd->xnew[i].co, collmd->x[i].co);
+               VECADDS(collmd->current_xnew[i].co, collmd->x[i].co, tv, step);
+       }
+}
+
 
 /**
  * gsl_poly_solve_cubic -
 
 /**
  * gsl_poly_solve_cubic -
@@ -362,846 +378,3 @@ DO_INLINE void interpolateOnTriangle(float to[3], float v1[3], float v2[3], floa
        VECADDMUL(to, v3, w3);
 }
 
        VECADDMUL(to, v3, w3);
 }
 
-// unused in the moment, has some bug in
-DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal[3], double normalVelocity,
-                                       double frictionConstant, double delta_V_n) 
-{
-       float vrel_t_pre[3];
-       float vrel_t[3];
-       VECSUBS(vrel_t_pre, vrel, normal, normalVelocity);
-       VECCOPY(to, vrel_t_pre);
-       VecMulf(to, MAX2(1.0f - frictionConstant * delta_V_n / INPR(vrel_t_pre,vrel_t_pre), 0.0f));
-}
-
-int collisions_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd)
-{
-       /*
-       unsigned int i = 0;
-       int result = 0;
-       LinkNode *search = NULL;
-       CollPair *collpair = NULL;
-       Cloth *cloth1, *cloth2;
-       float w1, w2, w3, u1, u2, u3;
-       float v1[3], v2[3], relativeVelocity[3];
-       float magrelVel;
-       
-       cloth1 = clmd->clothObject;
-       cloth2 = coll_clmd->clothObject;
-
-       // search = clmd->coll_parms.collision_list;
-       
-       while(search)
-       {
-               collpair = search->link;
-               
-               // compute barycentric coordinates for both collision points
-               collisions_compute_barycentric(collpair->pa,
-                                       cloth1->verts[collpair->ap1].txold,
-                                       cloth1->verts[collpair->ap2].txold,
-                                       cloth1->verts[collpair->ap3].txold, 
-                                       &w1, &w2, &w3);
-       
-               collisions_compute_barycentric(collpair->pb,
-                                       cloth2->verts[collpair->bp1].txold,
-                                       cloth2->verts[collpair->bp2].txold,
-                                       cloth2->verts[collpair->bp3].txold,
-                                       &u1, &u2, &u3);
-       
-               // Calculate relative "velocity".
-               interpolateOnTriangle(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3);
-               
-               interpolateOnTriangle(v2, cloth2->verts[collpair->bp1].tv, cloth2->verts[collpair->bp2].tv, cloth2->verts[collpair->bp3].tv, u1, u2, u3);
-               
-               VECSUB(relativeVelocity, v1, v2);
-                       
-               // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
-               magrelVel = INPR(relativeVelocity, collpair->normal);
-               
-               // printf("magrelVel: %f\n", magrelVel);
-                               
-               // Calculate masses of points.
-               
-               // If v_n_mag < 0 the edges are approaching each other.
-               if(magrelVel < -ALMOST_ZERO) 
-               {
-                       // Calculate Impulse magnitude to stop all motion in normal direction.
-                       // const double I_mag = v_n_mag / (1/m1 + 1/m2);
-                       float magnitude_i = magrelVel / 2.0f; // TODO implement masses
-                       float tangential[3], magtangent, magnormal, collvel[3];
-                       float vrel_t_pre[3];
-                       float vrel_t[3];
-                       double impulse;
-                       float epsilon = clmd->coll_parms.epsilon;
-                       float overlap = (epsilon + ALMOST_ZERO-collpair->distance);
-                       
-                       // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel);
-                       
-                       // magtangent = INPR(tangential, tangential);
-                       
-                       // Apply friction impulse.
-                       if (magtangent < -ALMOST_ZERO) 
-                       {
-                               
-                               // printf("friction applied: %f\n", magtangent);
-                               // TODO check original code 
-                       }
-                       
-
-                       impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
-                       
-                       // printf("impulse: %f\n", impulse);
-                       
-                       // face A
-                       VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); 
-                       cloth1->verts[collpair->ap1].impulse_count++;
-                       
-                       VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse); 
-                       cloth1->verts[collpair->ap2].impulse_count++;
-                       
-                       VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); 
-                       cloth1->verts[collpair->ap3].impulse_count++;
-                       
-                       // face B
-                       VECADDMUL(cloth2->verts[collpair->bp1].impulse, collpair->normal, u1 * impulse); 
-                       cloth2->verts[collpair->bp1].impulse_count++;
-                       
-                       VECADDMUL(cloth2->verts[collpair->bp2].impulse, collpair->normal, u2 * impulse); 
-                       cloth2->verts[collpair->bp2].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.
-       
-                       
-               }
-               
-               search = search->next;
-       }
-       
-       
-       return result;
-       */
-       return 0;
-}
-
-
-int collisions_collision_response_moving_tris(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;
-       ClothVertex *verts1=NULL, *verts2=NULL;
-       double distance = 0;
-       float epsilon = clmd->coll_parms.epsilon;
-       unsigned int i = 0;
-
-       for(i = 0; i < 4; i++)
-       {
-               collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair");                
-               
-               cloth1 = clmd->clothObject;
-               cloth2 = coll_clmd->clothObject;
-               
-               verts1 = cloth1->verts;
-               verts2 = cloth2->verts;
-       
-               face1 = &(cloth1->mfaces[tree1->tri_index]);
-               face2 = &(cloth2->mfaces[tree2->tri_index]);
-               
-               // check all possible pairs of triangles
-               if(i == 0)
-               {
-                       collpair->ap1 = face1->v1;
-                       collpair->ap2 = face1->v2;
-                       collpair->ap3 = face1->v3;
-                       
-                       collpair->bp1 = face2->v1;
-                       collpair->bp2 = face2->v2;
-                       collpair->bp3 = face2->v3;
-                       
-               }
-               
-               if(i == 1)
-               {
-                       if(face1->v4)
-                       {
-                               collpair->ap1 = face1->v3;
-                               collpair->ap2 = face1->v4;
-                               collpair->ap3 = face1->v1;
-                               
-                               collpair->bp1 = face2->v1;
-                               collpair->bp2 = face2->v2;
-                               collpair->bp3 = face2->v3;
-                       }
-                       else
-                               i++;
-               }
-               
-               if(i == 2)
-               {
-                       if(face2->v4)
-                       {
-                               collpair->ap1 = face1->v1;
-                               collpair->ap2 = face1->v2;
-                               collpair->ap3 = face1->v3;
-                               
-                               collpair->bp1 = face2->v3;
-                               collpair->bp2 = face2->v4;
-                               collpair->bp3 = face2->v1;
-                       }
-                       else
-                               i+=2;
-               }
-               
-               if(i == 3)
-               {
-                       if((face1->v4)&&(face2->v4))
-                       {
-                               collpair->ap1 = face1->v3;
-                               collpair->ap2 = face1->v4;
-                               collpair->ap3 = face1->v1;
-                               
-                               collpair->bp1 = face2->v3;
-                               collpair->bp2 = face2->v4;
-                               collpair->bp3 = face2->v1;
-                       }
-                       else
-                               i++;
-               }
-               
-               // calc SIPcode (?)
-               
-               if(i < 4)
-               {
-                       // calc distance + normal       
-                       distance = plNearestPoints(
-                                       verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, verts2[collpair->bp1].txold, verts2[collpair->bp2].txold, verts2[collpair->bp3].txold, collpair->pa,collpair->pb,collpair->vector);
-                       
-                       if (distance <= (epsilon + ALMOST_ZERO))
-                       {
-                               // printf("dist: %f\n", (float)distance);
-                               
-                               // collpair->face1 = tree1->tri_index;
-                               // collpair->face2 = tree2->tri_index;
-                               
-                               // VECCOPY(collpair->normal, collpair->vector);
-                               // Normalize(collpair->normal);
-                               
-                               // collpair->distance = distance;
-                               
-                       }
-                       else
-                       {
-                               MEM_freeN(collpair);
-                       }
-               }
-               else
-               {
-                       MEM_freeN(collpair);
-               }
-       }
-       */
-}
-
-int collisions_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair)
-{
-       Cloth *cloth1, *cloth2;
-       ClothVertex *verts1, *verts2;
-       float temp[3];
-        
-       cloth1 = clmd->clothObject;
-       cloth2 = coll_clmd->clothObject;
-       
-       verts1 = cloth1->verts;
-       verts2 = cloth2->verts;
-       
-       VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].xold);
-       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
-               return 1;
-       
-       VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].xold);
-       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
-               return 1;
-       
-       VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].xold);
-       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
-               return 1;
-       
-       VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].xold);
-       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
-               return 1;
-               
-       return 0;
-}
-
-void collisions_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
-{
-       EdgeCollPair edgecollpair;
-       Cloth *cloth1=NULL, *cloth2=NULL;
-       MFace *face1=NULL, *face2=NULL;
-       ClothVertex *verts1=NULL, *verts2=NULL;
-       double distance = 0;
-       float epsilon = clmd->coll_parms.epsilon;
-       unsigned int i = 0, j = 0, k = 0;
-       int numsolutions = 0;
-       float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
-       
-       cloth1 = clmd->clothObject;
-       cloth2 = coll_clmd->clothObject;
-       
-       verts1 = cloth1->verts;
-       verts2 = cloth2->verts;
-
-       face1 = &(cloth1->mfaces[tree1->tri_index]);
-       face2 = &(cloth2->mfaces[tree2->tri_index]);
-       
-       for( i = 0; i < 5; i++)
-       {
-               if(i == 0) 
-               {
-                       edgecollpair.p11 = face1->v1;
-                       edgecollpair.p12 = face1->v2;
-               }
-               else if(i == 1) 
-               {
-                       edgecollpair.p11 = face1->v2;
-                       edgecollpair.p12 = face1->v3;
-               }
-               else if(i == 2) 
-               {
-                       if(face1->v4) 
-                       {
-                               edgecollpair.p11 = face1->v3;
-                               edgecollpair.p12 = face1->v4;
-                       }
-                       else 
-                       {
-                               edgecollpair.p11 = face1->v3;
-                               edgecollpair.p12 = face1->v1;
-                               i+=5; // get out of here after this edge pair is handled
-                       }
-               }
-               else if(i == 3) 
-               {
-                       if(face1->v4) 
-                       {
-                               edgecollpair.p11 = face1->v4;
-                               edgecollpair.p12 = face1->v1;
-                       }       
-                       else
-                               continue;
-               }
-               else
-               {
-                       edgecollpair.p11 = face1->v3;
-                       edgecollpair.p12 = face1->v1;
-               }
-
-               
-               for( j = 0; j < 5; j++)
-               {
-                       if(j == 0)
-                       {
-                               edgecollpair.p21 = face2->v1;
-                               edgecollpair.p22 = face2->v2;
-                       }
-                       else if(j == 1)
-                       {
-                               edgecollpair.p21 = face2->v2;
-                               edgecollpair.p22 = face2->v3;
-                       }
-                       else if(j == 2)
-                       {
-                               if(face2->v4) 
-                               {
-                                       edgecollpair.p21 = face2->v3;
-                                       edgecollpair.p22 = face2->v4;
-                               }
-                               else 
-                               {
-                                       edgecollpair.p21 = face2->v3;
-                                       edgecollpair.p22 = face2->v1;
-                               }
-                       }
-                       else if(j == 3)
-                       {
-                               if(face2->v4) 
-                               {
-                                       edgecollpair.p21 = face2->v4;
-                                       edgecollpair.p22 = face2->v1;
-                               }
-                               else
-                                       continue;
-                       }
-                       else
-                       {
-                               edgecollpair.p21 = face2->v3;
-                               edgecollpair.p22 = face2->v1;
-                       }
-                       
-                       
-                       if(!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);
-                               VECSUB(c, verts1[edgecollpair.p21].xold, verts1[edgecollpair.p11].xold);
-                               VECSUB(d, verts1[edgecollpair.p21].v, verts1[edgecollpair.p11].v);
-                               VECSUB(e, verts2[edgecollpair.p22].xold, verts1[edgecollpair.p11].xold);
-                               VECSUB(f, verts2[edgecollpair.p22].v, verts1[edgecollpair.p11].v);
-                               
-                               numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution);
-                               
-                               for (k = 0; k < numsolutions; k++) 
-                               {                                                               
-                                       if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) 
-                                       {
-                                               float out_collisionTime = solution[k];
-                                               
-                                               // TODO: check for collisions 
-                                               
-                                               // TODO: put into (edge) collision list
-                                               
-                                               printf("Moving edge found!\n");
-                                       }
-                               }
-                       }
-               }
-       }               
-}
-
-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;
-       ClothVertex *verts1=NULL, *verts2=NULL;
-       double distance = 0;
-       float epsilon = clmd->coll_parms.epsilon;
-       unsigned int i = 0, j = 0, k = 0;
-       int numsolutions = 0;
-       float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
-
-       for(i = 0; i < 2; i++)
-       {               
-               cloth1 = clmd->clothObject;
-               cloth2 = coll_clmd->clothObject;
-               
-               verts1 = cloth1->verts;
-               verts2 = cloth2->verts;
-       
-               face1 = &(cloth1->mfaces[tree1->tri_index]);
-               face2 = &(cloth2->mfaces[tree2->tri_index]);
-               
-               // check all possible pairs of triangles
-               if(i == 0)
-               {
-                       collpair.ap1 = face1->v1;
-                       collpair.ap2 = face1->v2;
-                       collpair.ap3 = face1->v3;
-                       
-                       collpair.pointsb[0] = face2->v1;
-                       collpair.pointsb[1] = face2->v2;
-                       collpair.pointsb[2] = face2->v3;
-                       collpair.pointsb[3] = face2->v4;
-               }
-               
-               if(i == 1)
-               {
-                       if(face1->v4)
-                       {
-                               collpair.ap1 = face1->v3;
-                               collpair.ap2 = face1->v4;
-                               collpair.ap3 = face1->v1;
-                               
-                               collpair.pointsb[0] = face2->v1;
-                               collpair.pointsb[1] = face2->v2;
-                               collpair.pointsb[2] = face2->v3;
-                               collpair.pointsb[3] = face2->v4;
-                       }
-                       else
-                               i++;
-               }
-               
-               // calc SIPcode (?)
-               
-               if(i < 2)
-               {
-                       VECSUB(a, verts1[collpair.ap2].xold, verts1[collpair.ap1].xold);
-                       VECSUB(b, verts1[collpair.ap2].v, verts1[collpair.ap1].v);
-                       VECSUB(c, verts1[collpair.ap3].xold, verts1[collpair.ap1].xold);
-                       VECSUB(d, verts1[collpair.ap3].v, verts1[collpair.ap1].v);
-                               
-                       for(j = 0; j < 4; j++)
-                       {                                       
-                               if((j==3) && !(face2->v4))
-                                       break;
-                               
-                               VECSUB(e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold);
-                               VECSUB(f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v);
-                               
-                               numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution);
-                               
-                               for (k = 0; k < numsolutions; k++) 
-                               {                                                               
-                                       if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) 
-                                       {
-                                               float out_collisionTime = solution[k];
-                                               
-                                               // TODO: check for collisions 
-                                               
-                                               // TODO: put into (point-face) collision list
-                                               
-                                               printf("Moving found!\n");
-                                               
-                                       }
-                               }
-                               
-                               // TODO: check borders for collisions
-                       }
-                       
-               }
-       }
-       */
-}
-
-void collisions_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
-{
-       /*
-       // TODO: check for adjacent
-       collisions_collision_moving_edges(clmd, coll_clmd, tree1, tree2);
-       
-       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 collisions_update_collision_objects(float step)
-{
-       Base *base=NULL;
-       ClothModifierData *coll_clmd=NULL;
-       Object *coll_ob=NULL;
-       unsigned int i=0;
-       
-       // search all objects for collision object
-       for (base = G.scene->base.first; base; base = base->next)
-       {
-
-               coll_ob = base->object;
-               coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
-               if (!coll_clmd)
-                       continue;
-
-               // if collision object go on
-               if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
-               {
-                       if (coll_clmd->clothObject && coll_clmd->clothObject->tree) 
-                       {
-                               Cloth *coll_cloth = coll_clmd->clothObject;
-                               BVH *coll_bvh = coll_clmd->clothObject->tree;
-                               unsigned int coll_numverts = coll_cloth->numverts;
-
-                               // update position of collision object
-                               for(i = 0; i < coll_numverts; i++)
-                               {
-                                       VECCOPY(coll_cloth->verts[i].txold, coll_cloth->verts[i].tx);
-
-                                       VECADDS(coll_cloth->verts[i].tx, coll_cloth->verts[i].xold, coll_cloth->verts[i].v, step);
-                                       
-                                       // no dt here because of float rounding errors
-                                       VECSUB(coll_cloth->verts[i].tv, coll_cloth->verts[i].tx, coll_cloth->verts[i].txold);
-                               }
-                               
-                               // update BVH of collision object
-                               // bvh_update(coll_clmd, coll_bvh, 0); // 0 means STATIC, 1 means MOVING 
-                       }
-                       else
-                               printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
-               }
-       }
-}
-
-// collisions_MAX_THRESHOLD defines how much collision rounds/loops should be taken
-#define CLOTH_MAX_THRESHOLD 10
-
-// cloth - object collisions
-int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
-{
-       Base *base=NULL;
-       ClothModifierData *coll_clmd=NULL;
-       Cloth *cloth=NULL;
-       Object *coll_ob=NULL;
-       BVH *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))
-       {
-               return 0;
-       }
-       cloth = clmd->clothObject;
-       verts = cloth->verts;
-       collisions_bvh = (BVH *) cloth->tree;
-       numfaces = clmd->clothObject->numfaces;
-       numverts = clmd->clothObject->numverts;
-       
-       ////////////////////////////////////////////////////////////
-       // static collisions
-       ////////////////////////////////////////////////////////////
-
-       // update cloth bvh
-       // bvh_update(clmd, collisions_bvh, 0); // 0 means STATIC, 1 means MOVING (see later in this function)
-       
-       // update collision objects
-       collisions_update_collision_objects(step);
-       
-       do
-       {
-               result = 0;
-               ic = 0;
-               
-               // check all collision objects
-               for (base = G.scene->base.first; base; base = base->next)
-               {
-                       coll_ob = base->object;
-                       coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
-                       
-                       if (!coll_clmd)
-                               continue;
-                       
-                       // if collision object go on
-                       if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
-                       {
-                               if (coll_clmd->clothObject && coll_clmd->clothObject->tree) 
-                               {
-                                       BVH *coll_bvh = coll_clmd->clothObject->tree;
-                                       
-                                       // 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);
-                       
-                                               // 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(collision_list)
-                                       {
-                                               LinkNode *search = collision_list;
-                                               while(search)
-                                               {
-                                                       CollisionPair *coll_pair = search->link;
-                                                       
-                                                       MEM_freeN(coll_pair);
-                                                       search = search->next;
-                                               }
-                                               BLI_linklist_free(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++;
-       }
-       while(result && (CLOTH_MAX_THRESHOLD>rounds));
-       
-       printf("\n");
-                       
-       ////////////////////////////////////////////////////////////
-       // update positions
-       // this is needed for bvh_calc_DOP_hull_moving() [kdop.c]
-       ////////////////////////////////////////////////////////////
-       
-       // verts come from clmd
-       for(i = 0; i < numverts; i++)
-       {
-               VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
-       }
-       ////////////////////////////////////////////////////////////
-
-       ////////////////////////////////////////////////////////////
-       // moving collisions
-       ////////////////////////////////////////////////////////////
-
-       
-       // update cloth bvh
-       // bvh_update(clmd, 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)
-       {
-               
-               coll_ob = base->object;
-               coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
-               if (!coll_clmd)
-                       continue;
-               
-               if(!coll_clmd->clothObject)
-                       continue;
-               
-                               // if collision object go on
-               if (coll_clmd->clothObject && coll_clmd->clothObject->tree) 
-               {
-                       BVH *coll_bvh = coll_clmd->clothObject->tree;
-                       
-                       // bvh_update(coll_clmd, coll_bvh, 1);  // 0 means STATIC, 1 means MOVING       
-               }
-       }
-       
-       
-       do
-       {
-               result = 0;
-               ic = 0;
-               
-               // check all collision objects
-               for (base = G.scene->base.first; base; base = base->next)
-               {
-                       coll_ob = base->object;
-                       coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
-                       
-                       if (!coll_clmd)
-                               continue;
-                       
-                       // if collision object go on
-                       if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
-                       {
-                               if (coll_clmd->clothObject && coll_clmd->clothObject->tree) 
-                               {
-                                       BVH *coll_bvh = coll_clmd->clothObject->tree;
-                                       
-                                       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
-                                               
-                                               /*
-                                               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;
-                                                       
-                                                               ic++;
-                                                               ret++;
-                                                       }
-                                               }
-                                       }
-               
-               
-                                       // verts come from clmd
-                                       for(i = 0; i < numverts; i++)
-                                       {
-                                               VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
-                                       }
-               
-                                       // update cloth bvh
-                                       // bvh_update(clmd, collisions_bvh, 1);  // 0 means STATIC, 1 means MOVING 
-               
-               
-                                       // 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(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++;
-       }
-       while(result && (CLOTH_MAX_THRESHOLD>rounds));
-       
-       
-       ////////////////////////////////////////////////////////////
-       // update positions + velocities
-       ////////////////////////////////////////////////////////////
-       
-       // verts come from clmd
-       for(i = 0; i < numverts; i++)
-       {
-               VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
-       }
-       ////////////////////////////////////////////////////////////
-
-       return MIN2(ret, 1);
-}
index 2ce00d0e38c28c4aca37ac500dca5a726e1be614..f61e2d22f1c1990097d90552ce8f04335a16e630 100644 (file)
@@ -49,6 +49,7 @@
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 #include "BLI_threads.h"
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 #include "BLI_threads.h"
+#include "BKE_collisions.h"
 #include "BKE_curve.h"
 #include "BKE_displist.h"
 #include "BKE_effect.h"
 #include "BKE_curve.h"
 #include "BKE_displist.h"
 #include "BKE_effect.h"
@@ -1585,3 +1586,841 @@ void implicit_set_positions (ClothModifierData *clmd)
                VECCOPY(id->V[i], verts[i].v);
        }       
 }
                VECCOPY(id->V[i], verts[i].v);
        }       
 }
+
+
+int collisions_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd)
+{
+       /*
+       unsigned int i = 0;
+       int result = 0;
+       LinkNode *search = NULL;
+       CollPair *collpair = NULL;
+       Cloth *cloth1, *cloth2;
+       float w1, w2, w3, u1, u2, u3;
+       float v1[3], v2[3], relativeVelocity[3];
+       float magrelVel;
+       
+       cloth1 = clmd->clothObject;
+       cloth2 = coll_clmd->clothObject;
+
+       // search = clmd->coll_parms.collision_list;
+       
+       while(search)
+       {
+       collpair = search->link;
+               
+               // compute barycentric coordinates for both collision points
+       collisions_compute_barycentric(collpair->pa,
+       cloth1->verts[collpair->ap1].txold,
+       cloth1->verts[collpair->ap2].txold,
+       cloth1->verts[collpair->ap3].txold, 
+       &w1, &w2, &w3);
+       
+       collisions_compute_barycentric(collpair->pb,
+       cloth2->verts[collpair->bp1].txold,
+       cloth2->verts[collpair->bp2].txold,
+       cloth2->verts[collpair->bp3].txold,
+       &u1, &u2, &u3);
+       
+               // Calculate relative "velocity".
+       interpolateOnTriangle(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3);
+               
+       interpolateOnTriangle(v2, cloth2->verts[collpair->bp1].tv, cloth2->verts[collpair->bp2].tv, cloth2->verts[collpair->bp3].tv, u1, u2, u3);
+               
+       VECSUB(relativeVelocity, v1, v2);
+                       
+               // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
+       magrelVel = INPR(relativeVelocity, collpair->normal);
+               
+               // printf("magrelVel: %f\n", magrelVel);
+                               
+               // Calculate masses of points.
+               
+               // If v_n_mag < 0 the edges are approaching each other.
+       if(magrelVel < -ALMOST_ZERO) 
+       {
+                       // Calculate Impulse magnitude to stop all motion in normal direction.
+                       // const double I_mag = v_n_mag / (1/m1 + 1/m2);
+       float magnitude_i = magrelVel / 2.0f; // TODO implement masses
+       float tangential[3], magtangent, magnormal, collvel[3];
+       float vrel_t_pre[3];
+       float vrel_t[3];
+       double impulse;
+       float epsilon = clmd->coll_parms.epsilon;
+       float overlap = (epsilon + ALMOST_ZERO-collpair->distance);
+                       
+                       // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel);
+                       
+                       // magtangent = INPR(tangential, tangential);
+                       
+                       // Apply friction impulse.
+       if (magtangent < -ALMOST_ZERO) 
+       {
+                               
+                               // printf("friction applied: %f\n", magtangent);
+                               // TODO check original code 
+}
+                       
+
+       impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
+                       
+                       // printf("impulse: %f\n", impulse);
+                       
+                       // face A
+       VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); 
+       cloth1->verts[collpair->ap1].impulse_count++;
+                       
+       VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse); 
+       cloth1->verts[collpair->ap2].impulse_count++;
+                       
+       VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); 
+       cloth1->verts[collpair->ap3].impulse_count++;
+                       
+                       // face B
+       VECADDMUL(cloth2->verts[collpair->bp1].impulse, collpair->normal, u1 * impulse); 
+       cloth2->verts[collpair->bp1].impulse_count++;
+                       
+       VECADDMUL(cloth2->verts[collpair->bp2].impulse, collpair->normal, u2 * impulse); 
+       cloth2->verts[collpair->bp2].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.
+       
+                       
+}
+               
+       search = search->next;
+}
+       
+       
+       return result;
+       */
+       return 0;
+}
+
+
+int collisions_collision_response_moving_tris(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, CollisionTree *tree1, CollisionTree *tree2)
+{
+       /*
+       CollPair *collpair = NULL;
+       Cloth *cloth1=NULL, *cloth2=NULL;
+       MFace *face1=NULL, *face2=NULL;
+       ClothVertex *verts1=NULL, *verts2=NULL;
+       double distance = 0;
+       float epsilon = clmd->coll_parms.epsilon;
+       unsigned int i = 0;
+
+       for(i = 0; i < 4; i++)
+       {
+       collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair");                
+               
+       cloth1 = clmd->clothObject;
+       cloth2 = coll_clmd->clothObject;
+               
+       verts1 = cloth1->verts;
+       verts2 = cloth2->verts;
+       
+       face1 = &(cloth1->mfaces[tree1->tri_index]);
+       face2 = &(cloth2->mfaces[tree2->tri_index]);
+               
+               // check all possible pairs of triangles
+       if(i == 0)
+       {
+       collpair->ap1 = face1->v1;
+       collpair->ap2 = face1->v2;
+       collpair->ap3 = face1->v3;
+                       
+       collpair->bp1 = face2->v1;
+       collpair->bp2 = face2->v2;
+       collpair->bp3 = face2->v3;
+                       
+}
+               
+       if(i == 1)
+       {
+       if(face1->v4)
+       {
+       collpair->ap1 = face1->v3;
+       collpair->ap2 = face1->v4;
+       collpair->ap3 = face1->v1;
+                               
+       collpair->bp1 = face2->v1;
+       collpair->bp2 = face2->v2;
+       collpair->bp3 = face2->v3;
+}
+       else
+       i++;
+}
+               
+       if(i == 2)
+       {
+       if(face2->v4)
+       {
+       collpair->ap1 = face1->v1;
+       collpair->ap2 = face1->v2;
+       collpair->ap3 = face1->v3;
+                               
+       collpair->bp1 = face2->v3;
+       collpair->bp2 = face2->v4;
+       collpair->bp3 = face2->v1;
+}
+       else
+       i+=2;
+}
+               
+       if(i == 3)
+       {
+       if((face1->v4)&&(face2->v4))
+       {
+       collpair->ap1 = face1->v3;
+       collpair->ap2 = face1->v4;
+       collpair->ap3 = face1->v1;
+                               
+       collpair->bp1 = face2->v3;
+       collpair->bp2 = face2->v4;
+       collpair->bp3 = face2->v1;
+}
+       else
+       i++;
+}
+               
+               // calc SIPcode (?)
+               
+       if(i < 4)
+       {
+                       // calc distance + normal       
+       distance = plNearestPoints(
+       verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, verts2[collpair->bp1].txold, verts2[collpair->bp2].txold, verts2[collpair->bp3].txold, collpair->pa,collpair->pb,collpair->vector);
+                       
+       if (distance <= (epsilon + ALMOST_ZERO))
+       {
+                               // printf("dist: %f\n", (float)distance);
+                               
+                               // collpair->face1 = tree1->tri_index;
+                               // collpair->face2 = tree2->tri_index;
+                               
+                               // VECCOPY(collpair->normal, collpair->vector);
+                               // Normalize(collpair->normal);
+                               
+                               // collpair->distance = distance;
+                               
+}
+       else
+       {
+       MEM_freeN(collpair);
+}
+}
+       else
+       {
+       MEM_freeN(collpair);
+}
+}
+       */
+}
+
+int collisions_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair)
+{
+       Cloth *cloth1, *cloth2;
+       ClothVertex *verts1, *verts2;
+       float temp[3];
+        
+       cloth1 = clmd->clothObject;
+       cloth2 = coll_clmd->clothObject;
+       
+       verts1 = cloth1->verts;
+       verts2 = cloth2->verts;
+       
+       VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].xold);
+       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
+               return 1;
+       
+       VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].xold);
+       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
+               return 1;
+       
+       VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].xold);
+       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
+               return 1;
+       
+       VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].xold);
+       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
+               return 1;
+               
+       return 0;
+}
+
+
+void collisions_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
+{
+       /*
+       EdgeCollPair edgecollpair;
+       Cloth *cloth1=NULL, *cloth2=NULL;
+       MFace *face1=NULL, *face2=NULL;
+       ClothVertex *verts1=NULL, *verts2=NULL;
+       double distance = 0;
+       float epsilon = clmd->coll_parms.epsilon;
+       unsigned int i = 0, j = 0, k = 0;
+       int numsolutions = 0;
+       float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
+       
+       cloth1 = clmd->clothObject;
+       cloth2 = coll_clmd->clothObject;
+       
+       verts1 = cloth1->verts;
+       verts2 = cloth2->verts;
+
+       face1 = &(cloth1->mfaces[tree1->tri_index]);
+       face2 = &(cloth2->mfaces[tree2->tri_index]);
+       
+       for( i = 0; i < 5; i++)
+       {
+       if(i == 0) 
+       {
+       edgecollpair.p11 = face1->v1;
+       edgecollpair.p12 = face1->v2;
+}
+       else if(i == 1) 
+       {
+       edgecollpair.p11 = face1->v2;
+       edgecollpair.p12 = face1->v3;
+}
+       else if(i == 2) 
+       {
+       if(face1->v4) 
+       {
+       edgecollpair.p11 = face1->v3;
+       edgecollpair.p12 = face1->v4;
+}
+       else 
+       {
+       edgecollpair.p11 = face1->v3;
+       edgecollpair.p12 = face1->v1;
+       i+=5; // get out of here after this edge pair is handled
+}
+}
+       else if(i == 3) 
+       {
+       if(face1->v4) 
+       {
+       edgecollpair.p11 = face1->v4;
+       edgecollpair.p12 = face1->v1;
+}      
+       else
+       continue;
+}
+       else
+       {
+       edgecollpair.p11 = face1->v3;
+       edgecollpair.p12 = face1->v1;
+}
+
+               
+       for( j = 0; j < 5; j++)
+       {
+       if(j == 0)
+       {
+       edgecollpair.p21 = face2->v1;
+       edgecollpair.p22 = face2->v2;
+}
+       else if(j == 1)
+       {
+       edgecollpair.p21 = face2->v2;
+       edgecollpair.p22 = face2->v3;
+}
+       else if(j == 2)
+       {
+       if(face2->v4) 
+       {
+       edgecollpair.p21 = face2->v3;
+       edgecollpair.p22 = face2->v4;
+}
+       else 
+       {
+       edgecollpair.p21 = face2->v3;
+       edgecollpair.p22 = face2->v1;
+}
+}
+       else if(j == 3)
+       {
+       if(face2->v4) 
+       {
+       edgecollpair.p21 = face2->v4;
+       edgecollpair.p22 = face2->v1;
+}
+       else
+       continue;
+}
+       else
+       {
+       edgecollpair.p21 = face2->v3;
+       edgecollpair.p22 = face2->v1;
+}
+                       
+                       
+       if(!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);
+       VECSUB(c, verts1[edgecollpair.p21].xold, verts1[edgecollpair.p11].xold);
+       VECSUB(d, verts1[edgecollpair.p21].v, verts1[edgecollpair.p11].v);
+       VECSUB(e, verts2[edgecollpair.p22].xold, verts1[edgecollpair.p11].xold);
+       VECSUB(f, verts2[edgecollpair.p22].v, verts1[edgecollpair.p11].v);
+                               
+       numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution);
+                               
+       for (k = 0; k < numsolutions; k++) 
+       {                                                               
+       if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) 
+       {
+       float out_collisionTime = solution[k];
+                                               
+                                               // TODO: check for collisions 
+                                               
+                                               // TODO: put into (edge) collision list
+                                               
+       printf("Moving edge found!\n");
+}
+}
+}
+}
+}      
+       */      
+}
+
+void collisions_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
+{
+       /*
+       CollPair collpair;
+       Cloth *cloth1=NULL, *cloth2=NULL;
+       MFace *face1=NULL, *face2=NULL;
+       ClothVertex *verts1=NULL, *verts2=NULL;
+       double distance = 0;
+       float epsilon = clmd->coll_parms.epsilon;
+       unsigned int i = 0, j = 0, k = 0;
+       int numsolutions = 0;
+       float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
+
+       for(i = 0; i < 2; i++)
+       {               
+       cloth1 = clmd->clothObject;
+       cloth2 = coll_clmd->clothObject;
+               
+       verts1 = cloth1->verts;
+       verts2 = cloth2->verts;
+       
+       face1 = &(cloth1->mfaces[tree1->tri_index]);
+       face2 = &(cloth2->mfaces[tree2->tri_index]);
+               
+               // check all possible pairs of triangles
+       if(i == 0)
+       {
+       collpair.ap1 = face1->v1;
+       collpair.ap2 = face1->v2;
+       collpair.ap3 = face1->v3;
+                       
+       collpair.pointsb[0] = face2->v1;
+       collpair.pointsb[1] = face2->v2;
+       collpair.pointsb[2] = face2->v3;
+       collpair.pointsb[3] = face2->v4;
+}
+               
+       if(i == 1)
+       {
+       if(face1->v4)
+       {
+       collpair.ap1 = face1->v3;
+       collpair.ap2 = face1->v4;
+       collpair.ap3 = face1->v1;
+                               
+       collpair.pointsb[0] = face2->v1;
+       collpair.pointsb[1] = face2->v2;
+       collpair.pointsb[2] = face2->v3;
+       collpair.pointsb[3] = face2->v4;
+}
+       else
+       i++;
+}
+               
+               // calc SIPcode (?)
+               
+       if(i < 2)
+       {
+       VECSUB(a, verts1[collpair.ap2].xold, verts1[collpair.ap1].xold);
+       VECSUB(b, verts1[collpair.ap2].v, verts1[collpair.ap1].v);
+       VECSUB(c, verts1[collpair.ap3].xold, verts1[collpair.ap1].xold);
+       VECSUB(d, verts1[collpair.ap3].v, verts1[collpair.ap1].v);
+                               
+       for(j = 0; j < 4; j++)
+       {                                       
+       if((j==3) && !(face2->v4))
+       break;
+                               
+       VECSUB(e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold);
+       VECSUB(f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v);
+                               
+       numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution);
+                               
+       for (k = 0; k < numsolutions; k++) 
+       {                                                               
+       if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) 
+       {
+       float out_collisionTime = solution[k];
+                                               
+                                               // TODO: check for collisions 
+                                               
+                                               // TODO: put into (point-face) collision list
+                                               
+       printf("Moving found!\n");
+                                               
+}
+}
+                               
+                               // TODO: check borders for collisions
+}
+                       
+}
+}
+       */
+}
+
+
+// move collision objects forward in time and update static bounding boxes
+void collisions_update_collision_objects(float step)
+{
+       Base *base=NULL;
+       ClothModifierData *coll_clmd=NULL;
+       Object *coll_ob=NULL;
+       unsigned int i=0;
+       
+       // search all objects for collision object
+       for (base = G.scene->base.first; base; base = base->next)
+       {
+
+               coll_ob = base->object;
+               coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
+               if (!coll_clmd)
+                       continue;
+
+               // if collision object go on
+               if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
+               {
+                       if (coll_clmd->clothObject && coll_clmd->clothObject->tree) 
+                       {
+                               Cloth *coll_cloth = coll_clmd->clothObject;
+                               BVH *coll_bvh = coll_clmd->clothObject->tree;
+                               unsigned int coll_numverts = coll_cloth->numverts;
+
+                               // update position of collision object
+                               for(i = 0; i < coll_numverts; i++)
+                               {
+                                       VECCOPY(coll_cloth->verts[i].txold, coll_cloth->verts[i].tx);
+
+                                       VECADDS(coll_cloth->verts[i].tx, coll_cloth->verts[i].xold, coll_cloth->verts[i].v, step);
+                                       
+                                       // no dt here because of float rounding errors
+                                       VECSUB(coll_cloth->verts[i].tv, coll_cloth->verts[i].tx, coll_cloth->verts[i].txold);
+                               }
+                               
+                               // update BVH of collision object
+                               // bvh_update(coll_clmd, coll_bvh, 0); // 0 means STATIC, 1 means MOVING 
+                       }
+                       else
+                               printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
+               }
+       }
+}
+
+
+void collisions_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
+{
+       /*
+       // TODO: check for adjacent
+       collisions_collision_moving_edges(clmd, coll_clmd, tree1, tree2);
+       
+       collisions_collision_moving_tris(clmd, coll_clmd, tree1, tree2);
+       collisions_collision_moving_tris(coll_clmd, clmd, tree2, tree1);
+       */
+}
+
+// cloth - object collisions
+int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
+{
+       /*
+       Base *base=NULL;
+       ClothModifierData *coll_clmd=NULL;
+       Cloth *cloth=NULL;
+       Object *coll_ob=NULL;
+       BVH *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))
+       {
+               return 0;
+       }
+       cloth = clmd->clothObject;
+       verts = cloth->verts;
+       collisions_bvh = (BVH *) cloth->tree;
+       numfaces = clmd->clothObject->numfaces;
+       numverts = clmd->clothObject->numverts;
+       
+       ////////////////////////////////////////////////////////////
+       // static collisions
+       ////////////////////////////////////////////////////////////
+
+       // update cloth bvh
+       // bvh_update(clmd, collisions_bvh, 0); // 0 means STATIC, 1 means MOVING (see later in this function)
+       
+       // update collision objects
+       collisions_update_collision_objects(step);
+       
+       do
+       {
+               result = 0;
+               ic = 0;
+               
+               // check all collision objects
+               for (base = G.scene->base.first; base; base = base->next)
+               {
+                       coll_ob = base->object;
+                       coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
+                       
+                       if (!coll_clmd)
+                               continue;
+                       
+                       // if collision object go on
+                       if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
+                       {
+                               if (coll_clmd->clothObject && coll_clmd->clothObject->tree) 
+                               {
+                                       BVH *coll_bvh = coll_clmd->clothObject->tree;
+                                       
+                                       // 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);
+                       
+                                               // 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(collision_list)
+                                       {
+                                               LinkNode *search = collision_list;
+                                               while(search)
+                                               {
+                                                       CollisionPair *coll_pair = search->link;
+                                                       
+                                                       MEM_freeN(coll_pair);
+                                                       search = search->next;
+                                               }
+                                               BLI_linklist_free(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++;
+       }
+       while(result && (10>rounds));// CLOTH_MAX_THRESHOLD
+       
+       printf("\n");
+                       
+       ////////////////////////////////////////////////////////////
+       // update positions
+       // this is needed for bvh_calc_DOP_hull_moving() [kdop.c]
+       ////////////////////////////////////////////////////////////
+       
+       // verts come from clmd
+       for(i = 0; i < numverts; i++)
+       {
+               VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
+       }
+       ////////////////////////////////////////////////////////////
+
+       ////////////////////////////////////////////////////////////
+       // moving collisions
+       ////////////////////////////////////////////////////////////
+
+       
+       // update cloth bvh
+       // bvh_update(clmd, 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)
+       {
+               
+               coll_ob = base->object;
+               coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
+               if (!coll_clmd)
+                       continue;
+               
+               if(!coll_clmd->clothObject)
+                       continue;
+               
+                               // if collision object go on
+               if (coll_clmd->clothObject && coll_clmd->clothObject->tree) 
+               {
+                       BVH *coll_bvh = coll_clmd->clothObject->tree;
+                       
+                       // bvh_update(coll_clmd, coll_bvh, 1);  // 0 means STATIC, 1 means MOVING       
+               }
+       }
+       
+       
+       do
+       {
+               result = 0;
+               ic = 0;
+               
+               // check all collision objects
+               for (base = G.scene->base.first; base; base = base->next)
+               {
+                       coll_ob = base->object;
+                       coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
+                       
+                       if (!coll_clmd)
+                               continue;
+                       
+                       // if collision object go on
+                       if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
+                       {
+                               if (coll_clmd->clothObject && coll_clmd->clothObject->tree) 
+                               {
+                                       BVH *coll_bvh = coll_clmd->clothObject->tree;
+                                       
+                                       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
+                                               
+                                               
+                                               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;
+                                                       
+                                                               ic++;
+                                                               ret++;
+                                                       }
+                                               }
+                                       }
+               
+               
+                                       // verts come from clmd
+                                       for(i = 0; i < numverts; i++)
+                                       {
+                                               VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
+                                       }
+               
+                                       // update cloth bvh
+                                       // bvh_update(clmd, collisions_bvh, 1);  // 0 means STATIC, 1 means MOVING 
+               
+               
+                                       // 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(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++;
+       }
+       while(result && (10>rounds)); // CLOTH_MAX_THRESHOLD
+       
+       
+       ////////////////////////////////////////////////////////////
+       // update positions + velocities
+       ////////////////////////////////////////////////////////////
+       
+       // verts come from clmd
+       for(i = 0; i < numverts; i++)
+       {
+               VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
+       }
+       ////////////////////////////////////////////////////////////
+
+       return MIN2(ret, 1);
+       */
+}
\ No newline at end of file
index 1e17ee4f03eb4915292ab5cb6a6d05ebf970c509..5ad08587266b60a94f4b75469c55ae014c5bb869 100644 (file)
@@ -164,9 +164,9 @@ static int size_threshold = 16;
 /*
 * Common methods for all algorithms
 */
 /*
 * Common methods for all algorithms
 */
-void bvh_exchange(Tree **a, int i, int j)
+void bvh_exchange(CollisionTree **a, int i, int j)
 {
 {
-       Tree *t=a[i];
+       CollisionTree *t=a[i];
        a[i]=a[j];
        a[j]=t;
 }
        a[i]=a[j];
        a[j]=t;
 }
@@ -178,10 +178,10 @@ int floor_lg(int a)
 /*
 * Insertion sort algorithm
 */
 /*
 * Insertion sort algorithm
 */
-static void bvh_insertionsort(Tree **a, int lo, int hi, int axis)
+static void bvh_insertionsort(CollisionTree **a, int lo, int hi, int axis)
 {
        int i,j;
 {
        int i,j;
-       Tree *t;
+       CollisionTree *t;
        for (i=lo; i < hi; i++)
        {
                j=i;
        for (i=lo; i < hi; i++)
        {
                j=i;
@@ -195,7 +195,7 @@ static void bvh_insertionsort(Tree **a, int lo, int hi, int axis)
        }
 }
 
        }
 }
 
-static int bvh_partition(Tree **a, int lo, int hi, Tree * x, int axis)
+static int bvh_partition(CollisionTree **a, int lo, int hi, CollisionTree *x, int axis)
 {
        int i=lo, j=hi;
        while (1)
 {
        int i=lo, j=hi;
        while (1)
@@ -213,9 +213,9 @@ static int bvh_partition(Tree **a, int lo, int hi, Tree * x, int axis)
 /*
 * Heapsort algorithm
 */
 /*
 * Heapsort algorithm
 */
-static void bvh_downheap(Tree **a, int i, int n, int lo, int axis)
+static void bvh_downheap(CollisionTree **a, int i, int n, int lo, int axis)
 {
 {
-       Tree * d = a[lo+i-1];
+       CollisionTree *d = a[lo+i-1];
        int child;
        while (i<=n/2)
        {
        int child;
        while (i<=n/2)
        {
@@ -231,7 +231,7 @@ static void bvh_downheap(Tree **a, int i, int n, int lo, int axis)
        a[lo+i-1] = d;
 }
 
        a[lo+i-1] = d;
 }
 
-static void bvh_heapsort(Tree **a, int lo, int hi, int axis)
+static void bvh_heapsort(CollisionTree **a, int lo, int hi, int axis)
 {
        int n = hi-lo, i;
        for (i=n/2; i>=1; i=i-1)
 {
        int n = hi-lo, i;
        for (i=n/2; i>=1; i=i-1)
@@ -245,7 +245,7 @@ static void bvh_heapsort(Tree **a, int lo, int hi, int axis)
        }
 }
 
        }
 }
 
-static Tree *bvh_medianof3(Tree **a, int lo, int mid, int hi, int axis) // returns Sortable
+static CollisionTree *bvh_medianof3(CollisionTree **a, int lo, int mid, int hi, int axis) // returns Sortable
 {
        if ((a[mid])->bv[axis] < (a[lo])->bv[axis])
        {
 {
        if ((a[mid])->bv[axis] < (a[lo])->bv[axis])
        {
@@ -275,7 +275,7 @@ static Tree *bvh_medianof3(Tree **a, int lo, int mid, int hi, int axis) // retur
 /*
 * Quicksort algorithm modified for Introsort
 */
 /*
 * Quicksort algorithm modified for Introsort
 */
-static void bvh_introsort_loop (Tree **a, int lo, int hi, int depth_limit, int axis)
+static void bvh_introsort_loop (CollisionTree **a, int lo, int hi, int depth_limit, int axis)
 {
        int p;
 
 {
        int p;
 
@@ -293,16 +293,16 @@ static void bvh_introsort_loop (Tree **a, int lo, int hi, int depth_limit, int a
        }
 }
 
        }
 }
 
-void bvh_sort(Tree **a0, int begin, int end, int axis)
+void bvh_sort(CollisionTree **a0, int begin, int end, int axis)
 {
        if (begin < end)
        {
 {
        if (begin < end)
        {
-               Tree **a=a0;
+               CollisionTree **a=a0;
                bvh_introsort_loop(a, begin, end, 2*floor_lg(end-begin), axis);
                bvh_insertionsort(a, begin, end, axis);
        }
 }
                bvh_introsort_loop(a, begin, end, 2*floor_lg(end-begin), axis);
                bvh_insertionsort(a, begin, end, axis);
        }
 }
-void bvh_sort_along_axis(Tree **face_list, int start, int end, int axis)
+void bvh_sort_along_axis(CollisionTree **face_list, int start, int end, int axis)
 {
        bvh_sort(face_list, start, end, axis);
 }
 {
        bvh_sort(face_list, start, end, axis);
 }
@@ -310,7 +310,7 @@ void bvh_sort_along_axis(Tree **face_list, int start, int end, int axis)
 void bvh_free(BVH * bvh)
 {
        LinkNode *search = NULL;
 void bvh_free(BVH * bvh)
 {
        LinkNode *search = NULL;
-       Tree *tree = NULL;
+       CollisionTree *tree = NULL;
 
        if (bvh) 
        {
 
        if (bvh) 
        {
@@ -361,7 +361,7 @@ int bvh_largest_axis(float *bv)
 }
 
 // depends on the fact that the BVH's for each face is already build
 }
 
 // depends on the fact that the BVH's for each face is already build
-void bvh_calc_DOP_hull_from_faces(BVH * bvh, Tree **tri, int numfaces, float *bv)
+void bvh_calc_DOP_hull_from_faces(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
 {
        float newmin,newmax;
        int i, j;
 {
        float newmin,newmax;
        int i, j;
@@ -385,32 +385,22 @@ void bvh_calc_DOP_hull_from_faces(BVH * bvh, Tree **tri, int numfaces, float *bv
        }
 }
 
        }
 }
 
-void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, float *bv)
+void bvh_calc_DOP_hull_static(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
 {
        MVert *tempMVert = bvh->x;
 {
        MVert *tempMVert = bvh->x;
-       MFace *tempMFace = bvh->mfaces;
        float *tempBV = bv;
        float newminmax;
        int i, j, k;
        for (j = 0; j < numfaces; j++)
        {
        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.
+               // 1 up to 4 vertices per leaf. 
                for (k = 0; k < 4; k++)
                {
                for (k = 0; k < 4; k++)
                {
-                       int temp = 0;  
-                       // If this is a triangle.
-                       if (k == 3 && !tempMFace->v4)
+                       int temp = tri[j]->point_index[k];
+                       
+                       if(temp < 0)
                                continue;
                                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++)
                        {                               
                        // for all Axes.
                        for (i = KDOP_START; i < KDOP_END; i++)
                        {                               
@@ -424,33 +414,23 @@ void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, float *bv)
        }
 }
 
        }
 }
 
-void bvh_calc_DOP_hull_moving(BVH * bvh, Tree **tri, int numfaces, float *bv)
+void bvh_calc_DOP_hull_moving(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
 {
        MVert *tempMVert = bvh->x;
        MVert *tempMVert2 = bvh->xnew;
 {
        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++)
        {
        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++)
                {
                // 3 or 4 vertices per face.
                for (k = 0; k < 4; k++)
                {
-                       int temp = 0;  
-                       // If this is a triangle.
-                       if (k == 3 && !tempMFace->v4)
+                       int temp = tri[j]->point_index[k];
+                       
+                       if(temp < 0)
                                continue;
                                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++)
                        {                               
                        // for all Axes.
                        for (i = KDOP_START; i < KDOP_END; i++)
                        {                               
@@ -470,10 +450,10 @@ void bvh_calc_DOP_hull_moving(BVH * bvh, Tree **tri, int numfaces, float *bv)
        }
 }
 
        }
 }
 
-static void bvh_div_env_node(BVH * bvh, TreeNode *tree, Tree **face_list, unsigned int start, unsigned int end, int lastaxis, LinkNode *nlink)
+static void bvh_div_env_node(BVH * bvh, TreeNode *tree, CollisionTree **face_list, unsigned int start, unsigned int end, int lastaxis, LinkNode *nlink)
 {
        int             i = 0;
 {
        int             i = 0;
-       Tree *newtree = NULL;
+       CollisionTree *newtree = NULL;
        int laxis = 0, max_nodes=4;
        unsigned int tstart, tend;
        LinkNode *nlink1 = nlink;
        int laxis = 0, max_nodes=4;
        unsigned int tstart, tend;
        LinkNode *nlink1 = nlink;
@@ -512,7 +492,7 @@ static void bvh_div_env_node(BVH * bvh, TreeNode *tree, Tree **face_list, unsign
                // Build tree until 4 node left.
                if ((tend-tstart + 1 ) > 1) 
                {
                // Build tree until 4 node left.
                if ((tend-tstart + 1 ) > 1) 
                {
-                       newtree = (Tree *)MEM_callocN(sizeof(Tree), "Tree");
+                       newtree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
                        tnlink = BLI_linklist_append_fast(&nlink1->next, newtree);
 
                        newtree->nodes[0] = newtree->nodes[1] = newtree->nodes[2] = newtree->nodes[3] = NULL;
                        tnlink = BLI_linklist_append_fast(&nlink1->next, newtree);
 
                        newtree->nodes[0] = newtree->nodes[1] = newtree->nodes[2] = newtree->nodes[3] = NULL;
@@ -530,7 +510,7 @@ static void bvh_div_env_node(BVH * bvh, TreeNode *tree, Tree **face_list, unsign
                }
                else // ok, we have 1 left for this node
                {
                }
                else // ok, we have 1 left for this node
                {
-                       Tree *tnode = face_list[tstart];
+                       CollisionTree *tnode = face_list[tstart];
                        tree->nodes[i] = tnode;
                        tree->nodes[i]->parent = tree;
                }
                        tree->nodes[i] = tnode;
                        tree->nodes[i]->parent = tree;
                }
@@ -538,19 +518,16 @@ static void bvh_div_env_node(BVH * bvh, TreeNode *tree, Tree **face_list, unsign
        return;
 }
 
        return;
 }
 
-BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xnew, unsigned int numverts, float epsilon)
+// mfaces is allowed to be null
+// just vertexes are used if mfaces=NULL
+BVH *bvh_build (MFace *mfaces, unsigned int numfaces, MVert *x, MVert *xnew, unsigned int numverts, float epsilon)
 {
 {
-       unsigned int i = 0, j = 0, k = 0;
-       Tree **face_list=NULL;
+       unsigned int i = 0, j = 0;
+       CollisionTree **face_list=NULL;
        BVH     *bvh=NULL;
        BVH     *bvh=NULL;
-       Tree *tree=NULL;
+       CollisionTree *tree=NULL;
        LinkNode *nlink = NULL;
        LinkNode *nlink = NULL;
-       EdgeHash *edgehash = NULL;
-       unsigned int numsprings = 0;
        MFace *mface = NULL;
        MFace *mface = NULL;
-
-       if(!dm)
-               return NULL;
        
        bvh = MEM_callocN(sizeof(BVH), "BVH");
        if (bvh == NULL) 
        
        bvh = MEM_callocN(sizeof(BVH), "BVH");
        if (bvh == NULL) 
@@ -565,13 +542,19 @@ BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xnew, unsigned int numverts, f
        bvh->tree = NULL;
 
        bvh->epsilon = epsilon;
        bvh->tree = NULL;
 
        bvh->epsilon = epsilon;
-       bvh->numfaces = dm->getNumFaces(dm);
-       mface = bvh->mfaces = dm->getFaceArray(dm);
+       bvh->numfaces = numfaces;
+       mface = bvh->mfaces = mfaces;
+       
+       // we have no faces, we save seperate points
+       if(!bvh->mfaces)
+       {
+               bvh->numfaces = numverts;
+       }
 
        bvh->numverts = numverts;
        bvh->xnew = xnew;       
        bvh->x = x;     
 
        bvh->numverts = numverts;
        bvh->xnew = xnew;       
        bvh->x = x;     
-       tree = (Tree *)MEM_callocN(sizeof(Tree), "Tree");
+       tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
        // TODO: check succesfull alloc
        BLI_linklist_append(&bvh->tree, tree);
 
        // TODO: check succesfull alloc
        BLI_linklist_append(&bvh->tree, tree);
 
@@ -590,7 +573,25 @@ BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xnew, unsigned int numverts, f
 
        if(bvh->numfaces<=1)
        {
 
        if(bvh->numfaces<=1)
        {
-               bvh->root->tri_index = 0;       // Why that? --> only one face there 
+               // 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->isleaf = 1;
                bvh->root->traversed = 0;
                bvh->root->count_nodes = 0;
                bvh->root->isleaf = 1;
                bvh->root->traversed = 0;
                bvh->root->count_nodes = 0;
@@ -602,7 +603,7 @@ BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xnew, unsigned int numverts, f
        else
        {       
                // create face boxes            
        else
        {       
                // create face boxes            
-               face_list = MEM_callocN (bvh->numfaces * sizeof (Tree *), "Tree");
+               face_list = MEM_callocN (bvh->numfaces * sizeof (CollisionTree *), "CollisionTree");
                if (face_list == NULL) 
                {
                        printf("bvh_build: Out of memory for face_list.\n");
                if (face_list == NULL) 
                {
                        printf("bvh_build: Out of memory for face_list.\n");
@@ -611,17 +612,35 @@ BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xnew, unsigned int numverts, f
                }
 
                // create face boxes
                }
 
                // create face boxes
-               for(i = 0, k = 0; i < bvh->numfaces; i++)
+               for(i = 0; i < bvh->numfaces; i++)
                {
                        LinkNode *tnlink = NULL;
                        
                {
                        LinkNode *tnlink = NULL;
                        
-                       tree = (Tree *)MEM_callocN(sizeof(Tree), "Tree");
+                       tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
                        // TODO: check succesfull alloc
 
                        tnlink = BLI_linklist_append_fast(&nlink->next, tree);
 
                        face_list[i] = tree;
                        // TODO: check succesfull alloc
 
                        tnlink = BLI_linklist_append_fast(&nlink->next, tree);
 
                        face_list[i] = tree;
-                       tree->tri_index = i;
+                       
+                       if(bvh->mfaces)
+                       {
+                               bvh->root->point_index[0] = mfaces[i].v1; 
+                               bvh->root->point_index[1] = mfaces[i].v2;
+                               bvh->root->point_index[2] = mfaces[i].v3;
+                               if(mfaces[i].v4)
+                                       bvh->root->point_index[3] = mfaces[i].v4;
+                               else
+                                       bvh->root->point_index[3] = -1;
+                       }
+                       else
+                       {
+                               bvh->root->point_index[0] = i; 
+                               bvh->root->point_index[1] = -1;
+                               bvh->root->point_index[2] = -1;
+                               bvh->root->point_index[3] = -1;
+                       }
+                       
                        tree->isleaf = 1;
                        tree->nextLeaf = NULL;
                        tree->prevLeaf = bvh->leaf_tree;
                        tree->isleaf = 1;
                        tree->nextLeaf = NULL;
                        tree->prevLeaf = bvh->leaf_tree;
@@ -694,7 +713,7 @@ int bvh_overlap(float *bv1, float *bv2)
  * every other triangle that doesn't require any realloc, but uses
  * much memory
  */
  * every other triangle that doesn't require any realloc, but uses
  * much memory
  */
-int bvh_traverse(Tree * tree1, Tree * tree2, LinkNode *collision_list)
+int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision_list)
 {
        int i = 0, ret = 0;
                
 {
        int i = 0, ret = 0;
                
@@ -709,8 +728,11 @@ int bvh_traverse(Tree * tree1, Tree * tree2, LinkNode *collision_list)
                                // save potential colliding triangles
                                CollisionPair *collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair");
                                
                                // save potential colliding triangles
                                CollisionPair *collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair");
                                
-                               collpair->indexA = tree1->tri_index;
-                               collpair->indexB = tree2->tri_index;
+                               VECCOPY(collpair->point_indexA, tree1->point_index);
+                               collpair->point_indexA[3] = tree1->point_index[3];
+                               
+                               VECCOPY(collpair->point_indexB, tree2->point_index);
+                               collpair->point_indexB[3] = tree2->point_index[3];
                                
                                BLI_linklist_append(&collision_list, collpair);
                                
                                
                                BLI_linklist_append(&collision_list, collpair);
                                
@@ -744,7 +766,7 @@ int bvh_traverse(Tree * tree1, Tree * tree2, LinkNode *collision_list)
 
 // bottom up update of bvh tree:
 // join the 4 children here
 
 // bottom up update of bvh tree:
 // join the 4 children here
-void bvh_join(Tree * tree)
+void bvh_join(CollisionTree *tree)
 {
        int     i = 0, j = 0;
        if (!tree)
 {
        int     i = 0, j = 0;
        if (!tree)
@@ -775,17 +797,12 @@ void bvh_join(Tree * tree)
 
 // update static bvh
 // needs new positions in bvh->x, bvh->xnew
 
 // update static bvh
 // needs new positions in bvh->x, bvh->xnew
-void bvh_update(DerivedMesh *dm, BVH * bvh, int moving)
+void bvh_update(BVH * bvh, int moving)
 {
        TreeNode *leaf, *parent;
        int traversecheck = 1;  // if this is zero we don't go further 
        unsigned int j = 0;
        
 {
        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;
        for (leaf = bvh->leaf_root; leaf; leaf = leaf->nextLeaf)
        {
                traversecheck = 1;
index cb7fccd11c125d3485b548c3036ee62dae71e4d8..42faf2b2c3f1138d312ab8676512e821aed450b5 100644 (file)
@@ -4866,7 +4866,7 @@ static void clothModifier_initData(ModifierData *md)
        ClothModifierData *clmd = (ClothModifierData*) md;
        cloth_init (clmd);
 }
        ClothModifierData *clmd = (ClothModifierData*) md;
        cloth_init (clmd);
 }
-
+/*
 static void clothModifier_deformVerts(
                ModifierData *md, Object *ob, DerivedMesh *derivedData,
                float (*vertexCos)[3], int numVerts)
 static void clothModifier_deformVerts(
                ModifierData *md, Object *ob, DerivedMesh *derivedData,
                float (*vertexCos)[3], int numVerts)
@@ -4889,6 +4889,22 @@ static void clothModifier_deformVerts(
        if(dm)
                dm->release(dm);
 }
        if(dm)
                dm->release(dm);
 }
+*/
+
+static DerivedMesh *clothModifier_applyModifier(
+               ModifierData *md, Object *ob, DerivedMesh *derivedData,
+  int useRenderParams, int isFinalCalc)
+{
+       DerivedMesh *result = NULL;
+       
+       ClothModifierData *clmd = (ClothModifierData*) md;
+
+       result = clothModifier_do(clmd, ob, derivedData);
+
+       CDDM_calc_normals(result);
+
+       return derivedData;
+}
 
 static void clothModifier_updateDepgraph(
                 ModifierData *md, DagForest *forest, Object *ob,
 
 static void clothModifier_updateDepgraph(
                 ModifierData *md, DagForest *forest, Object *ob,
@@ -4957,6 +4973,8 @@ static void collisionModifier_initData(ModifierData *md)
        
        collmd->x = NULL;
        collmd->xnew = NULL;
        
        collmd->x = NULL;
        collmd->xnew = NULL;
+       collmd->current_x = NULL;
+       collmd->current_xnew = NULL;
        collmd->time = -1;
        collmd->numverts = 0;
        collmd->tree = NULL;
        collmd->time = -1;
        collmd->numverts = 0;
        collmd->tree = NULL;
@@ -4974,22 +4992,32 @@ static void collisionModifier_freeData(ModifierData *md)
                        MEM_freeN(collmd->x);
                if(collmd->xnew)
                        MEM_freeN(collmd->xnew);
                        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);
                
                collmd->x = NULL;
                collmd->xnew = NULL;
                
                collmd->x = NULL;
                collmd->xnew = NULL;
+               collmd->current_x = NULL;
+               collmd->current_xnew = NULL;
                collmd->time = -1;
                collmd->numverts = 0;
                collmd->tree = 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;
 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;
        float current_time = 0;
        unsigned int numverts = 0, i = 0;
        MVert *tempVert = NULL;
@@ -4999,6 +5027,12 @@ static void collisionModifier_deformVerts(
        if(derivedData) dm = CDDM_copy(derivedData);
        else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
        
        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);
        if(dm)
        {
                CDDM_apply_vert_coords(dm, vertexCos);
@@ -5013,17 +5047,26 @@ static void collisionModifier_deformVerts(
                        
                        // check if mesh has changed
                        if(collmd->x && (numverts != collmd->numverts))
                        
                        // check if mesh has changed
                        if(collmd->x && (numverts != collmd->numverts))
-                               collisionModifier_freeData(collmd);
+                               collisionModifier_freeData((ModifierData *)collmd);
                        
                        if(collmd->time == -1) // first time
                        {
                        
                        if(collmd->time == -1) // first time
                        {
-                               collmd->x = dm->dupVertArray(dm);
-                               collmd->xnew = dm->dupVertArray(dm);
+                               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->numverts = numverts;
                                
                                // TODO: epsilon
                                // create bounding box hierarchy
                                collmd->numverts = numverts;
                                
                                // TODO: epsilon
                                // create bounding box hierarchy
-                               collmd->tree = bvh_build(dm, collmd->x, collmd->xnew,  numverts, 0.01);
+                               collmd->tree = bvh_build(dm->getFaceArray(dm), dm->getNumFaces(dm), collmd->current_x, collmd->current_xnew,  numverts, ob->pd->pdef_sbift);
                        }
                        else if(numverts == collmd->numverts)
                        {
                        }
                        else if(numverts == collmd->numverts)
                        {
@@ -5040,7 +5083,10 @@ static void collisionModifier_deformVerts(
                                        Mat4MulVecfl ( ob->obmat, collmd->xnew[i].co );
                                }
                                
                                        Mat4MulVecfl ( ob->obmat, collmd->xnew[i].co );
                                }
                                
-                               bvh_update(dm, collmd->tree, 0); // recalc static bounding boxes
+                               memcpy(collmd->current_xnew, dm->getVertArray(dm), numverts*sizeof(MVert));
+                               memcpy(collmd->current_x, dm->getVertArray(dm), numverts*sizeof(MVert));
+                               
+                               bvh_update(collmd->tree, 0); // recalc static bounding boxes
                        }
                        
                        collmd->time = current_time;
                        }
                        
                        collmd->time = current_time;
@@ -5051,11 +5097,6 @@ static void collisionModifier_deformVerts(
                dm->release(dm);
 }
 
                dm->release(dm);
 }
 
-static int collisionModifier_dependsOnTime(ModifierData *md)
-{
-       return 1;
-}
-
 /* Boolean */
 
 static void booleanModifier_copyData(ModifierData *md, ModifierData *target)
 /* Boolean */
 
 static void booleanModifier_copyData(ModifierData *md, ModifierData *target)
@@ -5342,10 +5383,10 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->deformVerts = softbodyModifier_deformVerts;
        
                mti = INIT_TYPE(Cloth);
                mti->deformVerts = softbodyModifier_deformVerts;
        
                mti = INIT_TYPE(Cloth);
-               mti->type = eModifierTypeType_OnlyDeform;
+               mti->type = eModifierTypeType_Nonconstructive;
                mti->initData = clothModifier_initData;
                mti->initData = clothModifier_initData;
-               mti->flags = eModifierTypeFlag_AcceptsCVs;
-                                       // | eModifierTypeFlag_RequiresOriginalData;
+               mti->flags = eModifierTypeFlag_AcceptsMesh
+                               | eModifierTypeFlag_RequiresOriginalData;
                                        // | eModifierTypeFlag_SupportsMapping
                                        // | eModifierTypeFlag_SupportsEditmode 
                                        // | eModifierTypeFlag_EnableInEditmode;
                                        // | eModifierTypeFlag_SupportsMapping
                                        // | eModifierTypeFlag_SupportsEditmode 
                                        // | eModifierTypeFlag_EnableInEditmode;
@@ -5353,7 +5394,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->freeData = clothModifier_freeData; 
                mti->requiredDataMask = clothModifier_requiredDataMask;
                // mti->copyData = clothModifier_copyData;
                mti->freeData = clothModifier_freeData; 
                mti->requiredDataMask = clothModifier_requiredDataMask;
                // mti->copyData = clothModifier_copyData;
-               mti->deformVerts = clothModifier_deformVerts;
+               // mti->deformVerts = clothModifier_deformVerts;
+               mti->applyModifier = clothModifier_applyModifier;
                mti->updateDepgraph = clothModifier_updateDepgraph;
                
                mti = INIT_TYPE(Collision);
                mti->updateDepgraph = clothModifier_updateDepgraph;
                
                mti = INIT_TYPE(Collision);
@@ -5567,11 +5609,11 @@ int modifiers_isSoftbodyEnabled(Object *ob)
        return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
 }
 
        return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
 }
 
-ModifierData *modifiers_isClothEnabled(Object *ob)
+ClothModifierData *modifiers_isClothEnabled(Object *ob)
 {
 {
-       ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth);
+       ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
 
 
-       return md;
+       return clmd;
 }
 
 LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask)
 }
 
 LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask)
index 99f0885b43541aa6effecf83fdcc953e7238c323..56f1c817a50f0646db1043fd02f9fa67d7b04c0f 100644 (file)
@@ -2893,6 +2893,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                        
                        collmd->x = NULL;
                        collmd->xnew = NULL;
                        
                        collmd->x = NULL;
                        collmd->xnew = NULL;
+                       collmd->current_x = NULL;
+                       collmd->current_xnew = NULL;
                        collmd->time = -1;
                        collmd->numverts = 0;
                        collmd->tree = NULL;
                        collmd->time = -1;
                        collmd->numverts = 0;
                        collmd->tree = NULL;
@@ -3009,7 +3011,6 @@ static void direct_link_object(FileData *fd, Object *ob)
                sb->bpoint= NULL;       // init pointers so it gets rebuilt nicely
                sb->bspring= NULL;
                sb->scratch= NULL;
                sb->bpoint= NULL;       // init pointers so it gets rebuilt nicely
                sb->bspring= NULL;
                sb->scratch= NULL;
-
                
                sb->keys= newdataadr(fd, sb->keys);
                test_pointer_array(fd, (void **)&sb->keys);
                
                sb->keys= newdataadr(fd, sb->keys);
                test_pointer_array(fd, (void **)&sb->keys);
index 27f7431a9cff2cd76ae11ac141b93023ab50b99f..b4592e4d7245d109bd6db6451db1e3bac9dc7d94 100644 (file)
@@ -156,9 +156,13 @@ typedef struct Cloth
        unsigned char           old_solver_type;
        unsigned char           pad2;
        short                   pad3;
        unsigned char           old_solver_type;
        unsigned char           pad2;
        short                   pad3;
-       void                    *tree;                  /* collision tree for this cloth object */
+       struct CollisionTree    *tree;          /* collision tree for this cloth object */
        struct MFace            *mfaces;
        struct MFace            *mfaces;
-       void                    *implicit;              /* our implicit solver connects to this pointer */
+       struct Implicit_Data    *implicit;      /* our implicit solver connects to this pointer */
+       struct MVert            *x;
+       struct MVert            *xnew;
+       struct MVert            *current_x;
+       struct MVert            *current_xnew;
 }
 Cloth;
 
 }
 Cloth;
 
index 81e27afbac4463beaacfa52c1dd197fc5566abb1..b25c3e7992187412fa6e708bb53c7cf4efd5474a 100644 (file)
@@ -350,12 +350,14 @@ typedef struct ClothModifierData {
 typedef struct CollisionModifierData {
        ModifierData            modifier;
        
 typedef struct CollisionModifierData {
        ModifierData            modifier;
        
-       struct MVert *x;
-       struct MVert *xnew;
+       struct MVert *x; /* position at the beginning of the frame */
+       struct MVert *xnew; /* position at the end of the frame */
+       struct MVert *current_xnew; /* new position at the actual inter-frame step */
+       struct MVert *current_x; /* position at the actual inter-frame step */
        
        unsigned int numverts;
        float time;
        
        unsigned int numverts;
        float time;
-       void *tree;     /* collision tree for this cloth object */
+       struct BVH *tree;       /* collision tree for this cloth object */
 } CollisionModifierData;
 
 typedef enum {
 } CollisionModifierData;
 
 typedef enum {
index a821e209ef0c3870031325d98a78cda9a66bab93..062989d07548d8d1fe54e87eef9ce791d35d9766 100644 (file)
@@ -113,7 +113,6 @@ typedef struct SoftBody {
                ;   
 
        struct SBScratch *scratch;      /* scratch pad/cache on live time not saved in file */
                ;   
 
        struct SBScratch *scratch;      /* scratch pad/cache on live time not saved in file */
-
 } SoftBody;
 
 /* pd->forcefield:  Effector Fields types */
 } SoftBody;
 
 /* pd->forcefield:  Effector Fields types */
index 8f35e64b79fe4d2107993f1916cc80a92974dcf0..a68338e132ba50e06c810ec52a894c458ac497df 100644 (file)
@@ -99,6 +99,7 @@
 #include "BKE_customdata.h"
 #include "BKE_blender.h"
 #include "BKE_booleanops.h"
 #include "BKE_customdata.h"
 #include "BKE_blender.h"
 #include "BKE_booleanops.h"
+#include "BKE_cloth.h"
 #include "BKE_curve.h"
 #include "BKE_displist.h"
 #include "BKE_depsgraph.h"
 #include "BKE_curve.h"
 #include "BKE_displist.h"
 #include "BKE_depsgraph.h"