[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [13900] trunk/blender/source/blender: Cloth: 1.

Daniel Genrich daniel.genrich at gmx.net
Thu Feb 28 01:01:19 CET 2008


Revision: 13900
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=13900
Author:   genscher
Date:     2008-02-28 01:01:19 +0100 (Thu, 28 Feb 2008)

Log Message:
-----------
Cloth: 1. Bugfix for possible memory leak reported by Kenneth Styrberg (via mailing list), 2. Bugfix for friction again, 3. Preset menu on GUI (thanks to help from nudelZ (#blendercoders), 4. Possibility to disable autoprotect cache, 5. Some cache bugs fixed, 6. Some speedup in generating cloth

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
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/makesdna/DNA_cloth_types.h
    trunk/blender/source/blender/src/buttons_object.c
    trunk/blender/source/blender/src/editmesh.c

Modified: trunk/blender/source/blender/blenkernel/BKE_cloth.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_cloth.h	2008-02-27 23:11:04 UTC (rev 13899)
+++ trunk/blender/source/blender/blenkernel/BKE_cloth.h	2008-02-28 00:01:19 UTC (rev 13900)
@@ -148,6 +148,7 @@
 	CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE = ( 1 << 7 ), /* force cache freeing */
 	CLOTH_SIMSETTINGS_FLAG_SCALING = ( 1 << 8 ), /* is advanced scaling active? */
 	CLOTH_SIMSETTINGS_FLAG_LOADED = ( 1 << 9 ), /* did we just got load? */
+	CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT = ( 1 << 10 ), /* is autoprotect enabled? */
 } CLOTH_SIMSETTINGS_FLAGS;
 
 /* COLLISION FLAGS */

Modified: trunk/blender/source/blender/blenkernel/intern/cloth.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/cloth.c	2008-02-27 23:11:04 UTC (rev 13899)
+++ trunk/blender/source/blender/blenkernel/intern/cloth.c	2008-02-28 00:01:19 UTC (rev 13900)
@@ -152,7 +152,7 @@
 	clmd->sim_parms->mass = 1.0f;
 	clmd->sim_parms->stepsPerFrame = 5;
 	clmd->sim_parms->sim_time = 1.0;
-	clmd->sim_parms->flags = 0;
+	clmd->sim_parms->flags = CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT;
 	clmd->sim_parms->solver_type = 0;
 	clmd->sim_parms->preroll = 0;
 	clmd->sim_parms->maxspringlen = 10;
@@ -164,6 +164,7 @@
 	clmd->sim_parms->autoprotect = 25;
 	clmd->sim_parms->firstcachedframe = -1.0;
 	clmd->sim_parms->avg_spring_len = 0.0;
+	clmd->sim_parms->presets = 2; /* cotton as start setting */
 	
 	clmd->coll_parms->self_friction = 5.0;
 	clmd->coll_parms->friction = 5.0;
@@ -232,7 +233,6 @@
 	bvh->numverts = cloth->numverts;
 	
 	bvh->current_x = MEM_callocN ( sizeof ( MVert ) * bvh->numverts, "bvh->current_x" );
-	bvh->current_xold = MEM_callocN ( sizeof ( MVert ) * bvh->numverts, "bvh->current_xold" );
 	
 	if (bvh->current_x == NULL) 
 	{
@@ -241,9 +241,12 @@
 		return NULL;
 	}
 	
+	bvh->current_xold = MEM_callocN ( sizeof ( MVert ) * bvh->numverts, "bvh->current_xold" );
+	
 	if (bvh->current_xold == NULL) 
 	{
 		printf("bvh: Out of memory.\n");
+		MEM_freeN(bvh->current_x);
 		MEM_freeN(bvh);
 		return NULL;
 	}
@@ -574,6 +577,10 @@
 		cloth_free_modifier (ob, clmd);
 		if(G.rt > 0)
 			printf("clothModifier_do CLOTH_SIMSETTINGS_FLAG_RESET\n");
+		
+		// prevent rebuilding of cloth each time you move backward 
+		if(deltaTime < 0.0)
+			return result;
 	}
 	
 	// unused in the moment, calculated seperately in implicit.c
@@ -656,20 +663,22 @@
 	}
 	
 	// check for autoprotection, but only if cache active
-	if((framenr >= clmd->sim_parms->autoprotect) && (G.relbase_valid))
+	if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT)
 	{
-		if(G.rt > 0)
-			printf("fr#: %f, auto: %d\n", framenr, clmd->sim_parms->autoprotect);
-		clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT;
+		if((framenr >= clmd->sim_parms->autoprotect) && (G.relbase_valid))
+		{
+			if(G.rt > 0)
+				printf("fr#: %f, auto: %d\n", framenr, clmd->sim_parms->autoprotect);
+			
+			clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT;
+		}
 	}
-	if(G.rt > 0)
-		printf("clothModifier_do deltaTime=1 cachewrite\n");
 	
 	/* nice moving one frame forward */
 	if ( deltaTime == 1.0f )
 	{
 		clmd->sim_parms->sim_time = current_time;
-		
+			
 		if(G.rt > 0)
 			printf("clothModifier_do deltaTime=1\n");
 		
@@ -718,7 +727,7 @@
 	else if(deltaTime == 0.0f) 
 	{	
 		if(G.rt > 0)
-			printf("clothModifier_do deltaTime!=1 clmd->clothObject != NULL\n");
+			printf("dt = 0, %f\n", framenr);
 		if(cloth_read_cache(ob, clmd, framenr))
 		{
 			cloth_to_object (ob, clmd, result);
@@ -726,30 +735,35 @@
 		}
 		else /* same cache parts are missing */
 		{
-			/*
-			clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
-			*/
-			clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
-			cloth_clear_cache(ob, clmd, 0);
-			
-			cloth_write_cache(ob, clmd, framenr);
+			/* jump to a non-existing frame makes sim reset if cache is not protected */
+			if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
+			{	
+				/*
+				clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
+				*/
+				clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
+				cloth_clear_cache(ob, clmd, 0);
+				
+				cloth_write_cache(ob, clmd, framenr);
+			}
 		}
 	}
 	else
 	{	
 		if(G.rt > 0)
-			printf("clothModifier_do deltaTime!=1 clmd->clothObject != NULL\n");
+			printf("dt > 1.0 || dt < 0.0, %f\n", framenr);
 		if(cloth_read_cache(ob, clmd, framenr))
 		{
 			cloth_to_object (ob, clmd, result);
 			implicit_set_positions(clmd);
-			clmd->sim_parms->sim_time = current_time;
 		}
 		else
 		{
-			/* jump to a non-existing frame makes sim reset */
-			clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
+			/* jump to a non-existing frame makes sim reset if cache is not protected */
+			if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
+				clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
 		}
+		clmd->sim_parms->sim_time = current_time;
 	}
 	
 	return result;

Modified: trunk/blender/source/blender/blenkernel/intern/collision.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/collision.c	2008-02-27 23:11:04 UTC (rev 13899)
+++ trunk/blender/source/blender/blenkernel/intern/collision.c	2008-02-28 00:01:19 UTC (rev 13900)
@@ -478,7 +478,7 @@
 		
 		interpolateOnTriangle(v2, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, u1, u2, u3);
 		
-		VECSUB(relativeVelocity, v1, v2);
+		VECSUB(relativeVelocity, v2, v1);
 			
 		// Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
 		magrelVel = INPR(relativeVelocity, collpair->normal);
@@ -489,10 +489,10 @@
 		// TODO
 		
 		// If v_n_mag < 0 the edges are approaching each other.
-		if(magrelVel < -ALMOST_ZERO) 
+		if(magrelVel > ALMOST_ZERO) 
 		{
 			// Calculate Impulse magnitude to stop all motion in normal direction.
-			float magtangent;
+			float magtangent = 0, repulse = 0, d = 0;
 			double impulse = 0.0;
 			float vrel_t_pre[3];
 			float temp[3];
@@ -502,21 +502,25 @@
 			VecMulf(temp, magrelVel);
 			VECSUB(vrel_t_pre, relativeVelocity, temp);
 			
-			magtangent = INPR(vrel_t_pre,vrel_t_pre) - MIN2(clmd->coll_parms->friction * 0.01 * magrelVel,INPR(vrel_t_pre,vrel_t_pre));
+			// Decrease in magnitude of relative tangential velocity due to coulomb friction
+			// in original formula "magrelVel" should be the "change of relative velocity in normal direction" 
+			magtangent = MIN2(clmd->coll_parms->friction * 0.01 * magrelVel,sqrt(INPR(vrel_t_pre,vrel_t_pre)));
 			
 			// Apply friction impulse.
 			if (magtangent > ALMOST_ZERO) 
 			{	
 				Normalize(vrel_t_pre);
-
-				impulse = -2.0 * magtangent / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
+				
+				impulse = 2.0 * magtangent / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
 				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);
 			}
 			
-
-			impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
+			// Apply velocity stopping impulse
+			// I_c = m * v_N / 2.0
+			// no 2.0 * magrelVel normally, but looks nicer DG
+			impulse =  2.0 * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3); 
 			
 			VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); 
 			cloth1->verts[collpair->ap1].impulse_count++;
@@ -527,6 +531,22 @@
 			VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); 
 			cloth1->verts[collpair->ap3].impulse_count++;
 			
+			/*
+			// doesn't perform nice, dunno why DG
+			// Apply repulse impulse if distance too short
+			// I_r = -min(dt*kd, m(0,1d/dt - v_n))
+			d = clmd->coll_parms->epsilon - collpair->distance;
+			if((magrelVel < 0.1*d*clmd->sim_parms->stepsPerFrame) && (d > ALMOST_ZERO))
+			{
+				repulse = MIN2(d*5.0/clmd->sim_parms->stepsPerFrame, 0.1*d*clmd->sim_parms->stepsPerFrame - magrelVel);
+				
+				impulse = 0.25 * repulse / ( 1.0 + w1*w1 + w2*w2 + w3*w3); // original 2.0 / 0.25
+				VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse);
+				VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse);
+				VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse);
+			}
+			*/
+			
 			result = 1;
 		}
 		
@@ -1023,7 +1043,10 @@
 				bvh_traverse((ModifierData *)clmd, (ModifierData *)collmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_static, 0);
 			}
 			else
+			{
+				if(G.rt > 0)
 				printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
+			}
 		
 		
 			// process all collisions (calculate impulses, TODO: also repulses if distance too short)

Modified: trunk/blender/source/blender/blenkernel/intern/implicit.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/implicit.c	2008-02-27 23:11:04 UTC (rev 13899)
+++ trunk/blender/source/blender/blenkernel/intern/implicit.c	2008-02-28 00:01:19 UTC (rev 13900)
@@ -878,7 +878,7 @@
 	float tempfb = kb * fb(length, L);
 
 	float fbstar = cb * (length - L);
-
+	
 	if(tempfb < fbstar)
 		return fbstar;
 	else

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2008-02-27 23:11:04 UTC (rev 13899)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2008-02-28 00:01:19 UTC (rev 13900)
@@ -3037,6 +3037,9 @@
 			clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_LOADED;
 			clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE;
 			
+			if(clmd->sim_parms->presets > 10)
+				clmd->sim_parms->presets = 0;
+			
 		}
 		else if (md->type==eModifierType_Collision) {
 			

Modified: trunk/blender/source/blender/makesdna/DNA_cloth_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_cloth_types.h	2008-02-27 23:11:04 UTC (rev 13899)
+++ trunk/blender/source/blender/makesdna/DNA_cloth_types.h	2008-02-28 00:01:19 UTC (rev 13900)
@@ -83,6 +83,9 @@

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list