[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [28715] branches/render25/source/blender/ blenkernel/intern: improved cloth solver for hair situations.
Joseph Eagar
joeedh at gmail.com
Mon May 10 19:16:32 CEST 2010
Revision: 28715
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=28715
Author: joeedh
Date: 2010-05-10 19:16:32 +0200 (Mon, 10 May 2010)
Log Message:
-----------
improved cloth solver for hair situations. also, made flexibility dampening use a special mode for hair, that applies it to individual hair strands (you can use internal friction, e.g. the velocity smoothing, for global velocity dampening).
Modified Paths:
--------------
branches/render25/source/blender/blenkernel/intern/cloth.c
branches/render25/source/blender/blenkernel/intern/implicit.c
Modified: branches/render25/source/blender/blenkernel/intern/cloth.c
===================================================================
--- branches/render25/source/blender/blenkernel/intern/cloth.c 2010-05-10 15:05:27 UTC (rev 28714)
+++ branches/render25/source/blender/blenkernel/intern/cloth.c 2010-05-10 17:16:32 UTC (rev 28715)
@@ -957,7 +957,7 @@
return 0;
}
-#if 0
+#ifdef CLOTH_GOAL_ORIGINAL
for ( i = 0; i < dm->getNumVerts(dm); i++)
{
if((!(cloth->verts[i].flags & CLOTH_VERT_FLAG_PINNED)) && (cloth->verts[i].goal > ALMOST_ZERO))
Modified: branches/render25/source/blender/blenkernel/intern/implicit.c
===================================================================
--- branches/render25/source/blender/blenkernel/intern/implicit.c 2010-05-10 15:05:27 UTC (rev 28714)
+++ branches/render25/source/blender/blenkernel/intern/implicit.c 2010-05-10 17:16:32 UTC (rev 28715)
@@ -1292,7 +1292,8 @@
}
else if(s->type & CLOTH_SPRING_TYPE_GOAL)
{
- /*float tvect[3];
+#ifdef CLOTH_GOAL_ORIGINAL
+ float tvect[3];
s->flags |= CLOTH_SPRING_FLAG_NEEDED;
@@ -1319,7 +1320,8 @@
// HERE IS THE PROBLEM!!!!
// dfdx_spring(s->dfdx, dir, length, 0.0, k);
- // dfdv_damp(s->dfdv, dir, MIN2(1.0, (clmd->sim_parms->goalfrict/100.0)));*/
+ // dfdv_damp(s->dfdv, dir, MIN2(1.0, (clmd->sim_parms->goalfrict/100.0)));
+#endif
}
else // calculate force of bending springs
{
@@ -1353,7 +1355,9 @@
VECADD(lF[s->ij], lF[s->ij], s->f);
- //if(!(s->type & CLOTH_SPRING_TYPE_GOAL))
+#ifdef CLOTH_GOAL_ORIGINAL
+ if(!(s->type & CLOTH_SPRING_TYPE_GOAL))
+#endif
VECSUB(lF[s->kl], lF[s->kl], s->f);
sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, s->dfdx);
@@ -1737,6 +1741,9 @@
float damp;
int i, totverts=cloth->numverts;
+ damp = clmd->sim_parms->rigid_damp;
+ damp = 1.0 - pow(1.0 - damp, dt);
+
v = verts;
for (i=0; i < totverts; i++, v++) {
float vec[3];
@@ -1776,9 +1783,6 @@
mul_v3_fl(lin, 1.0 / totmass);
mul_v3_fl(ang, 1.0 / totmass);
- damp = clmd->sim_parms->rigid_damp;
- damp = 1.0 - pow(1.0 - damp, dt);
-
v = verts;
for (i=0; i<totverts; i++, v++) {
float vec[3], vel2[3]={0, 0, 0}, l, vel3[3]={0, 0, 0};
@@ -1806,6 +1810,99 @@
}
}
+/*uses rigid body damping on each hair strand.
+ step 1: global rigid body damping
+ step 2: if necassary, could try implementing shape matching,
+ assuming each hair segment is a cylinder (eek!).*/
+void hair_rigid_damping(ClothModifierData * clmd, float dt) {
+ Cloth *cloth = clmd->clothObject;
+ ClothVertex *v, *verts = clmd->clothObject->verts;
+ float gravity[3], lin[3] = {0, 0, 0}, ang[3] = {0, 0, 0}, totmass = 0, ocent[3], cent[3];
+ float damp;
+ int i, totverts=cloth->numverts, starti=0, totv;
+
+ VECCOPY(gravity, clmd->scene->physics_settings.gravity);
+ mul_v3_fl(gravity, dt*clmd->sim_parms->Cvi*0.01); /*only use 1/2 of gravity force, this is a hack, heh*/
+
+ damp = clmd->sim_parms->rigid_damp;
+ damp = 1.0 - pow(1.0 - damp, dt);
+
+ while (starti < totverts) {
+ v = verts + starti;
+ for (i=starti; i < totverts; i++, v++) {
+ float vec[3];
+
+ if (i != starti && v->goal > (v-1)->goal)
+ break;
+
+ if (i == starti) {
+ copy_v3_v3(cent, v->tx);
+ copy_v3_v3(ocent, v->txold);
+ }
+
+ sub_v3_v3v3(v->tv, v->tx, v->txold);
+
+ totmass += v->mass;
+ }
+
+ starti += 1;
+
+ totv = i - starti;
+ if (totmass == 0.0 || starti >= totverts)
+ return;
+
+ /*we artificially add on gravity, since the hair root isn't effected by it*/
+ sub_v3_v3v3(lin, cent, ocent);
+ add_v3_v3(lin, gravity);
+
+ v = verts + starti;
+ for (i=starti; i < starti+totv; i++, v++) {
+ float vel[3], vec[3], lang[3] = {0, 0, 0}, l, dot;
+
+ copy_v3_v3(vel, v->tv);
+ sub_v3_v3v3(vec, v->tx, ocent);
+
+ dot = dot_v3v3(vec, vel);
+ if (fabs(dot) > 0.000001) {
+ cross_v3_v3v3(lang, vec, vel);
+ }
+
+ add_v3_v3v3(ang, ang, lang);
+ }
+
+ mul_v3_fl(lin, 1.0 / totmass);
+ mul_v3_fl(ang, 1.0 / totmass);
+
+ v = verts + starti + 1;
+ for (i=starti + 1; i<starti+totv; i++, v++) {
+ float vec[3], vel2[3]={0, 0, 0}, l, vel3[3]={0, 0, 0};
+
+ sub_v3_v3v3(vec, v->tx, cent);
+ if (dot_v3v3(ang, ang) > FLT_EPSILON) {
+ cross_v3_v3v3(vel2, ang, vec);
+ }
+
+ copy_v3_v3(vec, lin);
+
+ add_v3_v3v3(vec, lin, vel2);
+ mul_v3_fl(vec, v->mass);
+
+ l = len_v3(v->tv);
+ normalize_v3(vec);
+ mul_v3_fl(vec, l);
+
+ sub_v3_v3(vec, v->tv);
+ mul_v3_fl(vec, damp);
+
+ add_v3_v3(v->tv, vec);
+
+ add_v3_v3v3(v->tx, v->txold, v->tv);
+ }
+
+ starti = i;
+ }
+}
+
int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors)
{
unsigned int i=0;
@@ -1825,7 +1922,9 @@
if(verts [i].flags & CLOTH_VERT_FLAG_PINNED)
{
VECSUB(id->V[i], verts[i].xconst, verts[i].xold);
- // mul_v3_fl(id->V[i], clmd->sim_parms->stepsPerFrame);
+#ifdef CLOTH_GOAL_ORIGINAL
+ mul_v3_fl(id->V[i], clmd->sim_parms->stepsPerFrame);
+#endif
}
}
}
@@ -1871,6 +1970,7 @@
VECCOPY(verts[i].tx, id->Xnew[i]);
/*apply goal forces*/
+#ifndef CLOTH_GOAL_ORIGINAL
if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) &&
!(verts [i].flags & CLOTH_VERT_FLAG_PINNED))
{
@@ -1883,13 +1983,16 @@
add_v3_v3(verts[i].tx, vec);
}
-
+#endif
VECSUB(verts[i].tv, verts[i].tx, verts[i].txold);
VECCOPY(verts[i].v, verts[i].tv);
}
//velocity rigid body damping
- rigidbody_damping(clmd, dt/clmd->sim_parms->timescale);
+ if (clmd->clothObject->numfaces)
+ rigidbody_damping(clmd, dt/clmd->sim_parms->timescale);
+ else
+ hair_rigid_damping(clmd, dt/clmd->sim_parms->timescale);
// call collision function
// TODO: check if "step" or "step+dt" is correct - dg
@@ -1918,10 +2021,12 @@
// V = Vnew;
cp_lfvector(id->V, id->Vnew, numverts);
+#if 1 //CLOTH_GOAL_ORIGINAL
// calculate
- //cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step+dt, id->M);
+ cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step+dt, id->M);
- //simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt/2, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI);
+ simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt/2, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI);
+#endif
} else {
// X = Xnew;
cp_lfvector(id->X, id->Xnew, numverts);
More information about the Bf-blender-cvs
mailing list