Softbody improvements, thanks to Nathanael

This commit is contained in:
erwin.coumans
2008-05-17 12:39:16 +00:00
parent 649709dc2d
commit d9e7058ff2
12 changed files with 2098 additions and 1828 deletions

View File

@@ -99,13 +99,32 @@ void SoftDemo::clientMoveAndDisplay()
float dt = getDeltaTimeMicroseconds() * 0.000001f;
// printf("dt = %f: ",dt);
float dt = 1.0/60.;
if (m_dynamicsWorld)
{
if(m_drag)
{
const int x=m_lastmousepos[0];
const int y=m_lastmousepos[1];
const btVector3 rayFrom=m_cameraPosition;
const btVector3 rayTo=getRayTo(x,y);
const btVector3 rayDir=(rayTo-rayFrom).normalized();
const btVector3 N=(m_cameraTargetPosition-m_cameraPosition).normalized();
const btScalar O=dot(m_impact,N);
const btScalar den=dot(N,rayDir);
if((den*den)>0)
{
const btScalar num=O-dot(N,rayFrom);
const btScalar hit=num/den;
if((hit>0)&&(hit<1500))
{
m_goal=rayFrom+rayDir*hit;
}
}
m_node->m_v+=(m_goal-m_node->m_x)/dt;
}
#define FIXED_STEP
#ifdef FIXED_STEP
m_dynamicsWorld->stepSimulation(dt=1.0f/60.f,0);
@@ -137,6 +156,10 @@ void SoftDemo::clientMoveAndDisplay()
#endif
if(m_drag)
{
m_node->m_v*=0;
}
m_softBodyWorldInfo.m_sparsesdf.GarbageCollect();
@@ -670,6 +693,28 @@ static void Init_Sticks(SoftDemo* pdemo)
Ctor_BigBall(pdemo);
}
//
// Bending
//
static void Init_Bending(SoftDemo* pdemo)
{
//TRACEDEMO
const btScalar s=4;
const btVector3 x[]={ btVector3(-s,0,-s),
btVector3(+s,0,-s),
btVector3(+s,0,+s),
btVector3(-s,0,+s)};
const btScalar m[]={ 0,0,0,1};
btSoftBody* psb=new btSoftBody(&pdemo->m_softBodyWorldInfo,4,x,m);
psb->appendLink(0,1);
psb->appendLink(1,2);
psb->appendLink(2,3);
psb->appendLink(3,0);
psb->appendLink(0,2);
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
}
//
// 100kg cloth locked at corners, 10 falling 10kg rb's.
//
@@ -715,6 +760,7 @@ static void Init_Bunny(SoftDemo* pdemo)
psb->scale(btVector3(6,6,6));
psb->setTotalMass(100,true);
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
pdemo->m_cutting=true;
}
@@ -756,6 +802,7 @@ static void Init_Torus(SoftDemo* pdemo)
psb->scale(btVector3(2,2,2));
psb->setTotalMass(50,true);
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
pdemo->m_cutting=true;
}
@@ -798,155 +845,6 @@ static void Init_Cutting1(SoftDemo* pdemo)
pdemo->m_cutting=true;
}
#ifdef BT_SOFTBODY_USE_STL
//
// TetraBunny
//
static void Init_TetraBunny(SoftDemo* pdemo)
{
btSoftBody* psb=btSoftBodyHelpers::CreateFromTetGenData(pdemo->m_softBodyWorldInfo,
TetraBunny::getElements(),
0,
TetraBunny::getNodes(),
false,true,true);
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
psb->rotate(btQuaternion(SIMD_PI/2,0,0));
psb->setVolumeMass(150);
psb->m_cfg.piterations=2;
pdemo->m_cutting=true;
}
//
// TetraCube
//
static void Init_TetraCube(SoftDemo* pdemo)
{
btSoftBody* psb=btSoftBodyHelpers::CreateFromTetGenData(pdemo->m_softBodyWorldInfo,
TetraCube::getElements(),
0,
TetraCube::getNodes(),
false,true,true);
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
psb->scale(btVector3(4,4,4));
psb->translate(btVector3(0,5,0));
psb->setVolumeMass(300);
psb->setMass(0,0);
/*psb->setMass(10,0);
psb->setMass(20,0);*/
psb->m_cfg.piterations=1;
//psb->m_materials[0]->m_kLST=0.05;
pdemo->m_cutting=true;
}
#endif //BT_SOFTBODY_USE_STL
//
// Tetra
//
static void Init_Tetra(SoftDemo* pdemo)
{
//TRACEDEMO
#if 0
{
btVector3 pts[]={ btVector3(-1,-1,-1),
btVector3(+1,-1,-1),
btVector3(+1,+1,-1),
btVector3(-1,+1,-1),
btVector3(-1,-1,+1),
btVector3(+1,-1,+1),
btVector3(+1,+1,+1),
btVector3(-1,+1,+1)};
btSoftBody* psb=btSoftBodyHelpers::CreateFromConvexHull(pdemo->m_softBodyWorldInfo,pts,8);
btSoftBodyHelpers::ExportAsSMeshFile(psb,"C:/HomeH/Oss/tetgen/Release/cube.smesh");
delete psb;
/*btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh( pdemo->m_softBodyWorldInfo,gVerticesBunny,
&gIndicesBunny[0][0],
BUNNY_NUM_TRIANGLES);
psb->scale(btVector3(6,6,6));
btSoftBodyHelpers::ExportAsSMeshFile(psb,"C:/HomeH/Oss/tetgen/Release/bunny.smesh");
delete psb;*/
}
btSoftBody* psb=btSoftBodyHelpers::CreateFromTetGenFile(pdemo->m_softBodyWorldInfo,
/*"C:/HomeH/Oss/tetgen/Release/bunny.1.ele",
"C:/HomeH/Oss/tetgen/Release/bunny.1.face",
"C:/HomeH/Oss/tetgen/Release/bunny.1.node",*/
"C:/HomeH/Oss/tetgen/Release/cube.1.ele",
0/*"C:/HomeH/Oss/tetgen/Release/cube.1.face"*/,
"C:/HomeH/Oss/tetgen/Release/cube.1.node",
true,true);
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
psb->scale(btVector3(4,4,4));
/*psb->rotate(btQuaternion(SIMD_PI/4,SIMD_PI/4,0));
psb->translate(btVector3(0,10,0));*/
psb->setVolumeMass(30);
psb->m_cfg.piterations=1;
psb->m_cfg.kKHR=1;
//psb->addVelocity(btVector3(0,50,0));
//psb->m_tetras.clear();
ImplicitSphere fnc;
fnc.center = btVector3(4,4,4);
fnc.radius = 4;
psb->refine(&fnc,0.001,true);
//psb->m_tetras.clear();
printf("Nodes: %u\r\n",psb->m_nodes.size());
printf("Links: %u\r\n",psb->m_links.size());
printf("Faces: %u\r\n",psb->m_faces.size());
printf("Tetras: %u\r\n",psb->m_tetras.size());
#else
#if 1
const btScalar s=4;
const int r=32;
const btVector3 p[]={ btVector3(+s,0,-s),
btVector3(-s,0,-s),
btVector3(+s,0,+s),
btVector3(-s,0,+s)};
btSoftBody* psb=btSoftBodyHelpers::CreatePatch(pdemo->m_softBodyWorldInfo,p[0],p[1],p[2],p[3],r,r,1+2+4+8,true);
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
psb->m_cfg.piterations=2;
/*ImplicitSphere fnc;
fnc.center = btVector3(0,0,0);
fnc.radius = 1.5;
psb->refine(&fnc,0.001,true);*/
//psb->m_faces.clear();
/*fnc.center = btVector3(4,0,4);
fnc.radius = 2;
psb->refine(&fnc,0.001,true);*/
#else
const btScalar s=4;
const btVector3 p[]={ btVector3(+s,-s,0),
btVector3(-s,0,0),
btVector3(0,0,+s),
btVector3(0,+s,0)};
btSoftBody* psb=new btSoftBody(&pdemo->m_softBodyWorldInfo,4,p,0);
psb->appendTetra(0,1,2,3);
psb->appendLink(0,1,1,btSoftBody::eLType::Structural);
psb->appendLink(1,2,1,btSoftBody::eLType::Structural);
psb->appendLink(2,0,1,btSoftBody::eLType::Structural);
psb->appendLink(0,3,1,btSoftBody::eLType::Structural);
psb->appendLink(1,3,1,btSoftBody::eLType::Structural);
psb->appendLink(2,3,1,btSoftBody::eLType::Structural);
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
psb->setSolver(btSoftBody::eSolverPresets::Velocities);
psb->m_cfg.viterations=1;
psb->m_cfg.diterations=1;
psb->m_cfg.kDF=0;
psb->m_cfg.kLST=0.000001;
//psb1->m_cfg.diterations=1;
/*btSoftBody* psb0=btSoftBodyHelpers::CreateRope( pdemo->m_softBodyWorldInfo,
btVector3(0,0,0),btVector3(5,0,0),16,1);
pdemo->getSoftDynamicsWorld()->addSoftBody(psb0);
btSoftBody* psb1=btSoftBodyHelpers::CreateRope( pdemo->m_softBodyWorldInfo,
btVector3(0,0,2),btVector3(5,0,2),16,1);
psb1->m_cfg.viterations=1;
psb1->m_cfg.diterations=1;
psb1->setSolver(btSoftBody::eSolverPresets::Velocities);
pdemo->getSoftDynamicsWorld()->addSoftBody(psb1);*/
#endif
#endif
pdemo->toggleIdle();
}
unsigned current_demo=0;
void SoftDemo::clientResetScene()
@@ -977,11 +875,6 @@ void SoftDemo::clientResetScene()
void (*demofncs[])(SoftDemo*)=
{
Init_Cloth,
Init_Cutting1,
#ifdef BT_SOFTBODY_USE_STL
Init_TetraBunny,
Init_TetraCube,
#endif //BT_SOFTBODY_USE_STL
Init_Pressure,
Init_Volume,
Init_Ropes,
@@ -998,6 +891,7 @@ void SoftDemo::clientResetScene()
Init_TorusMatch,
Init_Bunny,
Init_BunnyMatch,
Init_Cutting1,
};
current_demo=current_demo%(sizeof(demofncs)/sizeof(demofncs[0]));
@@ -1012,6 +906,7 @@ void SoftDemo::clientResetScene()
m_autocam = false;
m_raycast = false;
m_cutting = false;
m_results.time = SIMD_INFINITY;
demofncs[current_demo](this);
}
@@ -1158,52 +1053,105 @@ void SoftDemo::keyboardCallback(unsigned char key, int x, int y)
}
//
void SoftDemo::mouseFunc(int button, int state, int x, int y)
void SoftDemo::mouseMotionFunc(int x,int y)
{
if(m_cutting&&(state==0)&&(button==0))
if(m_node&&(m_results.time<SIMD_INFINITY))
{
const btVector3 rayFrom=m_cameraPosition;
const btVector3 rayTo=getRayTo(x,y);
const btVector3 rayDir=(rayTo-rayFrom).normalized();
btSoftBodyArray& sbs=getSoftDynamicsWorld()->getSoftBodyArray();
btSoftBody::sRayCast results;
results.time=SIMD_INFINITY;
for(int ib=0;ib<sbs.size();++ib)
if(!m_drag)
{
btSoftBody* psb=sbs[ib];
btSoftBody::sRayCast res;
if(psb->rayCast(rayFrom,rayDir,res,results.time))
#define SQ(_x_) (_x_)*(_x_)
if((SQ(x-m_lastmousepos[0])+SQ(y-m_lastmousepos[1]))>6)
{
results=res;
m_drag=true;
}
#undef SQ
}
if(results.time<SIMD_INFINITY)
if(m_drag)
{
#if 0
const btVector3 x=rayFrom+rayDir*results.time;
const btSoftBody::Face& f=results.body->m_faces[results.index];
btScalar bestarea=SIMD_INFINITY;
const btSoftBody::Node* n[2]={0,0};
for(int i=2,j=0;j<3;i=j++)
{
const btScalar a2=cross(f.m_n[i]->m_x-x,f.m_n[j]->m_x-x).length2();
if(a2<bestarea)
{
bestarea=a2;
n[0]=f.m_n[i];
n[1]=f.m_n[j];
}
}
results.body->cutLink(n[0],n[1],0.5);
#endif
ImplicitSphere isphere(rayFrom+rayDir*results.time,1);
printf("Mass before: %f\r\n",results.body->getTotalMass());
results.body->refine(&isphere,0.0001,true);
printf("Mass after: %f\r\n",results.body->getTotalMass());
return;
m_lastmousepos[0] = x;
m_lastmousepos[1] = y;
}
}
DemoApplication::mouseFunc(button,state,x,y);
else
{
DemoApplication::mouseMotionFunc(x,y);
}
}
//
void SoftDemo::mouseFunc(int button, int state, int x, int y)
{
if(button==0)
{
switch(state)
{
case 0:
{
m_results.time=SIMD_INFINITY;
DemoApplication::mouseFunc(button,state,x,y);
if(!m_pickConstraint)
{
const btVector3 rayFrom=m_cameraPosition;
const btVector3 rayTo=getRayTo(x,y);
const btVector3 rayDir=(rayTo-rayFrom).normalized();
btSoftBodyArray& sbs=getSoftDynamicsWorld()->getSoftBodyArray();
for(int ib=0;ib<sbs.size();++ib)
{
btSoftBody* psb=sbs[ib];
btSoftBody::sRayCast res;
if(psb->rayCast(rayFrom,rayDir,res,m_results.time))
{
m_results=res;
}
}
if(m_results.time<SIMD_INFINITY)
{
m_impact = rayFrom+rayDir*m_results.time;
m_drag = false;
m_lastmousepos[0] = x;
m_lastmousepos[1] = y;
m_node = 0;
switch(m_results.feature)
{
case btSoftBody::eFeature::Face:
{
btSoftBody::Face& f=m_results.body->m_faces[m_results.index];
m_node=f.m_n[0];
for(int i=1;i<3;++i)
{
if( (m_node->m_x-m_impact).length2()>
(f.m_n[i]->m_x-m_impact).length2())
{
m_node=f.m_n[i];
}
}
}
break;
}
if(m_node) m_goal=m_node->m_x;
return;
}
}
}
break;
case 1:
if((!m_drag)&&m_cutting&&(m_results.time<SIMD_INFINITY))
{
ImplicitSphere isphere(m_impact,1);
printf("Mass before: %f\r\n",m_results.body->getTotalMass());
m_results.body->refine(&isphere,0.0001,true);
printf("Mass after: %f\r\n",m_results.body->getTotalMass());
}
m_results.time=SIMD_INFINITY;
m_drag=false;
DemoApplication::mouseFunc(button,state,x,y);
break;
}
}
else
{
DemoApplication::mouseFunc(button,state,x,y);
}
}

View File

@@ -57,6 +57,12 @@ public:
bool m_raycast;
btScalar m_animtime;
btClock m_clock;
int m_lastmousepos[2];
btVector3 m_impact;
btSoftBody::sRayCast m_results;
btSoftBody::Node* m_node;
btVector3 m_goal;
bool m_drag;
//keep the collision shapes, for deletion/cleanup
@@ -80,6 +86,10 @@ public:
void exitPhysics();
SoftDemo() : m_drag(false)
{
}
virtual ~SoftDemo()
{
exitPhysics();
@@ -118,6 +128,7 @@ public:
void renderme();
void keyboardCallback(unsigned char key, int x, int y);
void mouseFunc(int button, int state, int x, int y);
void mouseMotionFunc(int x,int y);
};