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

Daniel Genrich daniel.genrich at gmx.net
Tue May 15 13:14:50 CEST 2012


Revision: 46654
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=46654
Author:   genscher
Date:     2012-05-15 11:14:50 +0000 (Tue, 15 May 2012)
Log Message:
-----------
Cloth:
- Triangulate Cloth Mesh for collisions
- Speed up collisions
- Remove EL Topo code
- Prepare code to incooperate El Topo self collisions (TODO next commits)


TODO:
----------
- Triangulation: Is custom data/uv preserved correctly?
- Use MPoly not tessface?

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/modifiers/intern/MOD_cloth.c

Modified: trunk/blender/source/blender/blenkernel/BKE_cloth.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_cloth.h	2012-05-15 10:55:26 UTC (rev 46653)
+++ trunk/blender/source/blender/blenkernel/BKE_cloth.h	2012-05-15 11:14:50 UTC (rev 46654)
@@ -211,7 +211,7 @@
 void cloth_free_modifier_extern (struct ClothModifierData *clmd );
 void cloth_free_modifier (struct ClothModifierData *clmd );
 void cloth_init (struct ClothModifierData *clmd );
-void clothModifier_do (struct ClothModifierData *clmd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3]);
+struct DerivedMesh *clothModifier_do (struct ClothModifierData *clmd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm);
 
 int cloth_uses_vgroup(struct ClothModifierData *clmd);
 

Modified: trunk/blender/source/blender/blenkernel/intern/cloth.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/cloth.c	2012-05-15 10:55:26 UTC (rev 46653)
+++ trunk/blender/source/blender/blenkernel/intern/cloth.c	2012-05-15 11:14:50 UTC (rev 46654)
@@ -93,7 +93,7 @@
 /* ********** cloth engine ******* */
 /* Prototypes for internal functions.
 */
-static void cloth_to_object (Object *ob,  ClothModifierData *clmd, float (*vertexCos)[3]);
+static void cloth_to_object (Object *ob,  ClothModifierData *clmd, DerivedMesh *dm);
 static void cloth_from_mesh ( ClothModifierData *clmd, DerivedMesh *dm );
 static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr, int first);
 static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm );
@@ -419,16 +419,71 @@
 	return ret;
 }
 
+
+static DerivedMesh *cloth_to_triangles(DerivedMesh *dm)
+{
+	DerivedMesh *result = NULL;
+	unsigned int i = 0, j = 0;
+	unsigned int quads = 0, numfaces = dm->getNumTessFaces(dm);
+	MFace *mface = dm->getTessFaceArray(dm);
+	MFace *mface2 = NULL;
+
+	/* calc faces */
+	for(i = 0; i < numfaces; i++)
+	{
+		if(mface[i].v4)
+			quads++;
+	}
+		
+	result = CDDM_from_template(dm, dm->getNumVerts(dm), 0, numfaces + quads, 0, 0);
+
+	DM_copy_vert_data(dm, result, 0, 0, dm->getNumVerts(dm));
+	DM_copy_tessface_data(dm, result, 0, 0, numfaces);
+
+	DM_ensure_tessface(result);
+	mface2 = result->getTessFaceArray(result);
+
+	for(i = 0, j = numfaces; i < numfaces; i++)
+	{
+		// DG TODO: is this necessary?
+		mface2[i].v1 = mface[i].v1;
+		mface2[i].v2 = mface[i].v2;
+		mface2[i].v3 = mface[i].v3;
+
+		mface2[i].v4 = 0;
+		//test_index_face(&mface2[i], &result->faceData, i, 3);
+
+		if(mface[i].v4)
+		{
+			DM_copy_tessface_data(dm, result, i, j, 1);
+
+			mface2[j].v1 = mface[i].v1;
+			mface2[j].v2 = mface[i].v3;
+			mface2[j].v3 = mface[i].v4;
+			mface2[j].v4 = 0;
+			//test_index_face(&mface2[j], &result->faceData, j, 3);
+
+			j++;
+		}
+	}
+
+	CDDM_calc_edges_tessface(result);
+	CDDM_tessfaces_to_faces(result); /* builds ngon faces from tess (mface) faces */
+
+	return result;
+}
+
 /************************************************
  * clothModifier_do - main simulation function
 ************************************************/
-void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3])
+DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, DerivedMesh *dm)
 {
 	PointCache *cache;
 	PTCacheID pid;
 	float timescale;
 	int framenr, startframe, endframe;
 	int cache_result;
+	DerivedMesh *result = NULL;
 
 	clmd->scene= scene;	/* nice to pass on later :) */
 	framenr= (int)scene->r.cfra;
@@ -448,7 +503,7 @@
 		BKE_ptcache_validate(cache, 0);
 		cache->last_exact= 0;
 		cache->flag &= ~PTCACHE_REDO_NEEDED;
-		return;
+		return NULL;
 	}
 	
 	// unused in the moment, calculated separately in implicit.c
@@ -460,20 +515,21 @@
 
 		/* do simulation */
 		if (!do_init_cloth(ob, clmd, dm, framenr))
-			return;
+			return NULL;
 
 		do_step_cloth(ob, clmd, dm, framenr);
-		cloth_to_object(ob, clmd, vertexCos);
+		result = cloth_to_triangles(dm);
+		cloth_to_object(ob, clmd, result);
 
 		clmd->clothObject->last_frame= framenr;
 
-		return;
+		return result;
 	}
 
 	/* simulation is only active during a specific period */
 	if (framenr < startframe) {
 		BKE_ptcache_invalidate(cache);
-		return;
+		return NULL;
 	}
 	else if (framenr > endframe) {
 		framenr= endframe;
@@ -481,7 +537,7 @@
 
 	/* initialize simulation data if it didn't exist already */
 	if (!do_init_cloth(ob, clmd, dm, framenr))
-		return;
+		return NULL;
 
 	if ((framenr == startframe) && (clmd->sim_parms->preroll == 0)) {
 		BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
@@ -489,7 +545,7 @@
 		BKE_ptcache_validate(cache, framenr);
 		cache->flag &= ~PTCACHE_REDO_NEEDED;
 		clmd->clothObject->last_frame= framenr;
-		return;
+		return NULL;
 	}
 
 	/* try to read from cache */
@@ -497,7 +553,8 @@
 
 	if (cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) {
 		implicit_set_positions(clmd);
-		cloth_to_object (ob, clmd, vertexCos);
+		result = cloth_to_triangles(dm);
+		cloth_to_object (ob, clmd, result);
 
 		BKE_ptcache_validate(cache, framenr);
 
@@ -506,7 +563,7 @@
 
 		clmd->clothObject->last_frame= framenr;
 
-		return;
+		return result;
 	}
 	else if (cache_result==PTCACHE_READ_OLD) {
 		implicit_set_positions(clmd);
@@ -514,11 +571,11 @@
 	else if ( /*ob->id.lib ||*/ (cache->flag & PTCACHE_BAKED)) { /* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */
 		/* if baked and nothing in cache, do nothing */
 		BKE_ptcache_invalidate(cache);
-		return;
+		return NULL;
 	}
 
 	if (framenr!=clmd->clothObject->last_frame+1)
-		return;
+		return NULL;
 
 	/* if on second frame, write cache for first frame */
 	if (cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
@@ -535,8 +592,11 @@
 	else
 		BKE_ptcache_write(&pid, framenr);
 
-	cloth_to_object (ob, clmd, vertexCos);
+	result = cloth_to_triangles(dm);
+	cloth_to_object (ob, clmd, result);
 	clmd->clothObject->last_frame= framenr;
+
+	return result;
 }
 
 /* frees all */
@@ -683,18 +743,19 @@
  * cloth_to_object - copies the deformed vertices to the object.
  *
  **/
-static void cloth_to_object (Object *ob,  ClothModifierData *clmd, float (*vertexCos)[3])
+static void cloth_to_object (Object *ob,  ClothModifierData *clmd, DerivedMesh *dm)
 {
 	unsigned int	i = 0;
 	Cloth *cloth = clmd->clothObject;
+	MVert *verts = dm->getVertArray(dm);
 
 	if (clmd->clothObject) {
 		/* inverse matrix is not uptodate... */
 		invert_m4_m4(ob->imat, ob->obmat);
 
 		for (i = 0; i < cloth->numverts; i++) {
-			copy_v3_v3 (vertexCos[i], cloth->verts[i].x);
-			mul_m4_v3(ob->imat, vertexCos[i]);	/* cloth is in global coords */
+			copy_v3_v3 (verts[i].co, cloth->verts[i].x);
+			mul_m4_v3(ob->imat, verts[i].co);	/* cloth is in global coords */
 		}
 	}
 }

Modified: trunk/blender/source/blender/blenkernel/intern/collision.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/collision.c	2012-05-15 10:55:26 UTC (rev 46653)
+++ trunk/blender/source/blender/blenkernel/intern/collision.c	2012-05-15 11:14:50 UTC (rev 46654)
@@ -161,286 +161,9 @@
 /***********************************
 Collision modifier code end
 ***********************************/
-
-/**
-* gsl_poly_solve_cubic -
-*
-* copied from SOLVE_CUBIC.C --> GSL
-*/
-
 #define mySWAP(a, b) do { double tmp = b ; b = a ; a = tmp ; } while (0)
-#if 0 /* UNUSED */
-static int 
-gsl_poly_solve_cubic (double a, double b, double c, 
-					  double *x0, double *x1, double *x2)
-{
-	double q = (a * a - 3 * b);
-	double r = (2 * a * a * a - 9 * a * b + 27 * c);
 
-	double Q = q / 9;
-	double R = r / 54;
 
-	double Q3 = Q * Q * Q;
-	double R2 = R * R;
-
-	double CR2 = 729 * r * r;
-	double CQ3 = 2916 * q * q * q;
-
-	if (R == 0 && Q == 0)
-	{
-		*x0 = - a / 3;
-		*x1 = - a / 3;
-		*x2 = - a / 3;
-		return 3;
-	}
-	else if (CR2 == CQ3) 
-	{
-		/* this test is actually R2 == Q3, written in a form suitable
-		for exact computation with integers */
-
-		/* Due to finite precision some double roots may be missed, and
-		considered to be a pair of complex roots z = x +/- epsilon i
-		close to the real axis. */
-
-		double sqrtQ = sqrt (Q);
-
-		if (R > 0)
-		{
-			*x0 = -2 * sqrtQ  - a / 3;
-			*x1 = sqrtQ - a / 3;
-			*x2 = sqrtQ - a / 3;
-		}
-		else
-		{
-			*x0 = - sqrtQ  - a / 3;
-			*x1 = - sqrtQ - a / 3;
-			*x2 = 2 * sqrtQ - a / 3;
-		}
-		return 3;
-	}
-	else if (CR2 < CQ3) /* equivalent to R2 < Q3 */
-	{
-		double sqrtQ = sqrt (Q);
-		double sqrtQ3 = sqrtQ * sqrtQ * sqrtQ;
-		double theta = acos (R / sqrtQ3);
-		double norm = -2 * sqrtQ;
-		*x0 = norm * cos (theta / 3) - a / 3;
-		*x1 = norm * cos ((theta + 2.0 * M_PI) / 3) - a / 3;
-		*x2 = norm * cos ((theta - 2.0 * M_PI) / 3) - a / 3;
-
-		/* Sort *x0, *x1, *x2 into increasing order */
-
-		if (*x0 > *x1)
-			mySWAP(*x0, *x1);
-
-		if (*x1 > *x2)
-		{
-			mySWAP(*x1, *x2);
-
-			if (*x0 > *x1)
-				mySWAP(*x0, *x1);
-		}
-
-		return 3;
-	}
-	else
-	{
-		double sgnR = (R >= 0 ? 1 : -1);
-		double A = -sgnR * pow (fabs (R) + sqrt (R2 - Q3), 1.0/3.0);
-		double B = Q / A;
-		*x0 = A + B - a / 3;
-		return 1;
-	}
-}
-
-
-
-/**
-* gsl_poly_solve_quadratic
-*
-* copied from GSL
-*/
-static int 
-gsl_poly_solve_quadratic (double a, double b, double c, 
-						  double *x0, double *x1)
-{
-	double disc = b * b - 4 * a * c;
-
-	if (a == 0) /* Handle linear case */
-	{
-		if (b == 0)
-		{
-			return 0;
-		}
-		else
-		{
-			*x0 = -c / b;
-			return 1;
-		};
-	}
-
-	if (disc > 0)
-	{
-		if (b == 0)
-		{
-			double r = fabs (0.5 * sqrt (disc) / a);
-			*x0 = -r;
-			*x1 =  r;
-		}
-		else
-		{
-			double sgnb = (b > 0 ? 1 : -1);
-			double temp = -0.5 * (b + sgnb * sqrt (disc));
-			double r1 = temp / a;
-			double r2 = c / temp;
-
-			if (r1 < r2) 
-			{
-				*x0 = r1;
-				*x1 = r2;
-			} 
-			else 
-			{
-				*x0 = r2;
-				*x1 = r1;
-			}
-		}
-		return 2;
-	}
-	else if (disc == 0) 
-	{
-		*x0 = -0.5 * b / a;
-		*x1 = -0.5 * b / a;
-		return 2;
-	}
-	else
-	{
-		return 0;
-	}
-}
-#endif /* UNUSED */
-
-
-
-/*
-* See Bridson et al. "Robust Treatment of Collision, Contact and Friction for Cloth Animation"
-*     page 4, left column
-*/
-#if 0
-static int cloth_get_collision_time ( double a[3], double b[3], double c[3], double d[3], double e[3], double f[3], double solution[3] )
-{
-	int num_sols = 0;
-
-	// x^0 - checked 
-	double g = 	a[0] * c[1] * e[2] - a[0] * c[2] * e[1] +

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list