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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs