cleaning up

- removed euler branch in favor for a 'better solver to come'
- removed some debug vars from lattices
- removed some garbage related to 'borrowing' collision from particles
note SB collision is completly decoupled from particle stuff to allow
: 1. SB collision targets can be 'anything evaluated by modifier stack' but won't be subsurfed (for performace reasons / possible though / see comment in code)
: 2. SB <-> SB collisions
: 3. ( 1. implies that SB collision targets may be animated, hooked,  curve deformed ,  .. ! )
This commit is contained in:
Jens Ole Wund 2005-10-24 22:13:32 +00:00
parent 76b7d3b402
commit 0a3993ec0f

@ -108,6 +108,8 @@ float SoftHeunTol = 1.0f; // humm .. this should be calculated from sb parameter
/* local prototypes */ /* local prototypes */
static void free_softbody_intern(SoftBody *sb); static void free_softbody_intern(SoftBody *sb);
/* aye this belongs to arith.c */
static void Vec3PlusStVec(float *v, float s, float *v1);
/*+++ frame based timing +++*/ /*+++ frame based timing +++*/
@ -339,36 +341,16 @@ static void free_softbody_intern(SoftBody *sb)
/* ************ dynamics ********** */ /* ************ dynamics ********** */
int sb_detect_collision(float opco[3], float npco[3], float colco[3], int sb_detect_collision(float opco[3], float facenormal[3], float *damp,
float facenormal[3], float *damp, float force[3], int mode, float force[3], unsigned int par_layer,struct Object *vertexowner)
float cur_time, unsigned int par_layer,struct Object *vertexowner)
{ {
// static short recursion = 0;
// static short didokee = 0;
Base *base; Base *base;
Object *ob; Object *ob;
float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[3]; int a, deflected=0;
float dv1[3], dv2[3], dv3[3]; float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[3], dv1[3], dv2[3],
float facedist,n_mag,t,t2, min_t,force_mag_norm; facedist,n_mag,t,force_mag_norm,
int a, deflected=0, deflected_now=0; innerfacethickness = -0.5f, outerfacethickness = 0.2f,
int d_object=0, d_face=0, ds_object=0, ds_face=0; ee = 5.0f, ff = 0.1f, fa;
// i'm going to rearrange it to declaration rules when WIP is finished (BM)
float innerfacethickness = -0.5f;
float outerfacethickness = 0.2f;
float ee = 5.0f;
float ff = 0.1f;
float fa;
/*
if (recursion){
if (!didokee)
printf("SB collision detected recursion. We will CRASH now!");
didokee =1;
return 0;
}
recursion =1;
*/
min_t = 200000;
base= G.scene->base.first; base= G.scene->base.first;
while (base) { while (base) {
@ -376,19 +358,18 @@ int sb_detect_collision(float opco[3], float npco[3], float colco[3],
if(base->object->type==OB_MESH && (base->lay & par_layer)) { if(base->object->type==OB_MESH && (base->lay & par_layer)) {
ob= base->object; ob= base->object;
if((vertexowner) && (ob == vertexowner)){ if((vertexowner) && (ob == vertexowner)){
/* if vertexowner is given /* if vertexowner is given we don't want to check collision with owner object */
* we don't want to check collision with owner object */
base = base->next; base = base->next;
continue; continue;
} }
/* only with deflecting set */ /* only with deflecting set */
if(ob->pd && ob->pd->deflect) { if(ob->pd && ob->pd->deflect) {
DerivedMesh *dm=NULL; DerivedMesh *dm=NULL;
int dmNeedsFree;
Mesh *me= NULL;
DispListMesh *disp_mesh = 0; DispListMesh *disp_mesh = 0;
MFace *mface; MFace *mface;
Object *copyob; Object *copyob;
int dmNeedsFree;
/* do object level stuff */ /* do object level stuff */
/* need to have user control for that since it depends on model scale */ /* need to have user control for that since it depends on model scale */
@ -398,16 +379,12 @@ int sb_detect_collision(float opco[3], float npco[3], float colco[3],
fa *= fa; fa *= fa;
fa = 1.0f/fa; fa = 1.0f/fa;
copyob = ob; copyob = ob;
// if (ob->pd->flag & PDEFLE_DEFORM){// get colliding mesh from modifier stack
// keep this option for debugging but IMHO this is not needed
if (1){// get colliding mesh from modifier stack
if(1) { // so maybe someone wants overkill to collide with subsurfed if(1) { // so maybe someone wants overkill to collide with subsurfed
dm = mesh_get_derived_deform(copyob, &dmNeedsFree); dm = mesh_get_derived_deform(copyob, &dmNeedsFree);
} else { } else {
dm = mesh_get_derived_final(copyob, &dmNeedsFree); dm = mesh_get_derived_final(copyob, &dmNeedsFree);
} }
}
if (dm) { if (dm) {
disp_mesh = dm->convertToDispListMesh(dm, 1); disp_mesh = dm->convertToDispListMesh(dm, 1);
@ -415,14 +392,11 @@ int sb_detect_collision(float opco[3], float npco[3], float colco[3],
a = disp_mesh->totface; a = disp_mesh->totface;
} }
else { else {
me = ob->data; a = 0 ;
mface= me->mface;
a = me->totface;
} }
/* use mesh*/ /* use mesh*/
while (a--) { while (a--) {
/* Calculate the global co-ordinates of the vertices*/ /* Calculate the global co-ordinates of the vertices*/
if (dm){ if (dm){
dm->getVertCo(dm,mface->v1,nv1); dm->getVertCo(dm,mface->v1,nv1);
@ -440,26 +414,9 @@ int sb_detect_collision(float opco[3], float npco[3], float colco[3],
Mat4MulVecfl(ob->obmat, nv4); Mat4MulVecfl(ob->obmat, nv4);
} }
} }
else{
VECCOPY(nv1,(me->mvert+(mface->v1))->co);
Mat4MulVecfl(ob->obmat, nv1);
VECCOPY(nv2,(me->mvert+(mface->v2))->co);
Mat4MulVecfl(ob->obmat, nv2);
VECCOPY(nv3,(me->mvert+(mface->v3))->co);
Mat4MulVecfl(ob->obmat, nv3);
if (mface->v4){
VECCOPY(nv4,(me->mvert+(mface->v4))->co);
Mat4MulVecfl(ob->obmat, nv4);
}
}
deflected_now = 0;
if (mode == 1){ // face intrusion test
// switch origin to be nv2 // switch origin to be nv2
VECSUB(edge1, nv1, nv2); VECSUB(edge1, nv1, nv2);
VECSUB(edge2, nv3, nv2); VECSUB(edge2, nv3, nv2);
@ -477,10 +434,7 @@ int sb_detect_collision(float opco[3], float npco[3], float colco[3],
force_mag_norm =(float)exp(-ee*facedist); force_mag_norm =(float)exp(-ee*facedist);
if (facedist > outerfacethickness*ff) if (facedist > outerfacethickness*ff)
force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness); force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
Vec3PlusStVec(force,force_mag_norm,d_nvect);
force[0] += force_mag_norm*d_nvect[0] ;
force[1] += force_mag_norm*d_nvect[1] ;
force[2] += force_mag_norm*d_nvect[2] ;
*damp=ob->pd->pdef_sbdamp; *damp=ob->pd->pdef_sbdamp;
deflected = 2; deflected = 2;
} }
@ -503,56 +457,13 @@ int sb_detect_collision(float opco[3], float npco[3], float colco[3],
force_mag_norm =(float)exp(-ee*facedist); force_mag_norm =(float)exp(-ee*facedist);
if (facedist > outerfacethickness*ff) if (facedist > outerfacethickness*ff)
force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness); force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
Vec3PlusStVec(force,force_mag_norm,d_nvect);
force[0] += force_mag_norm*d_nvect[0] ;
force[1] += force_mag_norm*d_nvect[1] ;
force[2] += force_mag_norm*d_nvect[2] ;
*damp=ob->pd->pdef_sbdamp; *damp=ob->pd->pdef_sbdamp;
deflected = 2; deflected = 2;
} }
}
} }
} }
if (mode == 2){ // edge intrusion test
//t= 0.5; // this is labda of line, can use it optimize quad intersection
// sorry but no .. see below (BM)
if(LineIntersectsTriangle(opco, npco, nv1, nv2, nv3, &t) ) {
if (t < min_t) {
deflected = 1;
deflected_now = 1;
}
}
if (mface->v4) {
if( LineIntersectsTriangle(opco, npco, nv1, nv3, nv4, &t2) ) {
if (t2 < min_t) {
deflected = 1;
deflected_now = 2;
}
}
}
if ((deflected_now > 0) && ((t < min_t) ||(t2 < min_t))) {
min_t = t;
ds_object = d_object;
ds_face = d_face;
if (deflected_now==1) {
min_t = t;
VECCOPY(dv1, nv1);
VECCOPY(dv2, nv2);
VECCOPY(dv3, nv3);
}
else {
min_t = t2;
VECCOPY(dv1, nv1);
VECCOPY(dv2, nv3);
VECCOPY(dv3, nv4);
}
}
}
mface++; mface++;
}//while a }//while a
@ -568,27 +479,8 @@ int sb_detect_collision(float opco[3], float npco[3], float colco[3],
base = base->next; base = base->next;
} // while (base) } // while (base)
if (mode == 1){ // face
// recursion = 0;
return deflected; return deflected;
}
if (mode == 2){ // edge intrusion test
if (deflected) {
VECSUB(edge1, dv1, dv2);
VECSUB(edge2, dv3, dv2);
Crossf(d_nvect, edge2, edge1);
n_mag = Normalise(d_nvect);
// return point of intersection
colco[0] = opco[0] + (min_t * (npco[0] - opco[0]));
colco[1] = opco[1] + (min_t * (npco[1] - opco[1]));
colco[2] = opco[2] + (min_t * (npco[2] - opco[2]));
VECCOPY(facenormal,d_nvect);
}
}
// recursion = 0;
return deflected;
} }
/* aye this belongs to arith.c */ /* aye this belongs to arith.c */
@ -599,43 +491,18 @@ static void Vec3PlusStVec(float *v, float s, float *v1)
v[2] += s*v1[2]; v[2] += s*v1[2];
} }
static int sb_deflect_face(Object *ob,float *actpos, float *futurepos,float *collisionpos, float *facenormal,float *force,float *cf ,float *bounce) static int sb_deflect_face(Object *ob,float *actpos, float *futurepos,float *collisionpos, float *facenormal,float *force,float *cf )
{ {
int deflected; int deflected;
float s_actpos[3], s_futurepos[3]; float s_actpos[3], s_futurepos[3];
VECCOPY(s_actpos,actpos); VECCOPY(s_actpos,actpos);
if(futurepos) if(futurepos)
VECCOPY(s_futurepos,futurepos); VECCOPY(s_futurepos,futurepos);
if (bounce) *bounce *= 1.5f; deflected= sb_detect_collision(s_actpos, facenormal, cf, force , ob->lay, ob);
deflected= sb_detect_collision(s_actpos, s_futurepos, collisionpos,
facenormal, cf, force , 1,
G.scene->r.cfra, ob->lay, ob);
return(deflected); return(deflected);
} }
/* for future use (BM)
static int sb_deflect_edge_face(Object *ob,float *actpos, float *futurepos,float *collisionpos, float *facenormal,float *slip ,float *bounce)
{
int deflected;
float dummy[3],s_actpos[3], s_futurepos[3];
SoftBody *sb= ob->soft; // is supposed to be there
VECCOPY(s_actpos,actpos);
VECCOPY(s_futurepos,futurepos);
if (slip) *slip *= 0.98f;
if (bounce) *bounce *= 1.5f;
deflected= SoftBodyDetectCollision(s_actpos, s_futurepos, collisionpos,
facenormal, dummy, dummy , 2,
G.scene->r.cfra, ob->lay, ob);
return(deflected);
}
*/
// some functions removed here .. to help HOS on next merge (BM)
#define USES_FIELD 1 #define USES_FIELD 1
#define USES_DEFLECT 2 #define USES_DEFLECT 2
@ -748,24 +615,13 @@ static void softbody_calc_forces(Object *ob, float forcetime)
/* this is the place where other forces can be added /* this is the place where other forces can be added
yes, constraints and collision stuff should go here too (read baraff papers on that!) yes, constraints and collision stuff should go here too (read baraff papers on that!)
*/ */
/* try to match moving collision targets */ /* moving collision targets */
/* master switch to turn collision off (BM)*/
//if(0) {
if(do_effector & USES_DEFLECT) { if(do_effector & USES_DEFLECT) {
/*sorry for decl. here i'll move 'em up when WIP is done (BM) */ float defforce[3] = {0.0f,0.0f,0.0f}, collisionpos[3],facenormal[3], cf = 1.0f;
float defforce[3];
float collisionpos[3],facenormal[3];
float cf = 1.0f;
float bounce = 0.5f;
kd = 1.0f; kd = 1.0f;
defforce[0] = 0.0f;
defforce[1] = 0.0f;
defforce[2] = 0.0f;
if (sb_deflect_face(ob,bp->pos, bp->pos, collisionpos, facenormal,defforce,&cf,&bounce)){ if (sb_deflect_face(ob,bp->pos, bp->pos, collisionpos, facenormal,defforce,&cf)){
bp->force[0] += defforce[0]*kd; Vec3PlusStVec(bp->force,kd,defforce);
bp->force[1] += defforce[1]*kd;
bp->force[2] += defforce[2]*kd;
bp->contactfrict = cf; bp->contactfrict = cf;
} }
else{ else{
@ -907,13 +763,12 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
maxerr = MAX2(maxerr,ABS(dx[2] - bp->prevdx[2])); maxerr = MAX2(maxerr,ABS(dx[2] - bp->prevdx[2]));
/* kind of hack .. while inside collision target .. make movement more *viscous* */ /* kind of hack .. while inside collision target .. make movement more *viscous* */
if (bp->contactfrict > 0.0f){ if (bp->contactfrict > 0.0f){
bp->vec[0] *= (1.0 - bp->contactfrict); bp->vec[0] *= (1.0f - bp->contactfrict);
bp->vec[1] *= (1.0 - bp->contactfrict); bp->vec[1] *= (1.0f - bp->contactfrict);
bp->vec[2] *= (1.0 - bp->contactfrict); bp->vec[2] *= (1.0f - bp->contactfrict);
} }
} }
else { VECADD(bp->pos, bp->pos, dx);} else { VECADD(bp->pos, bp->pos, dx);}
// experimental particle collision suff was here .. just to help HOS on next merge (BM)
}//snap }//snap
} //for } //for
if (err){ /* so step size will be controlled by biggest difference in slope */ if (err){ /* so step size will be controlled by biggest difference in slope */
@ -949,23 +804,6 @@ static void softbody_apply_goalsnap(Object *ob)
} }
} }
/* unused */
#if 0
static void softbody_force_goal(Object *ob)
{
SoftBody *sb= ob->soft; // is supposed to be there
BodyPoint *bp;
int a;
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
VECCOPY(bp->pos,bp->origT);
bp->vec[0] = bp->origE[0] - bp->origS[0];
bp->vec[1] = bp->origE[1] - bp->origS[1];
bp->vec[2] = bp->origE[2] - bp->origS[2];
}
}
#endif
/* expects full initialized softbody */ /* expects full initialized softbody */
static void interpolate_exciter(Object *ob, int timescale, int time) static void interpolate_exciter(Object *ob, int timescale, int time)
{ {
@ -974,8 +812,6 @@ static void interpolate_exciter(Object *ob, int timescale, int time)
float f; float f;
int a; int a;
// note: i removed Mesh usage here, softbody should remain generic! (ton)
f = (float)time/(float)timescale; f = (float)time/(float)timescale;
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) { for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
@ -989,15 +825,6 @@ static void interpolate_exciter(Object *ob, int timescale, int time)
} }
} }
if(ob->softflag & OB_SB_EDGES) {
/* hrms .. do springs alter their lenght ?
bs= ob->soft->bspring;
bp= ob->soft->bpoint;
for(a=0; (a<me->totedge && a < ob->soft->totspring ); a++, bs++) {
bs->len= VecLenf( (bp+bs->v1)->origT, (bp+bs->v2)->origT);
}
*/
}
} }
@ -1033,8 +860,7 @@ static void get_scalar_from_vertexgroup(Object *ob, int vertID, short groupindex
} }
/* Resetting a Mesh SB object's springs */ /* Resetting a Mesh SB object's springs */
/* Spring lenght are caculted from'raw' mesh vertices that are NOT altered by modifier stack. /* Spring lenght are caculted from'raw' mesh vertices that are NOT altered by modifier stack. */
YAH, mr zuster*/
static void springs_from_mesh(Object *ob) static void springs_from_mesh(Object *ob)
{ {
SoftBody *sb; SoftBody *sb;
@ -1095,7 +921,7 @@ static void mesh_to_softbody(Object *ob,int *rcs)
*/ */
if((ob->softflag & OB_SB_GOAL) && sb->vertgroup) { if((ob->softflag & OB_SB_GOAL) && sb->vertgroup) {
get_scalar_from_vertexgroup(ob, a, sb->vertgroup-1, &bp->goal); get_scalar_from_vertexgroup(ob, a,(short) (sb->vertgroup-1), &bp->goal);
// do this always, regardless successfull read from vertex group // do this always, regardless successfull read from vertex group
bp->goal= sb->mingoal + bp->goal*goalfac; bp->goal= sb->mingoal + bp->goal*goalfac;
} }
@ -1137,10 +963,7 @@ static void mesh_to_softbody(Object *ob,int *rcs)
static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff) static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff)
{ {
int u, v, w, dv, dw, bpc, bpuc; int u, v, w, dv, dw, bpc=0, bpuc;
int debugspringcounter = 0;
bpc =0;
dv= lt->pntsu; dv= lt->pntsu;
dw= dv*lt->pntsv; dw= dv*lt->pntsv;
@ -1156,23 +979,18 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff)
bs->v2 = bpc-dw; bs->v2 = bpc-dw;
bs->strength= 1.0; bs->strength= 1.0;
bs++; bs++;
debugspringcounter++;
} }
if(v) { if(v) {
bs->v1 = bpc; bs->v1 = bpc;
bs->v2 = bpc-dv; bs->v2 = bpc-dv;
bs->strength= 1.0; bs->strength= 1.0;
bs++; bs++;
debugspringcounter++;
} }
if(u) { if(u) {
bs->v1 = bpuc; bs->v1 = bpuc;
bs->v2 = bpc; bs->v2 = bpc;
bs->strength= 1.0; bs->strength= 1.0;
bs++; bs++;
debugspringcounter++;
} }
if (dostiff) { if (dostiff) {
@ -1183,14 +1001,12 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff)
bs->v2 = bpc-dw-dv-1; bs->v2 = bpc-dw-dv-1;
bs->strength= 1.0; bs->strength= 1.0;
bs++; bs++;
debugspringcounter++;
} }
if( (v < lt->pntsv-1) && (u) ) { if( (v < lt->pntsv-1) && (u) ) {
bs->v1 = bpc; bs->v1 = bpc;
bs->v2 = bpc-dw+dv-1; bs->v2 = bpc-dw+dv-1;
bs->strength= 1.0; bs->strength= 1.0;
bs++; bs++;
debugspringcounter++;
} }
} }
@ -1200,14 +1016,12 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff)
bs->v2 = bpc+dw-dv-1; bs->v2 = bpc+dw-dv-1;
bs->strength= 1.0; bs->strength= 1.0;
bs++; bs++;
debugspringcounter++;
} }
if( (v < lt->pntsv-1) && (u) ) { if( (v < lt->pntsv-1) && (u) ) {
bs->v1 = bpc; bs->v1 = bpc;
bs->v2 = bpc+dw+dv-1; bs->v2 = bpc+dw+dv-1;
bs->strength= 1.0; bs->strength= 1.0;
bs++; bs++;
debugspringcounter++;
} }
} }
} }
@ -1284,7 +1098,7 @@ static int softbody_baked_step(Object *ob, float framenr, float (*vertexCos)[3],
dfra= (float)sb->interval; dfra= (float)sb->interval;
/* offset in keys array */ /* offset in keys array */
ofs1= floor( (cfra-sfra)/dfra ); ofs1= (int)floor( (cfra-sfra)/dfra );
if(ofs1 < 0) { if(ofs1 < 0) {
key0=key1=key2=key3= *sb->keys; key0=key1=key2=key3= *sb->keys;
@ -1353,7 +1167,7 @@ static void softbody_baked_add(Object *ob, float framenr)
fac1= 0.0; fac1= 0.0;
} }
else { else {
ofs1= floor( (cfra-sfra)/dfra ); ofs1= (int)floor( (cfra-sfra)/dfra );
fac1= ((cfra-sfra)/dfra) - (float)ofs1; fac1= ((cfra-sfra)/dfra) - (float)ofs1;
} }
if( fac1 < 1.0/dfra ) { if( fac1 < 1.0/dfra ) {
@ -1382,13 +1196,13 @@ SoftBody *sbNew(void)
sb->nodemass= 1.0; sb->nodemass= 1.0;
sb->grav= 0.0; sb->grav= 0.0;
sb->physics_speed= 1.0; sb->physics_speed= 1.0;
sb->rklimit= 0.1; sb->rklimit= 0.1f;
sb->goalspring= 0.5; sb->goalspring= 0.5;
sb->goalfrict= 0.0; sb->goalfrict= 0.0;
sb->mingoal= 0.0; sb->mingoal= 0.0;
sb->maxgoal= 1.0; sb->maxgoal= 1.0;
sb->defgoal= 0.7; sb->defgoal= 0.7f;
sb->inspring= 0.5; sb->inspring= 0.5;
sb->infrict= 0.5; sb->infrict= 0.5;
@ -1433,9 +1247,8 @@ static int object_has_edges(Object *ob)
void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts) void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts)
{ {
SoftBody *sb; SoftBody *sb;
Base *base;
BodyPoint *bp; BodyPoint *bp;
int a,timescale,t,rcs; int a,rcs;
float dtime,ctime,forcetime,err; float dtime,ctime,forcetime,err;
/* baking works with global time */ /* baking works with global time */
@ -1473,9 +1286,7 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
if(sb->totpoint==0) return; if(sb->totpoint==0) return;
/* reset deflector cache, sumohandle is free, but its still sorta abuse... (ton) */ /* reset deflector cache, sumohandle is free, but its still sorta abuse... (ton) */
for(base= G.scene->base.first; base; base= base->next) { /* we don't use that any more (BM) */
base->object->sumohandle= NULL;
}
/* checking time: */ /* checking time: */
@ -1579,42 +1390,8 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
} }
else{ else{
/* do brute force explicit euler */ /* do brute force explicit euler */
/* inner intagration loop */ /* removed but left this branch for better integrators / solvers (BM) */
/* */ /* yah! Nicholas Guttenberg (NichG) here is the place to plug in */
// loop n times so that n*h = duration of one frame := 1
// x(t+h) = x(t) + h*v(t);
// v(t+h) = v(t) + h*f(x(t),t);
timescale = (int)(sb->rklimit * ABS(dtime));
for(t=1 ; t <= timescale; t++) {
if (ABS(dtime) > 15 ) break;
/* the *goal* mesh must use the n*h timing too !
use *cheap* linear intepolation for that */
interpolate_exciter(ob,timescale,t);
if (timescale > 0 ) {
forcetime = dtime/timescale;
/* does not fit the concept sloving ODEs :) */
/* softbody_apply_goal(ob,forcetime ); */
/* explicit Euler integration */
/* we are not controling a nuclear power plant!
so rought *almost* physical behaviour is acceptable.
in cases of *mild* stiffnes cranking up timscale -> decreasing stepsize *h*
avoids instability */
softbody_calc_forces(ob,forcetime);
softbody_apply_forces(ob,forcetime,0, NULL);
softbody_apply_goalsnap(ob);
// if (0){
/* ok here comes the überhammer
use a semi implicit euler integration to tackle *all* stiff conditions
but i doubt the cost/benifit holds for most of the cases
-- to be coded*/
// }
}
}
} }
} }
@ -1622,12 +1399,7 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
sb->ctime= ctime; sb->ctime= ctime;
/* reset deflector cache */ /* reset deflector cache */
for(base= G.scene->base.first; base; base= base->next) { /* we don't use that any more (BM) */
if(base->object->sumohandle) {
MEM_freeN(base->object->sumohandle);
base->object->sumohandle= NULL;
}
}
if(ob->softflag & OB_SB_BAKEDO) softbody_baked_add(ob, framenr); if(ob->softflag & OB_SB_BAKEDO) softbody_baked_add(ob, framenr);
} }