[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [29148] branches/hairsim: Ok.

Joseph Eagar joeedh at gmail.com
Wed Jun 2 04:55:32 CEST 2010


Revision: 29148
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=29148
Author:   joeedh
Date:     2010-06-02 04:55:32 +0200 (Wed, 02 Jun 2010)

Log Message:
-----------
Ok.  This branch is now fairly functional,
though it may not be totally obvious how to
tweak the settings.

A few notes:
* The collider friction, if not 0, turns out a method to
  help the solver converge better (and faster).
* Collisions with faces (and their edges) work, though this
  isn't quite perfect yet (still need to have it properly
  damp the tangental velocity for friction, instead of simply
  cancelling out the normal force in the rather simplistic way
  it does now).
* Don't a large quality value, use 2-6, and use a 20-40 collision
  quality value (this is important).
* Spring dampening actually works here, it can help a lot.
* So does bending stiffness.
* Pin stiffness works too, though it's impossible for it to always
  be completely correct it does work fairly well.  Remember it multiplies
  with the weights of the hair strand vertices (editable in particle hair
  edit mode).

Modified Paths:
--------------
    branches/hairsim/release/scripts/ui/properties_particle.py
    branches/hairsim/source/blender/blenkernel/intern/cloth.c
    branches/hairsim/source/blender/blenkernel/intern/collision.c
    branches/hairsim/source/blender/blenkernel/intern/derivatives.cpp
    branches/hairsim/source/blender/blenkernel/intern/implicit.c
    branches/hairsim/source/blender/blenkernel/intern/particle.c
    branches/hairsim/source/blender/blenkernel/intern/particle_system.c
    branches/hairsim/source/blender/blenlib/BLI_math_geom.h
    branches/hairsim/source/blender/blenlib/BLI_math_vector.h
    branches/hairsim/source/blender/blenlib/intern/math_geom.c
    branches/hairsim/source/blender/blenlib/intern/math_vector.c
    branches/hairsim/source/blender/blenlib/intern/math_vector_inline.c
    branches/hairsim/source/blender/editors/interface/interface_draw.c
    branches/hairsim/source/blender/editors/space_view3d/drawobject.c
    branches/hairsim/source/blender/makesdna/DNA_cloth_types.h
    branches/hairsim/source/blender/makesrna/intern/rna_cloth.c
    branches/hairsim/source/blender/render/intern/source/pipeline.c

Added Paths:
-----------
    branches/hairsim/source/blender/blenlib/intern/predicates.c

Modified: branches/hairsim/release/scripts/ui/properties_particle.py
===================================================================
--- branches/hairsim/release/scripts/ui/properties_particle.py	2010-06-02 02:26:53 UTC (rev 29147)
+++ branches/hairsim/release/scripts/ui/properties_particle.py	2010-06-02 02:55:32 UTC (rev 29148)
@@ -256,9 +256,6 @@
         sub.prop(cloth, "mass")
         sub.prop(cloth, "structural_stiffness", text="Structural")
         sub.prop(cloth, "bending_stiffness", text="Bending")
-        sub.prop(cloth, "internal_friction", slider=True)
-        sub.prop(cloth, "collider_friction", slider=True)
-        sub.prop(cloth, "flexibility_damping", text="Flexibility", slider=True)
 
         col = split.column()
 
@@ -266,11 +263,18 @@
         sub = col.column(align=True)
         sub.prop(cloth, "spring_damping", text="Spring")
         sub.prop(cloth, "air_damping", text="Air")
+        sub.prop(cloth, "flexibility_damping", text="Flexibility", slider=True)
 
+        col.label(text="Velocity Control")
+        sub = col.column(align=True)
+        sub.prop(cloth, "internal_friction", slider=True)
+        sub.prop(cloth, "collider_friction", slider=True)
+        sub.prop(cloth, "grid_size", slider=True, text="Grid Size")
+        sub.prop(cloth, "filter_size", slider=True, text="Filter Size")
+
         col.label(text="Quality:")
         col.prop(cloth, "quality", text="Steps", slider=True)
-
-
+  
 class PARTICLE_PT_cache(ParticleButtonsPanel):
     bl_label = "Cache"
     bl_default_closed = True

Modified: branches/hairsim/source/blender/blenkernel/intern/cloth.c
===================================================================
--- branches/hairsim/source/blender/blenkernel/intern/cloth.c	2010-06-02 02:26:53 UTC (rev 29147)
+++ branches/hairsim/source/blender/blenkernel/intern/cloth.c	2010-06-02 02:55:32 UTC (rev 29148)
@@ -267,7 +267,7 @@
 			continue;
 
 		if (!bvhspringtree)
-			bvhspringtree = BLI_bvhtree_new(cloth->numsprings*4, MAX2(epsilon, 0.01), 4, 26);
+			bvhspringtree = BLI_bvhtree_new(cloth->numsprings*4, MAX2(epsilon*2.0, 0.01), 4, 26);
 
 		VECCOPY(co[0], v1->txold);
 		VECCOPY(co[1], v1->tx);

Modified: branches/hairsim/source/blender/blenkernel/intern/collision.c
===================================================================
--- branches/hairsim/source/blender/blenkernel/intern/collision.c	2010-06-02 02:26:53 UTC (rev 29147)
+++ branches/hairsim/source/blender/blenkernel/intern/collision.c	2010-06-02 02:55:32 UTC (rev 29148)
@@ -64,8 +64,10 @@
 #define CON_GOAL	4
 #define CON_BEND	5
 
-#define SIGN(n) ((n) < DBL_EPSILON)
+#define EDGE_SCALE	1.01
 
+#define SIGN(n) ((n) < 0.0)
+
 /*n=number, g=initial guess - (n/g + g)*0.5*/
 #define GUESS(s, g)\
 g = s*0.5;\
@@ -113,6 +115,23 @@
 	}
 }
 
+static void scale_line_v3_d(double v1[3], double v2[3], double scale)
+{
+	double c[3];
+
+	add_v3_v3v3_d(c, v1, v2);
+	mul_v3_d(c, 0.5);
+	
+	sub_v3_v3_d(v1, c);
+	sub_v3_v3_d(v2, c);
+	
+	mul_v3_d(v1, scale);
+	mul_v3_d(v2, scale);
+
+	add_v3_v3_d(v1, c);
+	add_v3_v3_d(v2, c);
+}
+
 static int tri_hash_comp(void *a, void *b);
 
 /*"point-based dynamics" by mueller*/
@@ -212,21 +231,30 @@
 	ClothVertex *v1, *v2, *v3, *v4;
 	
 	cdouble_t off[3];
+	cdouble_t sign, elen1, elen2;
 } EdgeConstraint;
 
 double solve_tetra_gradient(double ip1[3], double ip2[3], double ip3[3], double ip4[3],
-                                      double grad1[3], double grad2[3], double grad3[3], double grad4[3]);
+                            double grad1[3], double grad2[3], double grad3[3], 
+							double grad4[3], double elen1, double elen2);
 
 static void eval_edge_constraint(void *vself) {
 	EdgeConstraint *self = vself;
 	ClothVertex *v1=self->v1, *v2=self->v2, *v3=self->v3, *v4=self->v4;
-	cdouble_t g1[3], g2[3], g3[3], g4[3], ov1[3], ov2[3];
+	cdouble_t g1[3], g2[3], g3[3], g4[3], offv1[3], offv2[3], l1[3], l2[3];
 	
-	add_v3_v3v3_d(ov1, v3->tx, self->off);
-	add_v3_v3v3_d(ov2, v4->tx, self->off);
+	copy_v3_v3_d(l1, v1->tx);
+	copy_v3_v3_d(l2, v2->tx);
 
-	self->coll.head.result = solve_tetra_gradient(v1->tx, v2->tx, ov1, ov2, g1, g2, g3, g4);
+	scale_line_v3_d(l1, l2, EDGE_SCALE);
 
+	add_v3_v3v3_d(offv1, v3->tx, self->off);
+	add_v3_v3v3_d(offv2, v4->tx, self->off);
+
+	scale_line_v3_d(offv1, offv2, EDGE_SCALE);
+
+	self->coll.head.result = solve_tetra_gradient(l1, l2, offv1, offv2, g1, g2, g3, g4, self->elen1, self->elen2);
+
 	if (isnan(g1[0]) || isnan(g2[0]) || isnan(g3[0]) || isnan(g4[0]))
 		self->coll.head.result = 0.0;
 
@@ -238,7 +266,7 @@
 
 static EdgeConstraint *make_edge_constraint(ClothVertex *v1, ClothVertex *v2, ClothVertex *v3,
 											ClothVertex *v4,  cdouble_t mindis, cdouble_t no[3],
-											MemArena *arena, cdouble_t friction)
+											MemArena *arena, cdouble_t friction, cdouble_t sign)
 {
 	EdgeConstraint *con = BLI_memarena_alloc(arena, sizeof(*con));
 	
@@ -249,6 +277,12 @@
 	con->v3 = v3;
 	con->v4 = v4;
 
+	con->sign = sign;
+	con->elen1 = len_v3v3_d(v1->tx, v2->tx);
+	con->elen2 = len_v3v3_d(v3->tx, v4->tx);
+
+	mindis *= 1.01;
+
 	copy_v3_v3_d(con->off, no);
 	copy_v3_v3_d(con->coll.no, no);
 	mul_v3_d(con->off, mindis);
@@ -354,7 +388,7 @@
 
 	con->coll.head.type = CON_POINT;
 	con->coll.head.k = 1.0;
-	con->coll.mindis = mindis;
+	con->coll.mindis = mindis+0.002;
 	con->coll.friction = friction;
 
 	con->coll.head.eval = eval_point_constraint;
@@ -701,6 +735,7 @@
 			tri->verts[i] = cv;
 			VECCOPY(cv->tx, collmd->current_xnew[cv->hash].co);
 			VECCOPY(cv->txold, collmd->current_x[cv->hash].co);
+			VECCOPY(cv->txold2, collmd->current_x[cv->hash].co);
 			VECCOPY(cv->tv, collmd->current_v[cv->hash].co);
 			cv->mass = 1000000.0; /*supposed to represent infinite mass*/
 
@@ -729,7 +764,7 @@
 		{
 			VECSUB ( tv, collmd->x[i].co, collmd->xold[i].co );
 			VECADDS( collmd->current_x[i].co, collmd->xold[i].co, tv, 1.0+prevstep );
-			VECCOPY( collmd->current_xnew[i].co, collmd->x[i].co);
+			VECADDS( collmd->current_xnew[i].co, collmd->xold[i].co, tv, 1.0+step );
 			VECSUB ( collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co );
 		}
 	} else {
@@ -1181,67 +1216,133 @@
 	}
 }
 
+
+static void calc_edge_normal(ClothEdge *e, cdouble_t no[3])
+{
+	cdouble_t vec1[3], vec2[3];
+
+	if (e->t2) {
+		add_v3_v3v3_d(e->no, e->t1->no, e->t2->no);
+		normalize_v3_d(e->no);
+	} else if (e->t1) {
+		/*form tangent*/
+		sub_v3_v3v3_d(vec1, e->v1->txold, e->v2->txold);					
+		cross_v3_v3v3_d(e->no, e->t1->no, vec1);
+		
+		/*make sure it's pointing outward, not inward*/
+		sub_v3_v3v3_d(vec2, e->v1->txold, e->t1->ocent);
+		if (dot_v3v3_d(e->no, vec2) <= 0.0) {
+			negate_v3_d(e->no);
+		}
+
+		normalize_v3_d(e->no);
+		
+		add_v3_v3_d(e->no, e->t1->no);
+		normalize_v3_d(e->no);
+	} else {
+		/*not sure what to do here, use world up vector?*/
+		e->no[0] = 0.0; e->no[1] = 0.0; e->no[2] = 1.0;
+	}
+	
+	if (no)
+		copy_v3_v3_d(no, e->no);
+}
+
+int line_line_moving_isect_d(double v1[2][3], double v2[2][3], double v3[2][3], double v4[2][3]);
+
 /*edge[v1-v2][new-old][x-z]*/
-int point_coll_edge_pair(cdouble_t e1[2][2][3], cdouble_t e2[2][2][3])
+int point_coll_edge_pair(cdouble_t e1[2][2][3], cdouble_t e2[2][2][3], cdouble_t *sign)
 {
-	cdouble_t t[4][3], vol1, vol2;
+	cdouble_t t[4][3], vol1, vol2, t1[4][3], t2[4][3];
 
-	/*compute signed volumes between old and new positions*/
-	copy_v3_v3_d(t[0], e1[0][0]);
-	copy_v3_v3_d(t[1], e1[1][0]);
-	copy_v3_v3_d(t[2], e2[0][0]);
-	copy_v3_v3_d(t[3], e2[1][0]);
+	//return line_line_moving_isect_d(e1[0], e1[1], e2[0], e2[1]);
+
+	copy_v3_v3_d(t1[0], e1[0][0]);
+	copy_v3_v3_d(t1[1], e1[1][0]);
+	copy_v3_v3_d(t1[2], e1[0][1]);
+	copy_v3_v3_d(t1[3], e1[1][1]);
+
+	copy_v3_v3_d(t2[0], e2[0][0]);
+	copy_v3_v3_d(t2[1], e2[1][0]);
+	copy_v3_v3_d(t2[2], e2[0][1]);
+	copy_v3_v3_d(t2[3], e2[1][1]);
 	
-	vol1 = signed_tetra_volume_d(t);
-
+	/*find original signed volume*/
 	copy_v3_v3_d(t[0], e1[0][1]);
 	copy_v3_v3_d(t[1], e1[1][1]);
 	copy_v3_v3_d(t[2], e2[0][1]);
 	copy_v3_v3_d(t[3], e2[1][1]);
 	
+	vol1 = signed_tetra_volume_d(t);
+	
+	/*find original signed volume*/
+	copy_v3_v3_d(t[0], e1[0][0]);
+	copy_v3_v3_d(t[1], e1[1][0]);
+	copy_v3_v3_d(t[2], e2[0][0]);
+	copy_v3_v3_d(t[3], e2[1][0]);
+	
 	vol2 = signed_tetra_volume_d(t);
 	
-	printf("%.7lf %.7lf\n", vol1, vol2);
-	fflush(stdout);
+	{
+		cdouble_t eps=0.0000001, table[]={eps*2, -eps*0.5, eps*1.1, eps*3.0, eps*-2.0, eps*-0.5};
+		int i, j, k, c=0, tot=sizeof(table)/sizeof(*table);
 
-	return SIGN(vol1) != SIGN(vol2);
+		for (i=0; i<2; i++) {
+		for (j=0; j<2; j++) {
+		for (k=0; k<3; k++) {
+			e1[i][j][k] += table[(c++)%tot];
+		}
+		}
+		}
+		}
+
+	*sign = vol1;
+	return tetra_isect_d(t1, t2);
 }
 
-int point_coll_edge(ClothVertex *v1, ClothVertex *v2, ClothTri *colltri, cdouble_t mindis)
+int point_coll_edge(ClothVertex *v1, ClothVertex *v2, ClothTri *colltri, cdouble_t mindis, cdouble_t *signs)
 {
 	ClothVertex *cv1, *cv2;
-	cdouble_t e1[2][2][3], e2[2][2][3], no[3];
+	cdouble_t e1[2][2][3], e2[2][2][3], no[3], m;
 	int i, ret=0;
 
-	copy_v3_v3_d(e1[0][0], v1->tx);
-	copy_v3_v3_d(e1[0][1], v1->txold);
+	for (i=0; i<3; i++) {
+		copy_v3_v3_d(e1[0][0], v1->tx);
+		copy_v3_v3_d(e1[0][1], v1->txold2);
 
-	copy_v3_v3_d(e1[1][0], v2->tx);
-	copy_v3_v3_d(e1[1][1], v2->txold);
+		copy_v3_v3_d(e1[1][0], v2->tx);
+		copy_v3_v3_d(e1[1][1], v2->txold2);
 
-	for (i=0; i<3; i++) {
+		m = EDGE_SCALE;
+		scale_line_v3_d(e1[0][0], e1[1][0], m);
+		scale_line_v3_d(e1[0][1], e1[1][1], m);
+
 		cv1 = colltri->verts[i];
 		cv2 = colltri->verts[(i+1)%3];
+
 		copy_v3_v3_d(e2[0][0], cv1->tx);
-		copy_v3_v3_d(e2[0][1], cv1->txold);
-
+		copy_v3_v3_d(e2[0][1], cv1->txold2);
 		copy_v3_v3_d(e2[1][0], cv2->tx);
-		copy_v3_v3_d(e2[1][1], cv2->txold);
+		copy_v3_v3_d(e2[1][1], cv2->txold2);
 		
-		copy_v3_v3_d(no, colltri->no);
-		if (colltri->edges[i]->t2) {
-			ClothTri *colltri2 = colltri == colltri->edges[i]->t1 ? colltri->edges[i]->t2 : colltri->edges[i]->t1;
-			add_v3_v3_d(no, colltri2->no);
-			mul_v3_d(no, 0.5);
-		}
-		mul_v3_d(no, mindis+DBL_EPSILON*10);
+		scale_line_v3_d(e2[0][0], e2[1][0], m);	
+		scale_line_v3_d(e2[0][1], e2[1][1], m);
 
+		calc_edge_normal(colltri->edges[i], no);
+		mul_v3_d(no, mindis);
+
 		add_v3_v3_d(e2[0][0], no);
-		//add_v3_v3_d(e2[0][1], no);
 		add_v3_v3_d(e2[1][0], no);
-		//add_v3_v3_d(e2[1][1], no);
+		
+		if (mindis < 0.01) {
+			mul_v3_d(no, 1.0/mindis);
+			mul_v3_d(no, 0.01);
+		}
 
-		ret |= point_coll_edge_pair(e1, e2) ? 1<<i : 0;
+		sub_v3_v3_d(e2[1][1], no);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list