Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Ole Wund <bjornmose@gmx.net>2007-10-19 02:47:55 +0400
committerJens Ole Wund <bjornmose@gmx.net>2007-10-19 02:47:55 +0400
commitd407f5ae81e378b4ff76d58da42086b8cf95b310 (patch)
tree8a8adf3212c91e875c6ac58d58d761d5f9a41b5a /source/blender
parent5ea45a1385a2bc71be572fd7923c508edb70eaa2 (diff)
added point to edge collision in case point to face missed
/* special hidden feature! shrink to fit */ if (G.rt > 500){ scale = (G.rt - 500) / 100.0f; } -- shrink a T shirt to fit .. evil grin -- by the way i did set up the rule 'if any *outer object* hits no *inner* will be regarded' ... pretty poor IMHO .. well but it works
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/intern/softbody.c126
1 files changed, 113 insertions, 13 deletions
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 93bda9ac530..c62f59106a3 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -1551,7 +1551,8 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
GHash *hash;
GHashIterator *ihash;
float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[3], dv1[3],ve[3],avel[3],
- vv1[3], vv2[3], vv3[3], vv4[3],
+ vv1[3], vv2[3], vv3[3], vv4[3], coledge[3], mindistedge = 1000.0f,
+ outerforceaccu[3],innerforceaccu[3],
facedist,n_mag,force_mag_norm,minx,miny,minz,maxx,maxy,maxz,
innerfacethickness = -0.5f, outerfacethickness = 0.2f,
ee = 5.0f, ff = 0.1f, fa;
@@ -1560,6 +1561,8 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
*intrusion = 0.0f;
hash = vertexowner->soft->scratch->colliderhash;
ihash = BLI_ghashIterator_new(hash);
+ outerforceaccu[0]=outerforceaccu[1]=outerforceaccu[2]=0.0f;
+ innerforceaccu[0]=innerforceaccu[1]=innerforceaccu[2]=0.0f;
/* go */
while (!BLI_ghashIterator_isDone(ihash) ) {
@@ -1675,16 +1678,24 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
Crossf(d_nvect, edge2, edge1);
n_mag = Normalize(d_nvect);
facedist = Inpf(dv1,d_nvect);
+ // so rules are
+ //
if ((facedist > innerfacethickness) && (facedist < outerfacethickness)){
if (point_in_tri_prism(opco, nv1, nv2, nv3) ){
force_mag_norm =(float)exp(-ee*facedist);
if (facedist > outerfacethickness*ff)
force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
- Vec3PlusStVec(force,force_mag_norm,d_nvect);
*damp=ob->pd->pdef_sbdamp;
if (facedist > 0.0f){
*damp *= (1.0f - facedist/outerfacethickness);
+ Vec3PlusStVec(outerforceaccu,force_mag_norm,d_nvect);
+ deflected = 3;
+
+ }
+ else {
+ Vec3PlusStVec(innerforceaccu,force_mag_norm,d_nvect);
+ if (deflected < 2) deflected = 2;
}
if ((mprevvert) && (*damp > 0.0f)){
choose_winner(ve,opco,nv1,nv2,nv3,vv1,vv2,vv3);
@@ -1693,7 +1704,6 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
}
*intrusion += facedist;
ci++;
- deflected = 2;
}
}
if (mface->v4){ /* quad */
@@ -1711,11 +1721,17 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
force_mag_norm =(float)exp(-ee*facedist);
if (facedist > outerfacethickness*ff)
force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
- Vec3PlusStVec(force,force_mag_norm,d_nvect);
*damp=ob->pd->pdef_sbdamp;
- if (facedist > 0.0f){
- *damp *= (1.0f - facedist/outerfacethickness);
- }
+ if (facedist > 0.0f){
+ *damp *= (1.0f - facedist/outerfacethickness);
+ Vec3PlusStVec(outerforceaccu,force_mag_norm,d_nvect);
+ deflected = 3;
+
+ }
+ else {
+ Vec3PlusStVec(innerforceaccu,force_mag_norm,d_nvect);
+ if (deflected < 2) deflected = 2;
+ }
if ((mprevvert) && (*damp > 0.0f)){
choose_winner(ve,opco,nv1,nv3,nv4,vv1,vv3,vv4);
@@ -1724,10 +1740,62 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
}
*intrusion += facedist;
ci++;
- deflected = 2;
}
}
+ if ((deflected < 2)&& (G.rt != 444)) // we did not hit a face until now
+ { // see if 'outer' hits an edge
+ float dist;
+
+ PclosestVL3Dfl(ve, opco, nv1, nv2);
+ VECSUB(ve,opco,ve);
+ dist = Normalize(ve);
+ if ((dist < outerfacethickness)&&(dist < mindistedge )){
+ VECCOPY(coledge,ve);
+ mindistedge = dist,
+ deflected=1;
+ }
+
+ PclosestVL3Dfl(ve, opco, nv2, nv3);
+ VECSUB(ve,opco,ve);
+ dist = Normalize(ve);
+ if ((dist < outerfacethickness)&&(dist < mindistedge )){
+ VECCOPY(coledge,ve);
+ mindistedge = dist,
+ deflected=1;
+ }
+
+ PclosestVL3Dfl(ve, opco, nv3, nv1);
+ VECSUB(ve,opco,ve);
+ dist = Normalize(ve);
+ if ((dist < outerfacethickness)&&(dist < mindistedge )){
+ VECCOPY(coledge,ve);
+ mindistedge = dist,
+ deflected=1;
+ }
+ if (mface->v4){ /* quad */
+ PclosestVL3Dfl(ve, opco, nv3, nv4);
+ VECSUB(ve,opco,ve);
+ dist = Normalize(ve);
+ if ((dist < outerfacethickness)&&(dist < mindistedge )){
+ VECCOPY(coledge,ve);
+ mindistedge = dist,
+ deflected=1;
+ }
+
+ PclosestVL3Dfl(ve, opco, nv1, nv4);
+ VECSUB(ve,opco,ve);
+ dist = Normalize(ve);
+ if ((dist < outerfacethickness)&&(dist < mindistedge )){
+ VECCOPY(coledge,ve);
+ mindistedge = dist,
+ deflected=1;
+ }
+
+ }
+
+
+ }
}
mface++;
mima++;
@@ -1735,6 +1803,25 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
} /* if(ob->pd && ob->pd->deflect) */
BLI_ghashIterator_step(ihash);
} /* while () */
+
+ if (deflected == 1){ // no face but 'outer' edge cylinder sees vert
+ force_mag_norm =(float)exp(-ee*mindistedge);
+ if (mindistedge > outerfacethickness*ff)
+ force_mag_norm =(float)force_mag_norm*fa*(mindistedge - outerfacethickness)*(mindistedge - outerfacethickness);
+ Vec3PlusStVec(force,force_mag_norm,coledge);
+ *damp=ob->pd->pdef_sbdamp;
+ if (mindistedge > 0.0f){
+ *damp *= (1.0f - mindistedge/outerfacethickness);
+ }
+
+ }
+ if (deflected == 2){ // face inner detected
+ VECADD(force,force,innerforceaccu);
+ }
+ if (deflected == 3){ // face outer detected
+ VECADD(force,force,outerforceaccu);
+ }
+
BLI_ghashIterator_free(ihash);
if (cavel) VecMulf(avel,1.0f/(float)cavel);
VECCOPY(vel,avel);
@@ -2313,6 +2400,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
VECCOPY(bp->prevvec, bp->vec);
VECCOPY(bp->prevdv, dv);
}
+
if (mode ==2){
/* be optimistic and execute step */
bp->vec[0] = bp->prevvec[0] + 0.5f * (dv[0] + bp->prevdv[0]);
@@ -2330,10 +2418,9 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
/* x(t + dt) = x(t) + v(t) * dt */
VECCOPY(dx,bp->vec);
- dx[0]*=forcetime ;
- dx[1]*=forcetime ;
- dx[2]*=forcetime ;
-
+ dx[0]*=forcetime;
+ dx[1]*=forcetime;
+ dx[2]*=forcetime;
/* again some nasty if's to have heun in here too */
if (mode ==1){
VECCOPY(bp->prevpos,bp->pos);
@@ -2492,6 +2579,7 @@ static void springs_from_mesh(Object *ob)
Mesh *me= ob->data;
BodyPoint *bp;
int a;
+ float scale =1.0f;
sb= ob->soft;
if (me && sb)
@@ -2509,9 +2597,13 @@ static void springs_from_mesh(Object *ob)
}
/* recalculate spring length for meshes here */
+ /* special hidden feature! shrink to fit */
+ if (G.rt > 500){
+ scale = (G.rt - 500) / 100.0f;
+ }
for(a=0; a<sb->totspring; a++) {
BodySpring *bs = &sb->bspring[a];
- bs->len= VecLenf(sb->bpoint[bs->v1].origS, sb->bpoint[bs->v2].origS);
+ bs->len= scale*VecLenf(sb->bpoint[bs->v1].origS, sb->bpoint[bs->v2].origS);
}
}
}
@@ -3035,6 +3127,11 @@ SoftBody *sbNew(void)
sb->balldamp = 0.50f;
sb->ballstiff= 1.0f;
sb->sbc_mode = 1;
+
+
+ sb->minloops = 10;
+
+ sb->choke = 3;
sb_new_scratch(sb);
return sb;
}
@@ -3244,9 +3341,12 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
/* do predictive euler step */
softbody_calc_forces(ob, forcetime,timedone/dtime);
softbody_apply_forces(ob, forcetime, 1, NULL);
+
+
/* crop new slope values to do averaged slope step */
softbody_calc_forces(ob, forcetime,timedone/dtime);
softbody_apply_forces(ob, forcetime, 2, &err);
+
softbody_apply_goalsnap(ob);
if (err > SoftHeunTol) { /* error needs to be scaled to some quantity */