[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