[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15407] trunk/blender/source/blender/ blenkernel: Cloth collisions: Reorganized collision system to be more flexible for other parts of blender , so it can be more easily reused.
Daniel Genrich
daniel.genrich at gmx.net
Wed Jul 2 22:29:56 CEST 2008
Revision: 15407
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15407
Author: genscher
Date: 2008-07-02 22:28:49 +0200 (Wed, 02 Jul 2008)
Log Message:
-----------
Cloth collisions: Reorganized collision system to be more flexible for other parts of blender, so it can be more easily reused. Also slowed down friction impulse.
Modified Paths:
--------------
trunk/blender/source/blender/blenkernel/BKE_cloth.h
trunk/blender/source/blender/blenkernel/intern/cloth.c
trunk/blender/source/blender/blenkernel/intern/collision.c
trunk/blender/source/blender/blenkernel/intern/implicit.c
Modified: trunk/blender/source/blender/blenkernel/BKE_cloth.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_cloth.h 2008-07-02 19:48:01 UTC (rev 15406)
+++ trunk/blender/source/blender/blenkernel/BKE_cloth.h 2008-07-02 20:28:49 UTC (rev 15407)
@@ -208,7 +208,7 @@
////////////////////////////////////////////////
// needed for implicit.c
-int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt );
+int cloth_bvh_objcollision ( Object *ob, ClothModifierData * clmd, float step, float dt );
////////////////////////////////////////////////
Modified: trunk/blender/source/blender/blenkernel/intern/cloth.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/cloth.c 2008-07-02 19:48:01 UTC (rev 15406)
+++ trunk/blender/source/blender/blenkernel/intern/cloth.c 2008-07-02 20:28:49 UTC (rev 15407)
@@ -132,7 +132,7 @@
clmd->coll_parms->self_friction = 5.0;
clmd->coll_parms->friction = 5.0;
- clmd->coll_parms->loop_count = 3;
+ clmd->coll_parms->loop_count = 2;
clmd->coll_parms->epsilon = 0.015f;
clmd->coll_parms->flags = CLOTH_COLLSETTINGS_FLAG_ENABLED;
clmd->coll_parms->collision_list = NULL;
@@ -471,7 +471,7 @@
tend();
- /* printf ( "Cloth simulation time: %f\n", ( float ) tval() ); */
+ // printf ( "%f\n", ( float ) tval() );
return ret;
}
Modified: trunk/blender/source/blender/blenkernel/intern/collision.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/collision.c 2008-07-02 19:48:01 UTC (rev 15406)
+++ trunk/blender/source/blender/blenkernel/intern/collision.c 2008-07-02 20:28:49 UTC (rev 15407)
@@ -541,7 +541,7 @@
{
Normalize ( vrel_t_pre );
- impulse = 2.0 * magtangent / ( 1.0 + w1*w1 + w2*w2 + w3*w3 );
+ impulse = magtangent / ( 1.0 + w1*w1 + w2*w2 + w3*w3 ); // 2.0 *
VECADDMUL ( cloth1->verts[collpair->ap1].impulse, vrel_t_pre, w1 * impulse );
VECADDMUL ( cloth1->verts[collpair->ap2].impulse, vrel_t_pre, w2 * impulse );
VECADDMUL ( cloth1->verts[collpair->ap3].impulse, vrel_t_pre, w3 * impulse );
@@ -1291,52 +1291,223 @@
return 1;
}
-int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData *collmd, float step, float dt )
-{
+int cloth_do_selfcollisions(ClothModifierData * clmd)
+{
+ int ret2 = 0, l;
Cloth *cloth = clmd->clothObject;
- BVHTree *cloth_bvh= ( BVHTree * ) cloth->bvhtree;
- long i=0, j = 0, numfaces = 0, numverts = 0;
- ClothVertex *verts = NULL;
- CollPair *collisions = NULL, *collisions_index = NULL;
- int ret = 0;
- int result = 0;
- float tnull[3] = {0,0,0};
- BVHTreeOverlap *overlap = NULL;
+
+ if ( clmd->clothObject->bvhselftree )
+ {
+ for(l = 0; l < clmd->coll_parms->self_loop_count; l++)
+ {
+ BVHTreeOverlap *overlap = NULL;
+ ClothVertex *verts = clmd->clothObject->verts; // needed for openMP
+ int k;
+ int ret = 0, result = 0;
+
+ // search for overlapping collision pairs
+ overlap = BLI_bvhtree_overlap ( cloth->bvhselftree, cloth->bvhselftree, &result );
+
+// #pragma omp parallel for private(k, i, j) schedule(static)
+ for ( k = 0; k < result; k++ )
+ {
+ float temp[3];
+ float length = 0;
+ float mindistance;
+ int i, j;
+
+ i = overlap[k].indexA;
+ j = overlap[k].indexB;
+
+ mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len );
+
+ if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
+ {
+ if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
+ && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) )
+ {
+ continue;
+ }
+ }
+
+ VECSUB ( temp, verts[i].tx, verts[j].tx );
+
+ if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue;
+
+ // check for adjacent points (i must be smaller j)
+ if ( BLI_edgehash_haskey ( cloth->edgehash, MIN2(i, j), MAX2(i, j) ) )
+ {
+ continue;
+ }
+
+ length = Normalize ( temp );
+
+ if ( length < mindistance )
+ {
+ float correction = mindistance - length;
+
+ if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
+ {
+ VecMulf ( temp, -correction );
+ VECADD ( verts[j].tx, verts[j].tx, temp );
+ }
+ else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED )
+ {
+ VecMulf ( temp, correction );
+ VECADD ( verts[i].tx, verts[i].tx, temp );
+ }
+ else
+ {
+ VecMulf ( temp, -correction*0.5 );
+ VECADD ( verts[j].tx, verts[j].tx, temp );
+
+ VECSUB ( verts[i].tx, verts[i].tx, temp );
+ }
+ ret = 1;
+ ret2 += ret;
+ }
+ else
+ {
+ // check for approximated time collisions
+ }
+ }
+
+ if ( overlap )
+ MEM_freeN ( overlap );
+
+ if(!ret)
+ break;
+
+ }
+ ////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////
+ // SELFCOLLISIONS: update velocities
+ ////////////////////////////////////////////////////////////
+ if ( ret2 )
+ {
+ int i;
+ ClothVertex *verts = clmd->clothObject->verts; // needed for openMP
+
+ for ( i = 0; i < cloth->numverts; i++ )
+ {
+ if ( ! ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) )
+ {
+ VECSUB ( verts[i].tv, verts[i].tx, verts[i].txold );
+ }
+ }
+ }
+ ////////////////////////////////////////////////////////////
+ }
+ return ret2;
+}
+// return all collision objects in scene
+// collision object will exclude self
+CollisionModifierData **get_collisionobjects(Object *self, int *numcollobj)
+{
+ Base *base=NULL;
+ CollisionModifierData **objs = NULL;
+ Object *coll_ob = NULL;
+ CollisionModifierData *collmd = NULL;
+ int numobj = 0, maxobj = 100;
+
+ objs = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
+ // check all collision objects
+ for ( base = G.scene->base.first; base; base = base->next )
+ {
+ coll_ob = base->object;
+ collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
+
+ if ( !collmd )
+ {
+ if ( coll_ob->dup_group )
+ {
+ GroupObject *go;
+ Group *group = coll_ob->dup_group;
- numfaces = clmd->clothObject->numfaces;
- numverts = clmd->clothObject->numverts;
+ for ( go= group->gobject.first; go; go= go->next )
+ {
+ coll_ob = go->ob;
- verts = cloth->verts;
+ collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
- if ( collmd->bvhtree )
- {
- /* get pointer to bounding volume hierarchy */
- BVHTree *coll_bvh = collmd->bvhtree;
+ if ( !collmd )
+ continue;
- /* move object to position (step) in time */
- collision_move_object ( collmd, step + dt, step );
+ if(coll_ob == self)
+ continue;
- /* search for overlapping collision pairs */
- overlap = BLI_bvhtree_overlap ( cloth_bvh, coll_bvh, &result );
+ if(numobj >= maxobj)
+ {
+ // realloc
+ int oldmax = maxobj;
+ CollisionModifierData **tmp;
+ maxobj *= 2;
+ tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
+ memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax);
+ MEM_freeN(objs);
+ objs = tmp;
+ }
+
+ objs[numobj] = collmd;
+ numobj++;
+ }
+ }
+ }
+ else
+ {
+ if(coll_ob == self)
+ continue;
+
+ if(numobj >= maxobj)
+ {
+ // realloc
+ int oldmax = maxobj;
+ CollisionModifierData **tmp;
+ maxobj *= 2;
+ tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
+ memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax);
+ MEM_freeN(objs);
+ objs = tmp;
+
+ }
+
+ objs[numobj] = collmd;
+ numobj++;
+ }
+ }
+ *numcollobj = numobj;
+ return objs;
+}
- collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * result*4, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision
- collisions_index = collisions;
+void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap)
+{
+ int i;
+
+ *collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * numresult * 4, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision
+ *collisions_index = *collisions;
- for ( i = 0; i < result; i++ )
- {
- collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, overlap+i, collisions_index );
- }
-
- if ( overlap )
- MEM_freeN ( overlap );
- }
- else
+ for ( i = 0; i < numresult; i++ )
{
- if ( G.rt > 0 )
- printf ( "cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n" );
+ *collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, overlap+i, *collisions_index );
}
+}
+int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair *collisions, CollPair *collisions_index)
+{
+ Cloth *cloth = clmd->clothObject;
+ int i=0, j = 0, numfaces = 0, numverts = 0;
+ ClothVertex *verts = NULL;
+ int ret = 0;
+ int result = 0;
+ float tnull[3] = {0,0,0};
+
+ numfaces = clmd->clothObject->numfaces;
+ numverts = clmd->clothObject->numverts;
+
+ verts = cloth->verts;
+
// process all collisions (calculate impulses, TODO: also repulses if distance too short)
result = 1;
for ( j = 0; j < 5; j++ ) // 5 is just a value that ensures convergence
@@ -1363,48 +1534,22 @@
}
}
}
-/*
- result += cloth_collision_moving ( clmd, collmd, collisions, collisions_index );
-
- // apply impulses in parallel
- if ( result )
- {
- 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;
-
- ret++;
- }
- }
- }
-*/
}
}
-
- if ( collisions ) MEM_freeN ( collisions );
-
return ret;
}
// cloth - object collisions
-int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt )
+int cloth_bvh_objcollision ( Object *ob, ClothModifierData * clmd, float step, float dt )
{
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list