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
path: root/source
diff options
context:
space:
mode:
authorJens Ole Wund <bjornmose@gmx.net>2006-09-29 00:27:46 +0400
committerJens Ole Wund <bjornmose@gmx.net>2006-09-29 00:27:46 +0400
commit8e7b4039247419a34093b06b5a05c2423d2cab05 (patch)
treeb4e765dd6cfac489c91992c78f26c98aea6f1f5b /source
parent22ce0faffe1423a31c1abd8ab262a20aedbda8eb (diff)
new softbody feature:
simple (naive) self collision estimates a collision ball using the spring lenght to attached neighbours (idea stolen from old cloth modifier files, but i'm sure ZAZ and genscher won't mind) -- usefull for untangeling static cloth like objects -- may be used for cloth simulation with known limitations like 'tunnel effect' if objects are moving too fast ... demo -- volatile files http://www.wund.homepage.t-online.de/hidden/sb_without_selfcol.avi http://www.wund.homepage.t-online.de/hidden/sb_with_selfcoll.avi have fun BM
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/softbody.c79
-rw-r--r--source/blender/makesdna/DNA_object_force.h1
-rw-r--r--source/blender/src/buttons_object.c5
3 files changed, 79 insertions, 6 deletions
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index ada8fb5cc21..eed086035ca 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -92,6 +92,7 @@ typedef struct BodyPoint {
float prevpos[3], prevvec[3], prevdx[3], prevdv[3]; /* used for Heun integration */
int nofsprings; int *springs;
float contactfrict;
+ float colball;
} BodyPoint;
typedef struct BodySpring {
@@ -673,6 +674,27 @@ static void build_bps_springlist(Object *ob)
}/*for bp*/
}
+static void calculate_collision_balls(Object *ob)
+{
+ SoftBody *sb= ob->soft; /* is supposed to be there */
+ BodyPoint *bp;
+ BodySpring *bs;
+ int a,b;
+
+ if (sb==NULL) return; /* paranoya check */
+
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+ bp->colball=0;
+ for(b=bp->nofsprings;b>0;b--){
+ bs = sb->bspring + bp->springs[b-1];
+ bp->colball += bs->len;
+ }
+ if (bp->nofsprings != 0) bp->colball /= bp->nofsprings;
+ else bp->colball=0;
+ /* printf("collision ballsize %f \n",bp->colball); */
+ }/*for bp*/
+}
+
/* creates new softbody if didn't exist yet, makes new points and springs arrays */
static void renew_softbody(Object *ob, int totpoint, int totspring)
@@ -984,7 +1006,7 @@ static void softbody_calc_forces(Object *ob, float forcetime)
ListBase *do_effector;
float iks, ks, kd, gravity, actspringlen, forcefactor, sd[3];
float fieldfactor = 1000.0f, windfactor = 250.0f;
- int a, b, do_deflector;
+ int a, b, do_deflector;
/* clear forces */
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
@@ -1001,7 +1023,7 @@ static void softbody_calc_forces(Object *ob, float forcetime)
bproot= sb->bpoint; /* need this for proper spring addressing */
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
- if(bp->goal < SOFTGOALSNAP){ /* ommit this bp when i snaps */
+ if(bp->goal < SOFTGOALSNAP){ /* ommit this bp when it snaps */
float auxvect[3];
float velgoal[3];
float absvel =0, projvel= 0;
@@ -1084,7 +1106,57 @@ static void softbody_calc_forces(Object *ob, float forcetime)
bp->contactfrict = 0.0f;
}
+ }
+ else
+ {
+ bp->contactfrict = 0.0f;
+ }
+ /* naive ball self collision */
+ if((ob->softflag & OB_SB_EDGES) && (sb->bspring)
+ && (ob->softflag & OB_SB_SELF)){
+ int attached;
+ BodyPoint *obp;
+ int c,b;
+ float def[3];
+ float tune2 = 0.5f;
+ float tune = 1.0f;
+ float distance;
+ float compare;
+
+ for(c=sb->totpoint, obp= sb->bpoint; c>0; c--, obp++) {
+
+ if (c < a ) continue; /* exploit force(a,b) == force(b,a) part1/2 */
+
+ compare = (obp->colball + bp->colball) * tune2;
+ VecSubf(def, bp->pos, obp->pos);
+ distance = Normalise(def);
+
+
+ if (distance < compare ){
+ /* exclude body points attached with a spring */
+ attached = 0;
+ for(b=obp->nofsprings;b>0;b--){
+ bs = sb->bspring + obp->springs[b-1];
+ if (( sb->totpoint-a == bs->v2) || ( sb->totpoint-a == bs->v1)){
+ attached=1;
+ continue;}
+
+ }
+ if (!attached){
+ /* would need another UI parameter defining fricton on self contact */
+ float ccfriction = 0.05;
+ float f = tune/(distance) + tune/(compare*compare)*distance - 2.0f*tune/compare ;
+ Vec3PlusStVec(bp->force,f,def);
+ if (bp->contactfrict == 0.0f) bp->contactfrict = ccfriction*compare/distance;
+ /* exploit force(a,b) == force(b,a) part2/2 */
+ Vec3PlusStVec(obp->force,-f,def);
+ if (obp->contactfrict == 0.0f) obp->contactfrict = ccfriction*compare/distance;
+ }
+
+ }
+ }
}
+ /* naive ball self collision done */
/*other forces done*/
/* nice things could be done with anisotropic friction
@@ -1147,7 +1219,6 @@ static void softbody_calc_forces(Object *ob, float forcetime)
}/*any edges*/
}/*omit on snap */
}/*loop all bp's*/
-
/* cleanup */
if(do_effector)
pdEndEffectors(do_effector);
@@ -1429,13 +1500,13 @@ static void mesh_to_softbody(Object *ob)
}
build_bps_springlist(ob); /* scan for springs attached to bodypoints ONCE */
-
/* insert *other second order* springs if desired */
if (sb->secondspring > 0.0000001f) {
add_2nd_order_springs(ob,sb->secondspring); /* exploits the the first run of build_bps_springlist(ob);*/
build_bps_springlist(ob); /* yes we need to do it again*/
}
springs_from_mesh(ob); /* write the 'rest'-lenght of the springs */
+ calculate_collision_balls(ob);
}
}
diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h
index b7bc74d524b..0508d7bac60 100644
--- a/source/blender/makesdna/DNA_object_force.h
+++ b/source/blender/makesdna/DNA_object_force.h
@@ -123,6 +123,7 @@ typedef struct SoftBody {
#define OB_SB_BAKESET 64
#define OB_SB_BAKEDO 128
#define OB_SB_RESET 256
+#define OB_SB_SELF 512
#ifdef __cplusplus
}
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index 983c6335407..749ff17c4e9 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -2355,8 +2355,9 @@ static void object_softbodies(Object *ob)
/* EDGE SPRING STUFF */
if(ob->type!=OB_SURF) {
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, OB_SB_EDGES, B_SOFTBODY_CHANGE, "Use Edges", 10,30,150,20, &ob->softflag, 0, 0, 0, 0, "Use Edges as springs");
- uiDefButBitS(block, TOG, OB_SB_QUADS, B_SOFTBODY_CHANGE, "Stiff Quads", 160,30,150,20, &ob->softflag, 0, 0, 0, 0, "Adds diagonal springs on 4-gons");
+ uiDefButBitS(block, TOG, OB_SB_EDGES, B_SOFTBODY_CHANGE, "Use Edges", 10,30,90,20, &ob->softflag, 0, 0, 0, 0, "Use Edges as springs");
+ uiDefButBitS(block, TOG, OB_SB_QUADS, B_SOFTBODY_CHANGE, "Stiff Quads", 110,30,90,20, &ob->softflag, 0, 0, 0, 0, "Adds diagonal springs on 4-gons");
+ uiDefButBitS(block, TOG, OB_SB_SELF, B_DIFF, "Self Collision", 220,30,90,20, &ob->softflag, 0, 0, 0, 0, "Use Edges as springs");
uiDefButF(block, NUM, B_DIFF, "E Stiff:", 10,10,150,20, &sb->inspring, 0.0, 0.999, 10, 0, "Edge spring stiffness");
uiDefButF(block, NUM, B_DIFF, "E Damp:", 160,10,150,20, &sb->infrict, 0.0, 50.0, 10, 0, "Edge spring friction");
uiBlockEndAlign(block);