forked from bartvdbraak/blender
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:
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);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1032,9 +859,8 @@ 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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user