forked from bartvdbraak/blender
softbodies again
unnesting aerodynamics from edge collision cleaning up softbody.c that is: removing old todos in comments adding some new :)
This commit is contained in:
parent
bc10cf38b9
commit
03be45c8c0
@ -96,12 +96,7 @@ typedef struct BodyPoint {
|
|||||||
typedef struct BodySpring {
|
typedef struct BodySpring {
|
||||||
int v1, v2;
|
int v1, v2;
|
||||||
float len, strength;
|
float len, strength;
|
||||||
float ext_force[3];
|
float ext_force[3]; /* edges colliding and sailing */
|
||||||
/* ^^^^^^^^^ for collision now,
|
|
||||||
but could be used for forces depending on orientations
|
|
||||||
such as wind --> project the lenght on the (relative) wind
|
|
||||||
via inner product force -> sin(<v_wind-v_spring,v1-v2>)
|
|
||||||
*/
|
|
||||||
short order;
|
short order;
|
||||||
short flag;
|
short flag;
|
||||||
} BodySpring;
|
} BodySpring;
|
||||||
@ -169,7 +164,7 @@ static float sb_time_scale(Object *ob)
|
|||||||
/*+++ collider caching and dicing +++*/
|
/*+++ collider caching and dicing +++*/
|
||||||
|
|
||||||
/********************
|
/********************
|
||||||
for each target object/face the ortho bounding box (OBB) is stored
|
for each target object/face the axis aligned bounding box (AABB) is stored
|
||||||
faces paralell to global axes
|
faces paralell to global axes
|
||||||
so only simple "value" in [min,max] ckecks are used
|
so only simple "value" in [min,max] ckecks are used
|
||||||
float operations still
|
float operations still
|
||||||
@ -443,12 +438,6 @@ void ccd_build_deflector_cache(Object *vertexowner)
|
|||||||
if(base->object->type==OB_MESH && (base->lay & vertexowner->lay)) {
|
if(base->object->type==OB_MESH && (base->lay & vertexowner->lay)) {
|
||||||
ob= base->object;
|
ob= base->object;
|
||||||
if((vertexowner) && (ob == vertexowner)){
|
if((vertexowner) && (ob == vertexowner)){
|
||||||
/* duuh thats myself! */
|
|
||||||
/* anyhow to do some clever caching with o frozen version */
|
|
||||||
/*
|
|
||||||
if(ob->pd && ob->pd->deflect) {
|
|
||||||
ob->sumohandle=ccd_mesh_make_self(ob);
|
|
||||||
} no self intersection test yet*/
|
|
||||||
/* if vertexowner is given we don't want to check collision with owner object */
|
/* if vertexowner is given we don't want to check collision with owner object */
|
||||||
base = base->next;
|
base = base->next;
|
||||||
continue;
|
continue;
|
||||||
@ -558,7 +547,6 @@ static void add_2nd_order_roller(Object *ob,float stiffness,int *counter, int ad
|
|||||||
int a,b,c,notthis,v0;
|
int a,b,c,notthis,v0;
|
||||||
if (!sb->bspring){return;} /* we are 2nd order here so 1rst should have been build :) */
|
if (!sb->bspring){return;} /* we are 2nd order here so 1rst should have been build :) */
|
||||||
/* first run counting second run adding */
|
/* first run counting second run adding */
|
||||||
/*run all body points*/
|
|
||||||
*counter = 0;
|
*counter = 0;
|
||||||
if (addsprings) bs3 = ob->soft->bspring+ob->soft->totspring;
|
if (addsprings) bs3 = ob->soft->bspring+ob->soft->totspring;
|
||||||
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
|
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
|
||||||
@ -619,9 +607,8 @@ static void add_2nd_order_springs(Object *ob,float stiffness)
|
|||||||
int counter = 0;
|
int counter = 0;
|
||||||
BodySpring *bs_new;
|
BodySpring *bs_new;
|
||||||
|
|
||||||
add_2nd_order_roller(ob,stiffness,&counter,0);
|
add_2nd_order_roller(ob,stiffness,&counter,0); /* counting */
|
||||||
if (counter) {
|
if (counter) {
|
||||||
/* printf("Added %d springs \n", counter); */
|
|
||||||
/* resize spring-array to hold additional springs */
|
/* resize spring-array to hold additional springs */
|
||||||
bs_new= MEM_callocN( (ob->soft->totspring + counter )*sizeof(BodySpring), "bodyspring");
|
bs_new= MEM_callocN( (ob->soft->totspring + counter )*sizeof(BodySpring), "bodyspring");
|
||||||
memcpy(bs_new,ob->soft->bspring,(ob->soft->totspring )*sizeof(BodySpring));
|
memcpy(bs_new,ob->soft->bspring,(ob->soft->totspring )*sizeof(BodySpring));
|
||||||
@ -630,11 +617,9 @@ static void add_2nd_order_springs(Object *ob,float stiffness)
|
|||||||
MEM_freeN(ob->soft->bspring);
|
MEM_freeN(ob->soft->bspring);
|
||||||
ob->soft->bspring = bs_new;
|
ob->soft->bspring = bs_new;
|
||||||
|
|
||||||
|
add_2nd_order_roller(ob,stiffness,&counter,1); /* adding */
|
||||||
add_2nd_order_roller(ob,stiffness,&counter,1);
|
|
||||||
ob->soft->totspring +=counter ;
|
ob->soft->totspring +=counter ;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_bp_springlist(BodyPoint *bp,int springID)
|
static void add_bp_springlist(BodyPoint *bp,int springID)
|
||||||
@ -683,7 +668,6 @@ static void build_bps_springlist(Object *ob)
|
|||||||
add_bp_springlist(bp,sb->totspring -b);
|
add_bp_springlist(bp,sb->totspring -b);
|
||||||
}
|
}
|
||||||
}/*for springs*/
|
}/*for springs*/
|
||||||
/* if (bp->nofsprings) printf(" node %d has %d spring links\n",a,bp->nofsprings);*/
|
|
||||||
}/*for bp*/
|
}/*for bp*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -732,7 +716,6 @@ static void calculate_collision_balls(Object *ob)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else bp->colball=0;
|
else bp->colball=0;
|
||||||
/* printf("CB %f \n",bp->colball); */
|
|
||||||
}/*for bp*/
|
}/*for bp*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,6 +754,8 @@ static void renew_softbody(Object *ob, int totpoint, int totspring)
|
|||||||
bp->nofsprings= 0;
|
bp->nofsprings= 0;
|
||||||
bp->springs= NULL;
|
bp->springs= NULL;
|
||||||
bp->contactfrict = 0.0f;
|
bp->contactfrict = 0.0f;
|
||||||
|
bp->colball = 0.0f;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -854,9 +839,7 @@ static void Vec3PlusStVec(float *v, float s, float *v1)
|
|||||||
v[2] += s*v1[2];
|
v[2] += s*v1[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BEGIN the spring external section*/
|
/* +++ the spring external section*/
|
||||||
|
|
||||||
//#if (0)
|
|
||||||
|
|
||||||
int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp,
|
int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp,
|
||||||
float force[3], unsigned int par_layer,struct Object *vertexowner)
|
float force[3], unsigned int par_layer,struct Object *vertexowner)
|
||||||
@ -946,8 +929,6 @@ int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* 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);
|
||||||
@ -998,8 +979,6 @@ int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp
|
|||||||
return deflected;
|
return deflected;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
|
|
||||||
void scan_for_ext_spring_forces(Object *ob)
|
void scan_for_ext_spring_forces(Object *ob)
|
||||||
{
|
{
|
||||||
@ -1015,53 +994,57 @@ void scan_for_ext_spring_forces(Object *ob)
|
|||||||
BodySpring *bs = &sb->bspring[a];
|
BodySpring *bs = &sb->bspring[a];
|
||||||
bs->ext_force[0]=bs->ext_force[1]=bs->ext_force[2]=0.0f;
|
bs->ext_force[0]=bs->ext_force[1]=bs->ext_force[2]=0.0f;
|
||||||
feedback[0]=feedback[1]=feedback[2]=0.0f;
|
feedback[0]=feedback[1]=feedback[2]=0.0f;
|
||||||
bs->flag &= ~BSF_INTERSECT;
|
bs->flag &= ~BSF_INTERSECT;
|
||||||
|
|
||||||
/* +++ springs colliding */
|
|
||||||
if (bs->order ==1){
|
if (bs->order ==1){
|
||||||
if ( sb_detect_edge_collisionCached (sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos,
|
/* +++ springs colliding */
|
||||||
&damp,feedback,ob->lay,ob)){
|
if (ob->softflag & OB_SB_EDGECOLL){
|
||||||
VecAddf(bs->ext_force,bs->ext_force,feedback);
|
if ( sb_detect_edge_collisionCached (sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos,
|
||||||
bs->flag |= BSF_INTERSECT;
|
&damp,feedback,ob->lay,ob)){
|
||||||
|
VecAddf(bs->ext_force,bs->ext_force,feedback);
|
||||||
}
|
bs->flag |= BSF_INTERSECT;
|
||||||
/* ---- springs colliding */
|
|
||||||
|
|
||||||
/* +++ springs seeing wind ... n stuff depending on their orientation*/
|
}
|
||||||
|
}
|
||||||
|
/* ---- springs colliding */
|
||||||
|
|
||||||
|
/* +++ springs seeing wind ... n stuff depending on their orientation*/
|
||||||
|
/* note we don't use sb->mediafrict but use sb->aeroedge for magnitude of effect*/
|
||||||
if(sb->aeroedge){
|
if(sb->aeroedge){
|
||||||
float vel[3],sp[3],pr[3],force[3];
|
float vel[3],sp[3],pr[3],force[3];
|
||||||
float f,windfactor = 1.0f;
|
float f,windfactor = 1.0f;
|
||||||
/*see if we have wind*/
|
/*see if we have wind*/
|
||||||
if(do_effector) {
|
if(do_effector) {
|
||||||
float speed[3],pos[3];
|
float speed[3],pos[3];
|
||||||
VecMidf(pos, sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos);
|
VecMidf(pos, sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos);
|
||||||
VecMidf(vel, sb->bpoint[bs->v1].vec , sb->bpoint[bs->v2].vec);
|
VecMidf(vel, sb->bpoint[bs->v1].vec , sb->bpoint[bs->v2].vec);
|
||||||
pdDoEffectors(do_effector, pos, force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
|
pdDoEffectors(do_effector, pos, force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
|
||||||
VecMulf(speed,windfactor); /*oh_ole*/
|
VecMulf(speed,windfactor);
|
||||||
VecAddf(vel,vel,speed);
|
VecAddf(vel,vel,speed);
|
||||||
}
|
}
|
||||||
/* media in rest */
|
/* media in rest */
|
||||||
else{
|
else{
|
||||||
VECADD(vel, sb->bpoint[bs->v1].vec , sb->bpoint[bs->v2].vec);
|
VECADD(vel, sb->bpoint[bs->v1].vec , sb->bpoint[bs->v2].vec);
|
||||||
}
|
}
|
||||||
f = Normalise(vel);
|
f = Normalise(vel);
|
||||||
f = -0.0001f*f*f*sb->aeroedge;
|
f = -0.0001f*f*f*sb->aeroedge;
|
||||||
|
/* todo add a nice angle dependant function */
|
||||||
|
/* look up one at bergman scheafer */
|
||||||
|
|
||||||
VECSUB(sp, sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos);
|
VECSUB(sp, sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos);
|
||||||
Projf(pr,vel,sp);
|
Projf(pr,vel,sp);
|
||||||
VECSUB(vel,vel,pr);
|
VECSUB(vel,vel,pr);
|
||||||
Normalise(vel);
|
Normalise(vel);
|
||||||
Vec3PlusStVec(bs->ext_force,f,vel);
|
Vec3PlusStVec(bs->ext_force,f,vel);
|
||||||
}
|
}
|
||||||
|
/* --- springs seeing wind */
|
||||||
/* --- springs seeing wind */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(do_effector)
|
if(do_effector)
|
||||||
pdEndEffectors(do_effector);
|
pdEndEffectors(do_effector);
|
||||||
}
|
}
|
||||||
/* END the spring external section*/
|
/* --- the spring external section*/
|
||||||
|
|
||||||
int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *damp,
|
int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *damp,
|
||||||
float force[3], unsigned int par_layer,struct Object *vertexowner)
|
float force[3], unsigned int par_layer,struct Object *vertexowner)
|
||||||
@ -1157,8 +1140,6 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* 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);
|
||||||
@ -1203,7 +1184,6 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
|
|||||||
mface++;
|
mface++;
|
||||||
mima++;
|
mima++;
|
||||||
}/* while a */
|
}/* while a */
|
||||||
/* give it away */
|
|
||||||
} /* if(ob->pd && ob->pd->deflect) */
|
} /* if(ob->pd && ob->pd->deflect) */
|
||||||
}/* if (base->object->type==OB_MESH && (base->lay & par_layer)) { */
|
}/* if (base->object->type==OB_MESH && (base->lay & par_layer)) { */
|
||||||
base = base->next;
|
base = base->next;
|
||||||
@ -1249,7 +1229,7 @@ static void softbody_calc_forces(Object *ob, float forcetime)
|
|||||||
ListBase *do_effector;
|
ListBase *do_effector;
|
||||||
float iks, ks, kd, gravity, actspringlen, forcefactor, sd[3];
|
float iks, ks, kd, gravity, actspringlen, forcefactor, sd[3];
|
||||||
float fieldfactor = 1000.0f, windfactor = 250.0f;
|
float fieldfactor = 1000.0f, windfactor = 250.0f;
|
||||||
int a, b, do_deflector,do_selfcollision,do_springcollision;
|
int a, b, do_deflector,do_selfcollision,do_springcollision,do_aero;
|
||||||
|
|
||||||
/* clear forces */
|
/* clear forces */
|
||||||
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
|
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
|
||||||
@ -1258,18 +1238,19 @@ static void softbody_calc_forces(Object *ob, float forcetime)
|
|||||||
|
|
||||||
gravity = sb->grav * sb_grav_force_scale(ob);
|
gravity = sb->grav * sb_grav_force_scale(ob);
|
||||||
|
|
||||||
/* check! */
|
/* check conditions for various options */
|
||||||
do_deflector= is_there_deflection(ob->lay);
|
do_deflector= is_there_deflection(ob->lay);
|
||||||
do_effector= pdInitEffectors(ob,NULL);
|
do_effector= pdInitEffectors(ob,NULL);
|
||||||
do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF));
|
do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF));
|
||||||
do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
|
do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
|
||||||
|
do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES));
|
||||||
|
|
||||||
iks = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */
|
iks = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */
|
||||||
bproot= sb->bpoint; /* need this for proper spring addressing */
|
bproot= sb->bpoint; /* need this for proper spring addressing */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (do_springcollision) scan_for_ext_spring_forces(ob);
|
if (do_springcollision || do_aero) scan_for_ext_spring_forces(ob);
|
||||||
|
|
||||||
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
|
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
|
||||||
/* naive ball self collision */
|
/* naive ball self collision */
|
||||||
@ -1284,12 +1265,12 @@ static void softbody_calc_forces(Object *ob, float forcetime)
|
|||||||
float compare;
|
float compare;
|
||||||
|
|
||||||
for(c=sb->totpoint, obp= sb->bpoint; c>0; c--, obp++) {
|
for(c=sb->totpoint, obp= sb->bpoint; c>0; c--, obp++) {
|
||||||
if (c < a ) continue; /* exploit force(a,b) == force(b,a) part1/2 */
|
if (c < a ) continue; /* exploit force(a,b) == -force(b,a) part1/2 */
|
||||||
compare = (obp->colball + bp->colball);
|
compare = (obp->colball + bp->colball);
|
||||||
VecSubf(def, bp->pos, obp->pos);
|
VecSubf(def, bp->pos, obp->pos);
|
||||||
distance = Normalise(def);
|
distance = Normalise(def);
|
||||||
if (distance < compare ){
|
if (distance < compare ){
|
||||||
/* exclude body points attached with a spring */
|
/* exclude body points attached with a spring */
|
||||||
attached = 0;
|
attached = 0;
|
||||||
for(b=obp->nofsprings;b>0;b--){
|
for(b=obp->nofsprings;b>0;b--){
|
||||||
bs = sb->bspring + obp->springs[b-1];
|
bs = sb->bspring + obp->springs[b-1];
|
||||||
@ -1298,37 +1279,26 @@ static void softbody_calc_forces(Object *ob, float forcetime)
|
|||||||
continue;}
|
continue;}
|
||||||
}
|
}
|
||||||
if (!attached){
|
if (!attached){
|
||||||
/* would need another UI parameter defining fricton on self contact */
|
|
||||||
float ccfriction = sb->balldamp;
|
|
||||||
float f = tune/(distance) + tune/(compare*compare)*distance - 2.0f*tune/compare ;
|
float f = tune/(distance) + tune/(compare*compare)*distance - 2.0f*tune/compare ;
|
||||||
|
|
||||||
VecMidf(velcenter, bp->vec, obp->vec);
|
VecMidf(velcenter, bp->vec, obp->vec);
|
||||||
VecSubf(dvel,velcenter,bp->vec);
|
VecSubf(dvel,velcenter,bp->vec);
|
||||||
VecMulf(dvel,sb->nodemass);
|
VecMulf(dvel,sb->nodemass);
|
||||||
|
|
||||||
Vec3PlusStVec(bp->force,ccfriction,dvel);
|
Vec3PlusStVec(bp->force,sb->balldamp,dvel);
|
||||||
Vec3PlusStVec(bp->force,f*(1.0f-ccfriction),def);
|
Vec3PlusStVec(bp->force,f*(1.0f-sb->balldamp),def);
|
||||||
/* exploit force(a,b) == force(b,a) part2/2 */
|
/* exploit force(a,b) == -force(b,a) part2/2 */
|
||||||
|
VecSubf(dvel,velcenter,obp->vec);
|
||||||
VecSubf(dvel,velcenter,obp->vec);
|
VecMulf(dvel,sb->nodemass);
|
||||||
VecMulf(dvel,sb->nodemass);
|
|
||||||
|
|
||||||
Vec3PlusStVec(obp->force,ccfriction,dvel);
|
Vec3PlusStVec(obp->force,sb->balldamp,dvel);
|
||||||
Vec3PlusStVec(obp->force,-f*(1.0f-ccfriction),def);
|
Vec3PlusStVec(obp->force,-f*(1.0f-sb->balldamp),def);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//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 */
|
/* naive ball self collision done */
|
||||||
|
|
||||||
if(bp->goal < SOFTGOALSNAP){ /* ommit this bp when it snaps */
|
if(bp->goal < SOFTGOALSNAP){ /* ommit this bp when it snaps */
|
||||||
float auxvect[3];
|
float auxvect[3];
|
||||||
@ -1372,13 +1342,11 @@ static void softbody_calc_forces(Object *ob, float forcetime)
|
|||||||
|
|
||||||
pdDoEffectors(do_effector, bp->pos, force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
|
pdDoEffectors(do_effector, bp->pos, force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
|
||||||
|
|
||||||
/* note: now we have wind as motion of media, so we can do anisotropic stuff here, */
|
|
||||||
/* if we had vertex normals here(BM) */
|
|
||||||
/* apply forcefield*/
|
/* apply forcefield*/
|
||||||
VecMulf(force,fieldfactor* eval_sb_fric_force_scale);
|
VecMulf(force,fieldfactor* eval_sb_fric_force_scale);
|
||||||
VECADD(bp->force, bp->force, force);
|
VECADD(bp->force, bp->force, force);
|
||||||
|
|
||||||
/* friction in moving media */
|
/* BP friction in moving media */
|
||||||
kd= sb->mediafrict* eval_sb_fric_force_scale;
|
kd= sb->mediafrict* eval_sb_fric_force_scale;
|
||||||
bp->force[0] -= kd * (bp->vec[0] + windfactor*speed[0]/eval_sb_fric_force_scale);
|
bp->force[0] -= kd * (bp->vec[0] + windfactor*speed[0]/eval_sb_fric_force_scale);
|
||||||
bp->force[1] -= kd * (bp->vec[1] + windfactor*speed[1]/eval_sb_fric_force_scale);
|
bp->force[1] -= kd * (bp->vec[1] + windfactor*speed[1]/eval_sb_fric_force_scale);
|
||||||
@ -1387,7 +1355,7 @@ static void softbody_calc_forces(Object *ob, float forcetime)
|
|||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* friction in media (not) moving*/
|
/* BP friction in media (not) moving*/
|
||||||
kd= sb->mediafrict* sb_fric_force_scale(ob);
|
kd= sb->mediafrict* sb_fric_force_scale(ob);
|
||||||
/* assume it to be proportional to actual velocity */
|
/* assume it to be proportional to actual velocity */
|
||||||
bp->force[0]-= bp->vec[0]*kd;
|
bp->force[0]-= bp->vec[0]*kd;
|
||||||
@ -1396,11 +1364,7 @@ static void softbody_calc_forces(Object *ob, float forcetime)
|
|||||||
/* friction in media done */
|
/* friction in media done */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*other forces*/
|
/* +++cached collision targets */
|
||||||
/* this is the place where other forces can be added
|
|
||||||
yes, constraints and collision stuff should go here too (read baraff papers on that!)
|
|
||||||
*/
|
|
||||||
/* moving collision targets */
|
|
||||||
if(do_deflector) {
|
if(do_deflector) {
|
||||||
float defforce[3] = {0.0f,0.0f,0.0f}, collisionpos[3],facenormal[3], cf = 1.0f;
|
float defforce[3] = {0.0f,0.0f,0.0f}, collisionpos[3],facenormal[3], cf = 1.0f;
|
||||||
kd = 1.0f;
|
kd = 1.0f;
|
||||||
@ -1412,27 +1376,19 @@ static void softbody_calc_forces(Object *ob, float forcetime)
|
|||||||
else{
|
else{
|
||||||
bp->contactfrict = 0.0f;
|
bp->contactfrict = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bp->contactfrict = 0.0f;
|
bp->contactfrict = 0.0f;
|
||||||
}
|
}
|
||||||
|
/* ---cached collision targets */
|
||||||
|
|
||||||
/*other forces done*/
|
/* +++springs */
|
||||||
/* nice things could be done with anisotropic friction
|
|
||||||
like wind/air resistance in normal direction
|
|
||||||
--> having a piece of cloth sailing down
|
|
||||||
but this needs to have a *valid* vertex normal
|
|
||||||
*valid* means to be calulated on time axis
|
|
||||||
hrms .. may be a rough one could be used as well .. let's see
|
|
||||||
*/
|
|
||||||
|
|
||||||
if(ob->softflag & OB_SB_EDGES) {
|
if(ob->softflag & OB_SB_EDGES) {
|
||||||
if (sb->bspring){ /* spring list exists at all ? */
|
if (sb->bspring){ /* spring list exists at all ? */
|
||||||
for(b=bp->nofsprings;b>0;b--){
|
for(b=bp->nofsprings;b>0;b--){
|
||||||
bs = sb->bspring + bp->springs[b-1];
|
bs = sb->bspring + bp->springs[b-1];
|
||||||
if (do_springcollision){
|
if (do_springcollision || do_aero){
|
||||||
VecAddf(bp->force,bp->force,bs->ext_force);
|
VecAddf(bp->force,bp->force,bs->ext_force);
|
||||||
if (bs->flag & BSF_INTERSECT)
|
if (bs->flag & BSF_INTERSECT)
|
||||||
bp->contactfrict = 0.9f; /* another ad hoc magic */
|
bp->contactfrict = 0.9f; /* another ad hoc magic */
|
||||||
@ -1485,12 +1441,12 @@ static void softbody_calc_forces(Object *ob, float forcetime)
|
|||||||
}/* loop springs */
|
}/* loop springs */
|
||||||
}/* existing spring list */
|
}/* existing spring list */
|
||||||
}/*any edges*/
|
}/*any edges*/
|
||||||
|
/* ---springs */
|
||||||
}/*omit on snap */
|
}/*omit on snap */
|
||||||
}/*loop all bp's*/
|
}/*loop all bp's*/
|
||||||
/* cleanup */
|
|
||||||
if(do_effector)
|
|
||||||
pdEndEffectors(do_effector);
|
|
||||||
|
|
||||||
|
/* cleanup */
|
||||||
|
if(do_effector) pdEndEffectors(do_effector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1563,7 +1519,8 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
|
|||||||
maxerr = MAX2(maxerr,ABS(dx[0] - bp->prevdx[0]));
|
maxerr = MAX2(maxerr,ABS(dx[0] - bp->prevdx[0]));
|
||||||
maxerr = MAX2(maxerr,ABS(dx[1] - bp->prevdx[1]));
|
maxerr = MAX2(maxerr,ABS(dx[1] - bp->prevdx[1]));
|
||||||
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* */
|
/* weak point: not knowing anything about targets dynamics we assume it to be resting */
|
||||||
|
/* while inside collision target .. make movement more *viscous* */
|
||||||
if (bp->contactfrict > 0.0f){
|
if (bp->contactfrict > 0.0f){
|
||||||
bp->vec[0] *= (1.0f - bp->contactfrict);
|
bp->vec[0] *= (1.0f - bp->contactfrict);
|
||||||
bp->vec[1] *= (1.0f - bp->contactfrict);
|
bp->vec[1] *= (1.0f - bp->contactfrict);
|
||||||
|
@ -2329,11 +2329,10 @@ static void object_softbodies(Object *ob)
|
|||||||
uiDefButS(block, ROW, B_DIFF, "Min",130,150,60,20, &sb->sbc_mode, 4.0,(float)2, 0, 0, "Minimal Spring lenght * Ball Size");
|
uiDefButS(block, ROW, B_DIFF, "Min",130,150,60,20, &sb->sbc_mode, 4.0,(float)2, 0, 0, "Minimal Spring lenght * Ball Size");
|
||||||
uiDefButS(block, ROW, B_DIFF, "Max",190,150,60,20, &sb->sbc_mode, 4.0,(float)3, 0, 0, "Maximal Spring lenght * Ball Size");
|
uiDefButS(block, ROW, B_DIFF, "Max",190,150,60,20, &sb->sbc_mode, 4.0,(float)3, 0, 0, "Maximal Spring lenght * Ball Size");
|
||||||
uiDefButS(block, ROW, B_DIFF, "AvMiMa",250,150,60,20, &sb->sbc_mode, 4.0,(float)4, 0, 0, "(Min+Max)/2 * Ball Size");
|
uiDefButS(block, ROW, B_DIFF, "AvMiMa",250,150,60,20, &sb->sbc_mode, 4.0,(float)4, 0, 0, "(Min+Max)/2 * Ball Size");
|
||||||
uiDefButF(block, NUM, B_DIFF, "B Stiff:", 10,130,150,20, &sb->ballstiff, 0.001, 100.0, 10, 0, "");
|
uiDefButF(block, NUM, B_DIFF, "B Stiff:", 10,130,150,20, &sb->ballstiff, 0.001, 100.0, 10, 0, "Ball inflating presure");
|
||||||
uiDefButF(block, NUM, B_DIFF, "B Damp:", 160,130,150,20, &sb->balldamp, 0.001, 1.0, 10, 0, "");
|
uiDefButF(block, NUM, B_DIFF, "B Damp:", 160,130,150,20, &sb->balldamp, 0.001, 1.0, 10, 0, "Blending to inelastic collision");
|
||||||
uiDefButS(block, NUM, B_DIFF, "Aero:", 160,110,150,20, &sb->aeroedge, 0.00, 30000.0, 10, 0, "");
|
|
||||||
uiBlockEndAlign(block);
|
uiBlockEndAlign(block);
|
||||||
|
uiDefButS(block, NUM, B_DIFF, "Aero:", 10,100,150,20, &sb->aeroedge, 0.00, 30000.0, 10, 0, "Make edges 'sail'");
|
||||||
}
|
}
|
||||||
/* OTHER OBJECTS COLLISION STUFF */
|
/* OTHER OBJECTS COLLISION STUFF */
|
||||||
if (ob->type==OB_MESH){
|
if (ob->type==OB_MESH){
|
||||||
|
Loading…
Reference in New Issue
Block a user