Added initial broadphase support for softbody versus softbody and softbody versus rigidbody (see btSoftSoftCollisionAlgorithm and btSoftRididCollisionAlgorithm)
Added SOFTBODY_SHAPE_PROXYTYPE. Some refactoring for btSoftBody, needs more work.
This commit is contained in:
@@ -26,7 +26,8 @@ subject to the following restrictions:
|
||||
#include "../GimpactTestDemo/TorusMesh.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
#include "../../Extras/ConvexHull/btConvexHull.h"
|
||||
|
||||
#include "btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "BulletDynamics/SoftBody/btSoftBodyHelpers.h"
|
||||
|
||||
static float gCollisionMargin = 0.05f/*0.05f*/;
|
||||
#include "SoftDemo.h"
|
||||
@@ -42,8 +43,7 @@ const int maxProxies = 32766;
|
||||
const int maxOverlap = 65535;
|
||||
|
||||
//
|
||||
btSoftBody* CreateFromConvexHull( btSoftBody::ISoftBody* isoftbody,
|
||||
const btVector3* vertices,
|
||||
btSoftBody* btSoftBodyHelpers::CreateFromConvexHull(btSoftBody::btSoftBodyWorldInfo& worldInfo, const btVector3* vertices,
|
||||
int nvertices)
|
||||
{
|
||||
HullDesc hdsc(QF_TRIANGLES,nvertices,vertices);
|
||||
@@ -51,8 +51,7 @@ HullResult hres;
|
||||
HullLibrary hlib;/*??*/
|
||||
hdsc.mMaxVertices=nvertices;
|
||||
hlib.CreateConvexHull(hdsc,hres);
|
||||
btSoftBody* psb=btSoftBody::Create( isoftbody,
|
||||
(int)hres.mNumOutputVertices,
|
||||
btSoftBody* psb=new btSoftBody(worldInfo,(int)hres.mNumOutputVertices,
|
||||
hres.mOutputVertices,0);
|
||||
for(int i=0;i<(int)hres.mNumFaces;++i)
|
||||
{
|
||||
@@ -117,30 +116,15 @@ void SoftDemo::createStack( btCollisionShape* boxShape, float halfCubeSize, int
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// ISoftBody implementation
|
||||
//
|
||||
|
||||
//
|
||||
void SoftDemo::SoftBodyImpl::Attach(btSoftBody*)
|
||||
{}
|
||||
|
||||
//
|
||||
void SoftDemo::SoftBodyImpl::Detach(btSoftBody*)
|
||||
{}
|
||||
|
||||
//
|
||||
void SoftDemo::SoftBodyImpl::StartCollide(const btVector3&,const btVector3&)
|
||||
{}
|
||||
|
||||
#ifdef DHSJHDSAKJDHSJKADHSAKJDHSA
|
||||
//
|
||||
bool SoftDemo::SoftBodyImpl::CheckContactPrecise(const btVector3& x,
|
||||
btSoftBody::ISoftBody::sCti& cti)
|
||||
{
|
||||
btScalar maxdepth=0;
|
||||
btGjkEpaSolver2::sResults res;
|
||||
btDynamicsWorld* pdw=pdemo->m_dynamicsWorld;
|
||||
// btDynamicsWorld* pdw=pdemo->m_dynamicsWorld;
|
||||
|
||||
btCollisionObjectArray& coa=pdw->getCollisionObjectArray();
|
||||
for(int i=0,ni=coa.size();i<ni;++i)
|
||||
{
|
||||
@@ -165,7 +149,7 @@ return(maxdepth<0);
|
||||
|
||||
//
|
||||
bool SoftDemo::SoftBodyImpl::CheckContact( const btVector3& x,
|
||||
btSoftBody::ISoftBody::sCti& cti)
|
||||
btSoftBody::sCti& cti)
|
||||
{
|
||||
btScalar maxdepth=0;
|
||||
btGjkEpaSolver2::sResults res;
|
||||
@@ -216,6 +200,7 @@ if(water_density>0)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
extern int gNumManifold;
|
||||
@@ -267,14 +252,22 @@ void SoftDemo::clientMoveAndDisplay()
|
||||
|
||||
#endif
|
||||
|
||||
/* soft bodies */
|
||||
/* soft bodies collision detection */
|
||||
for(int ib=0;ib<m_softbodies.size();++ib)
|
||||
{
|
||||
btSoftBody* psb=m_softbodies[ib];
|
||||
// psb->updateAabb(dt);
|
||||
}
|
||||
|
||||
/* soft bodies simulation */
|
||||
for(int ib=0;ib<m_softbodies.size();++ib)
|
||||
{
|
||||
btSoftBody* psb=m_softbodies[ib];
|
||||
psb->AddVelocity(m_dynamicsWorld->getGravity()*dt);
|
||||
psb->Step(dt);
|
||||
}
|
||||
m_sparsesdf.GarbageCollect();
|
||||
|
||||
m_softBodyWorldInfo.m_sparsesdf.GarbageCollect();
|
||||
|
||||
//optional but useful: debug drawing
|
||||
|
||||
@@ -418,9 +411,10 @@ const btVector3 c[]={ p+h*btVector3(-1,-1,-1),
|
||||
p+h*btVector3(+1,-1,+1),
|
||||
p+h*btVector3(-1,+1,+1),
|
||||
p+h*btVector3(+1,+1,+1)};
|
||||
btSoftBody* psb=CreateFromConvexHull(&pdemo->m_softbodyimpl,c,8);
|
||||
btSoftBody* psb=btSoftBodyHelpers::CreateFromConvexHull(pdemo->m_softBodyWorldInfo,c,8);
|
||||
psb->GenerateBendingConstraints(2,1);
|
||||
pdemo->m_softbodies.push_back(psb);
|
||||
|
||||
return(psb);
|
||||
}
|
||||
|
||||
@@ -435,9 +429,10 @@ for(int i=0;i<np;++i)
|
||||
{
|
||||
pts.push_back(Vector3Rand()*s+p);
|
||||
}
|
||||
btSoftBody* psb=CreateFromConvexHull(&pdemo->m_softbodyimpl,&pts[0],pts.size());
|
||||
btSoftBody* psb=btSoftBodyHelpers::CreateFromConvexHull(pdemo->m_softBodyWorldInfo,&pts[0],pts.size());
|
||||
psb->GenerateBendingConstraints(2,1);
|
||||
pdemo->m_softbodies.push_back(psb);
|
||||
|
||||
return(psb);
|
||||
}
|
||||
|
||||
@@ -452,8 +447,7 @@ static void Init_Ropes(SoftDemo* pdemo)
|
||||
const int n=15;
|
||||
for(int i=0;i<n;++i)
|
||||
{
|
||||
btSoftBody* psb=CreateRope( &pdemo->m_softbodyimpl,
|
||||
btVector3(-10,0,i*0.25),
|
||||
btSoftBody* psb=btSoftBodyHelpers::CreateRope(pdemo->m_softBodyWorldInfo, btVector3(-10,0,i*0.25),
|
||||
btVector3(10,0,i*0.25),
|
||||
16,
|
||||
1+2);
|
||||
@@ -461,6 +455,7 @@ for(int i=0;i<n;++i)
|
||||
psb->m_cfg.kLST = 0.1+(i/(btScalar)(n-1))*0.9;
|
||||
psb->SetTotalMass(20);
|
||||
pdemo->m_softbodies.push_back(psb);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,8 +469,7 @@ struct Functors
|
||||
{
|
||||
static btSoftBody* CtorRope(SoftDemo* pdemo,const btVector3& p)
|
||||
{
|
||||
btSoftBody* psb=CreateRope(&pdemo->m_softbodyimpl,
|
||||
p,p+btVector3(10,0,0),8,1);
|
||||
btSoftBody* psb=btSoftBodyHelpers::CreateRope(pdemo->m_softBodyWorldInfo,p,p+btVector3(10,0,0),8,1);
|
||||
psb->m_cfg.kDF = 0;
|
||||
psb->SetTotalMass(50);
|
||||
pdemo->m_softbodies.push_back(psb);
|
||||
@@ -488,8 +482,8 @@ startTransform.setOrigin(btVector3(12,8,0));
|
||||
btRigidBody* body=pdemo->localCreateRigidBody(50,startTransform,new btBoxShape(btVector3(2,6,2)));
|
||||
btSoftBody* psb0=Functors::CtorRope(pdemo,btVector3(0,8,-1));
|
||||
btSoftBody* psb1=Functors::CtorRope(pdemo,btVector3(0,8,+1));
|
||||
psb0->AppendAnchor(psb0->m_nodes.size()-1,body);
|
||||
psb1->AppendAnchor(psb1->m_nodes.size()-1,body);
|
||||
psb0->AppendAnchor(psb0->getNodes().size()-1,body);
|
||||
psb1->AppendAnchor(psb1->getNodes().size()-1,body);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -501,12 +495,12 @@ static void Init_ClothAttach(SoftDemo* pdemo)
|
||||
const btScalar s=4;
|
||||
const btScalar h=6;
|
||||
const int r=9;
|
||||
btSoftBody* psb=CreatePatch(&pdemo->m_softbodyimpl,
|
||||
btVector3(-s,h,-s),
|
||||
btSoftBody* psb=btSoftBodyHelpers::CreatePatch(pdemo->m_softBodyWorldInfo,btVector3(-s,h,-s),
|
||||
btVector3(+s,h,-s),
|
||||
btVector3(-s,h,+s),
|
||||
btVector3(+s,h,+s),r,r,4+8,true);
|
||||
pdemo->m_softbodies.push_back(psb);
|
||||
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
startTransform.setOrigin(btVector3(0,h,-(s+3.5)));
|
||||
@@ -521,12 +515,12 @@ psb->AppendAnchor(r-1,body);
|
||||
static void Init_Impact(SoftDemo* pdemo)
|
||||
{
|
||||
//TRACEDEMO
|
||||
btSoftBody* psb=CreateRope( &pdemo->m_softbodyimpl,
|
||||
btVector3(0,0,0),
|
||||
btSoftBody* psb=btSoftBodyHelpers::CreateRope(pdemo->m_softBodyWorldInfo, btVector3(0,0,0),
|
||||
btVector3(0,-1,0),
|
||||
0,
|
||||
1);
|
||||
pdemo->m_softbodies.push_back(psb);
|
||||
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
startTransform.setOrigin(btVector3(0,20,0));
|
||||
@@ -545,8 +539,7 @@ const int segments=6;
|
||||
const int count=50;
|
||||
for(int i=0;i<count;++i)
|
||||
{
|
||||
btSoftBody* psb=CreatePatch(&pdemo->m_softbodyimpl,
|
||||
btVector3(-s,h,-s),
|
||||
btSoftBody* psb=btSoftBodyHelpers::CreatePatch(pdemo->m_softBodyWorldInfo,btVector3(-s,h,-s),
|
||||
btVector3(+s,h,-s),
|
||||
btVector3(-s,h,+s),
|
||||
btVector3(+s,h,+s),
|
||||
@@ -568,6 +561,7 @@ for(int i=0;i<count;++i)
|
||||
psb->SetTotalMass(0.1);
|
||||
psb->AddForce(btVector3(0,2,0),0);
|
||||
pdemo->m_softbodies.push_back(psb);
|
||||
|
||||
}
|
||||
pdemo->m_autocam=true;
|
||||
}
|
||||
@@ -595,8 +589,7 @@ for(int i=0,ni=20;i<ni;++i)
|
||||
static void Init_Pressure(SoftDemo* pdemo)
|
||||
{
|
||||
//TRACEDEMO
|
||||
btSoftBody* psb=CreateEllipsoid(&pdemo->m_softbodyimpl,
|
||||
btVector3(35,25,0),
|
||||
btSoftBody* psb=btSoftBodyHelpers::CreateEllipsoid(pdemo->m_softBodyWorldInfo,btVector3(35,25,0),
|
||||
btVector3(1,1,1)*3,
|
||||
512);
|
||||
psb->m_cfg.kLST = 0.1;
|
||||
@@ -604,6 +597,7 @@ psb->m_cfg.kDF = 1;
|
||||
psb->m_cfg.kPR = 2500;
|
||||
psb->SetTotalMass(30,true);
|
||||
pdemo->m_softbodies.push_back(psb);
|
||||
|
||||
Ctor_BigPlate(pdemo);
|
||||
Ctor_LinearStair(pdemo,btVector3(0,0,0),btVector3(2,1,5),0,10);
|
||||
pdemo->m_autocam=true;
|
||||
@@ -615,8 +609,7 @@ pdemo->m_autocam=true;
|
||||
static void Init_Volume(SoftDemo* pdemo)
|
||||
{
|
||||
//TRACEDEMO
|
||||
btSoftBody* psb=CreateEllipsoid(&pdemo->m_softbodyimpl,
|
||||
btVector3(35,25,0),
|
||||
btSoftBody* psb=btSoftBodyHelpers::CreateEllipsoid(pdemo->m_softBodyWorldInfo,btVector3(35,25,0),
|
||||
btVector3(1,1,1)*3,
|
||||
512);
|
||||
psb->m_cfg.kLST = 0.45;
|
||||
@@ -624,6 +617,7 @@ psb->m_cfg.kVC = 20;
|
||||
psb->SetTotalMass(50,true);
|
||||
psb->SetPose(true,false);
|
||||
pdemo->m_softbodies.push_back(psb);
|
||||
|
||||
Ctor_BigPlate(pdemo);
|
||||
Ctor_LinearStair(pdemo,btVector3(0,0,0),btVector3(2,1,5),0,10);
|
||||
pdemo->m_autocam=true;
|
||||
@@ -647,8 +641,7 @@ for(int y=0;y<n;++y)
|
||||
const btVector3 org(-sz+sz*2*x*in,
|
||||
-10,
|
||||
-sz+sz*2*y*in);
|
||||
btSoftBody* psb=CreateRope( &pdemo->m_softbodyimpl,
|
||||
org,
|
||||
btSoftBody* psb=btSoftBodyHelpers::CreateRope( pdemo->m_softBodyWorldInfo, org,
|
||||
org+btVector3(hg*0.001,hg,0),
|
||||
sg,
|
||||
1);
|
||||
@@ -662,6 +655,7 @@ for(int y=0;y<n;++y)
|
||||
psb->SetMass(1,0);
|
||||
psb->SetTotalMass(0.01);
|
||||
pdemo->m_softbodies.push_back(psb);
|
||||
|
||||
}
|
||||
}
|
||||
Ctor_BigBall(pdemo);
|
||||
@@ -674,17 +668,19 @@ static void Init_Cloth(SoftDemo* pdemo)
|
||||
{
|
||||
//TRACEDEMO
|
||||
const btScalar s=8;
|
||||
btSoftBody* psb=CreatePatch(&pdemo->m_softbodyimpl,
|
||||
btVector3(-s,0,-s),
|
||||
btSoftBody* psb=btSoftBodyHelpers::CreatePatch( pdemo->m_softBodyWorldInfo,btVector3(-s,0,-s),
|
||||
btVector3(+s,0,-s),
|
||||
btVector3(-s,0,+s),
|
||||
btVector3(+s,0,+s),
|
||||
31,31,
|
||||
|
||||
// 31,31,
|
||||
1+2+4+8,true);
|
||||
psb->GenerateBendingConstraints(2,1);
|
||||
psb->m_cfg.kLST = 0.4;
|
||||
psb->SetTotalMass(150);
|
||||
pdemo->m_softbodies.push_back(psb);
|
||||
|
||||
Ctor_RbUpStack(pdemo,10);
|
||||
}
|
||||
|
||||
@@ -694,8 +690,7 @@ Ctor_RbUpStack(pdemo,10);
|
||||
static void Init_Bunny(SoftDemo* pdemo)
|
||||
{
|
||||
//TRACEDEMO
|
||||
btSoftBody* psb=CreateFromTriMesh( &pdemo->m_softbodyimpl,
|
||||
gVerticesBunny,
|
||||
btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVerticesBunny,
|
||||
&gIndicesBunny[0][0],
|
||||
BUNNY_NUM_TRIANGLES);
|
||||
psb->GenerateBendingConstraints(2,0.5);
|
||||
@@ -705,6 +700,7 @@ psb->RandomizeConstraints();
|
||||
psb->Scale(btVector3(6,6,6));
|
||||
psb->SetTotalMass(100,true);
|
||||
pdemo->m_softbodies.push_back(psb);
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
@@ -713,8 +709,7 @@ pdemo->m_softbodies.push_back(psb);
|
||||
static void Init_BunnyMatch(SoftDemo* pdemo)
|
||||
{
|
||||
//TRACEDEMO
|
||||
btSoftBody* psb=CreateFromTriMesh( &pdemo->m_softbodyimpl,
|
||||
gVerticesBunny,
|
||||
btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo, gVerticesBunny,
|
||||
&gIndicesBunny[0][0],
|
||||
BUNNY_NUM_TRIANGLES);
|
||||
psb->GenerateBendingConstraints(2,0.5);
|
||||
@@ -726,6 +721,7 @@ psb->Scale(btVector3(6,6,6));
|
||||
psb->SetTotalMass(100,true);
|
||||
psb->SetPose(true,true);
|
||||
pdemo->m_softbodies.push_back(psb);
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
@@ -734,8 +730,7 @@ pdemo->m_softbodies.push_back(psb);
|
||||
static void Init_Torus(SoftDemo* pdemo)
|
||||
{
|
||||
//TRACEDEMO
|
||||
btSoftBody* psb=CreateFromTriMesh( &pdemo->m_softbodyimpl,
|
||||
gVertices,
|
||||
btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh( pdemo->m_softBodyWorldInfo, gVertices,
|
||||
&gIndices[0][0],
|
||||
NUM_TRIANGLES);
|
||||
psb->GenerateBendingConstraints(2,1);
|
||||
@@ -747,6 +742,7 @@ psb->Transform(btTransform(m,btVector3(0,4,0)));
|
||||
psb->Scale(btVector3(2,2,2));
|
||||
psb->SetTotalMass(50,true);
|
||||
pdemo->m_softbodies.push_back(psb);
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
@@ -755,8 +751,7 @@ pdemo->m_softbodies.push_back(psb);
|
||||
static void Init_TorusMatch(SoftDemo* pdemo)
|
||||
{
|
||||
//TRACEDEMO
|
||||
btSoftBody* psb=CreateFromTriMesh( &pdemo->m_softbodyimpl,
|
||||
gVertices,
|
||||
btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo, gVertices,
|
||||
&gIndices[0][0],
|
||||
NUM_TRIANGLES);
|
||||
psb->GenerateBendingConstraints(2,1);
|
||||
@@ -770,6 +765,8 @@ psb->Scale(btVector3(2,2,2));
|
||||
psb->SetTotalMass(50,true);
|
||||
psb->SetPose(true,true);
|
||||
pdemo->m_softbodies.push_back(psb);
|
||||
|
||||
|
||||
}
|
||||
|
||||
static unsigned current_demo=0;
|
||||
@@ -791,10 +788,11 @@ for(int i=m_dynamicsWorld->getNumCollisionObjects()-1;i>0;i--)
|
||||
}
|
||||
for(int i=0;i<m_softbodies.size();++i)
|
||||
{
|
||||
delete m_softbodies[i];
|
||||
btSoftBody* softbody = m_softbodies[i];
|
||||
delete softbody;
|
||||
}
|
||||
m_softbodies.clear();
|
||||
m_sparsesdf.Reset();
|
||||
m_softBodyWorldInfo.m_sparsesdf.Reset();
|
||||
/* Init */
|
||||
void (*demofncs[])(SoftDemo*)=
|
||||
{
|
||||
@@ -814,10 +812,14 @@ void (*demofncs[])(SoftDemo*)=
|
||||
Init_BunnyMatch,
|
||||
};
|
||||
current_demo=current_demo%(sizeof(demofncs)/sizeof(demofncs[0]));
|
||||
m_softbodyimpl.air_density = (btScalar)1.2;
|
||||
m_softbodyimpl.water_density = 0;
|
||||
m_softbodyimpl.water_offset = 0;
|
||||
m_softbodyimpl.water_normal = btVector3(0,0,0);
|
||||
|
||||
|
||||
m_softBodyWorldInfo.air_density = (btScalar)1.2;
|
||||
m_softBodyWorldInfo.water_density = 0;
|
||||
m_softBodyWorldInfo.water_offset = 0;
|
||||
m_softBodyWorldInfo.water_normal = btVector3(0,0,0);
|
||||
|
||||
|
||||
m_autocam = false;
|
||||
demofncs[current_demo](this);
|
||||
}
|
||||
@@ -832,13 +834,13 @@ int nps=0;
|
||||
for(int ib=0;ib<m_softbodies.size();++ib)
|
||||
{
|
||||
btSoftBody* psb=m_softbodies[ib];
|
||||
nps+=psb->m_nodes.size();
|
||||
for(int i=0;i<psb->m_nodes.size();++i)
|
||||
nps+=psb->getNodes().size();
|
||||
for(int i=0;i<psb->getNodes().size();++i)
|
||||
{
|
||||
ps+=psb->m_nodes[i].m_x;
|
||||
ps+=psb->getNodes()[i].m_x;
|
||||
}
|
||||
DrawFrame(psb,idraw);
|
||||
Draw(psb,idraw,fDrawFlags::Std);
|
||||
btSoftBodyHelpers::DrawFrame(psb,idraw);
|
||||
btSoftBodyHelpers::Draw(psb,idraw,fDrawFlags::Std);
|
||||
}
|
||||
ps/=nps;
|
||||
if(m_autocam)
|
||||
@@ -849,12 +851,12 @@ if(m_autocam)
|
||||
static const btVector3 axis[]={btVector3(1,0,0),
|
||||
btVector3(0,1,0),
|
||||
btVector3(0,0,1)};
|
||||
if(m_softbodyimpl.water_density>0)
|
||||
if(m_softBodyWorldInfo.water_density>0)
|
||||
{
|
||||
const btVector3 c= btVector3((btScalar)0.25,(btScalar)0.25,1);
|
||||
const btScalar a= (btScalar)0.5;
|
||||
const btVector3 n= m_softbodyimpl.water_normal;
|
||||
const btVector3 o= -n*m_softbodyimpl.water_offset;
|
||||
const btVector3 n= m_softBodyWorldInfo.water_normal;
|
||||
const btVector3 o= -n*m_softBodyWorldInfo.water_offset;
|
||||
const btVector3 x= cross(n,axis[n.minAxis()]).normalized();
|
||||
const btVector3 y= cross(x,n).normalized();
|
||||
const btScalar s= 25;
|
||||
@@ -878,44 +880,40 @@ switch(key)
|
||||
void SoftDemo::initPhysics()
|
||||
{
|
||||
|
||||
//#define USE_GROUND_PLANE 1
|
||||
#ifdef USE_GROUND_PLANE
|
||||
m_collisionShapes.push_back(new btStaticPlaneShape(btVector3(0,1,0),0.5));
|
||||
#else
|
||||
|
||||
///Please don't make the box sizes larger then 1000: the collision detection will be inaccurate.
|
||||
///See http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=346
|
||||
m_collisionShapes.push_back(new btBoxShape (btVector3(200,CUBE_HALF_EXTENTS,200)));
|
||||
//m_collisionShapes.push_back(new btCylinderShapeZ (btVector3(5,5,5)));
|
||||
//m_collisionShapes.push_back(new btSphereShape(5));
|
||||
#endif
|
||||
|
||||
m_collisionShapes.push_back(new btCylinderShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS)));
|
||||
|
||||
|
||||
m_dispatcher=0;
|
||||
m_collisionConfiguration = new btDefaultCollisionConfiguration();
|
||||
|
||||
///register some softbody collision algorithms on top of the default btDefaultCollisionConfiguration
|
||||
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
m_softBodyWorldInfo.m_dispatcher = m_dispatcher;
|
||||
|
||||
////////////////////////////
|
||||
///Register softbody versus softbody collision algorithm
|
||||
|
||||
|
||||
///Register softbody versus rigidbody collision algorithm
|
||||
|
||||
|
||||
////////////////////////////
|
||||
|
||||
btVector3 worldAabbMin(-1000,-1000,-1000);
|
||||
btVector3 worldAabbMax(1000,1000,1000);
|
||||
|
||||
m_broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies);
|
||||
/// For large worlds or over 16384 objects, use the bt32BitAxisSweep3 broadphase
|
||||
// m_broadphase = new bt32BitAxisSweep3(worldAabbMin,worldAabbMax,maxProxies);
|
||||
/// When trying to debug broadphase issues, try to use the btSimpleBroadphase
|
||||
// m_broadphase = new btSimpleBroadphase;
|
||||
|
||||
//box-box is in Extras/AlternativeCollisionAlgorithms:it requires inclusion of those files
|
||||
|
||||
m_softBodyWorldInfo.m_broadphase = m_broadphase;
|
||||
|
||||
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver();
|
||||
|
||||
m_solver = solver;
|
||||
//default solverMode is SOLVER_RANDMIZE_ORDER. Warmstarting seems not to improve convergence, see
|
||||
//solver->setSolverMode(0);//btSequentialImpulseConstraintSolver::SOLVER_USE_WARMSTARTING | btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER);
|
||||
|
||||
btDiscreteDynamicsWorld* world = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
|
||||
m_dynamicsWorld = world;
|
||||
@@ -940,8 +938,7 @@ void SoftDemo::initPhysics()
|
||||
|
||||
// clientResetScene();
|
||||
|
||||
m_softbodyimpl.pdemo=this;
|
||||
m_sparsesdf.Initialize();
|
||||
m_softBodyWorldInfo.m_sparsesdf.Initialize();
|
||||
clientResetScene();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ subject to the following restrictions:
|
||||
#include "DemoApplication.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "BulletDynamics/SoftBody/btSoftBody.h"
|
||||
#include "BulletDynamics/SoftBody/btSparseSDF.h"
|
||||
|
||||
|
||||
class btBroadphaseInterface;
|
||||
class btCollisionShape;
|
||||
@@ -31,31 +31,27 @@ class btConstraintSolver;
|
||||
struct btCollisionAlgorithmCreateFunc;
|
||||
class btDefaultCollisionConfiguration;
|
||||
|
||||
///collisions between two btSoftBody's
|
||||
class btSoftSoftCollisionAlgorithm;
|
||||
|
||||
///collisions between a btSoftBody and a btRigidBody
|
||||
class btSoftRididCollisionAlgorithm;
|
||||
|
||||
|
||||
///CcdPhysicsDemo shows basic stacking using Bullet physics, and allows toggle of Ccd (using key '1')
|
||||
class SoftDemo : public DemoApplication
|
||||
{
|
||||
public:
|
||||
struct SoftBodyImpl : btSoftBody::ISoftBody
|
||||
{
|
||||
void Attach(btSoftBody*);
|
||||
void Detach(btSoftBody*);
|
||||
void StartCollide(const btVector3&,const btVector3&);
|
||||
bool CheckContactPrecise(const btVector3&,
|
||||
btSoftBody::ISoftBody::sCti&);
|
||||
bool CheckContact( const btVector3&,
|
||||
btSoftBody::ISoftBody::sCti&);
|
||||
void EndCollide();
|
||||
void EvaluateMedium( const btVector3&,
|
||||
btSoftBody::ISoftBody::sMedium&);
|
||||
SoftDemo* pdemo;
|
||||
btScalar air_density;
|
||||
btScalar water_density;
|
||||
btScalar water_offset;
|
||||
btVector3 water_normal;
|
||||
} m_softbodyimpl;
|
||||
|
||||
btAlignedObjectArray<btSoftSoftCollisionAlgorithm*> m_SoftSoftCollisionAlgorithms;
|
||||
|
||||
btAlignedObjectArray<btSoftRididCollisionAlgorithm*> m_SoftRigidCollisionAlgorithms;
|
||||
|
||||
btSoftBody::btSoftBodyWorldInfo m_softBodyWorldInfo;
|
||||
|
||||
btAlignedObjectArray<btSoftBody*> m_softbodies;
|
||||
btSparseSdf<3> m_sparsesdf;
|
||||
|
||||
|
||||
bool m_autocam;
|
||||
|
||||
|
||||
@@ -66,12 +62,6 @@ struct SoftBodyImpl : btSoftBody::ISoftBody
|
||||
|
||||
btCollisionDispatcher* m_dispatcher;
|
||||
|
||||
#ifdef USE_PARALLEL_DISPATCHER
|
||||
#ifdef WIN32
|
||||
class Win32ThreadSupport* m_threadSupportCollision;
|
||||
class Win32ThreadSupport* m_threadSupportSolver;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
btConstraintSolver* m_solver;
|
||||
|
||||
|
||||
77
Demos/SoftDemo/btSoftBodyRigidBodyCollisionConfiguration.cpp
Normal file
77
Demos/SoftDemo/btSoftBodyRigidBodyCollisionConfiguration.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "btSoftRigidCollisionAlgorithm.h"
|
||||
#include "btSoftSoftCollisionAlgorithm.h"
|
||||
|
||||
|
||||
btSoftBodyRigidBodyCollisionConfiguration::btSoftBodyRigidBodyCollisionConfiguration(btStackAlloc* stackAlloc,btPoolAllocator* persistentManifoldPool,btPoolAllocator* collisionAlgorithmPool)
|
||||
:btDefaultCollisionConfiguration(stackAlloc,persistentManifoldPool,collisionAlgorithmPool)
|
||||
{
|
||||
void* mem;
|
||||
|
||||
mem = btAlignedAlloc(sizeof(btSoftSoftCollisionAlgorithm::CreateFunc),16);
|
||||
m_softSoftCreateFunc = new(mem) btSoftSoftCollisionAlgorithm::CreateFunc;
|
||||
|
||||
mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc),16);
|
||||
m_softRigidCreateFunc = new(mem) btSoftRigidCollisionAlgorithm::CreateFunc;
|
||||
|
||||
mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc),16);
|
||||
m_swappedSoftRigidCreateFunc = new(mem) btSoftRigidCollisionAlgorithm::CreateFunc;
|
||||
m_swappedSoftRigidCreateFunc->m_swapped=true;
|
||||
|
||||
}
|
||||
|
||||
btSoftBodyRigidBodyCollisionConfiguration::~btSoftBodyRigidBodyCollisionConfiguration()
|
||||
{
|
||||
m_softSoftCreateFunc->~btCollisionAlgorithmCreateFunc();
|
||||
btAlignedFree( m_softSoftCreateFunc);
|
||||
|
||||
m_softRigidCreateFunc->~btCollisionAlgorithmCreateFunc();
|
||||
btAlignedFree( m_softRigidCreateFunc);
|
||||
|
||||
m_swappedSoftRigidCreateFunc->~btCollisionAlgorithmCreateFunc();
|
||||
btAlignedFree( m_swappedSoftRigidCreateFunc);
|
||||
|
||||
|
||||
}
|
||||
|
||||
///creation of soft-soft and soft-rigid, and otherwise fallback to base class implementation
|
||||
btCollisionAlgorithmCreateFunc* btSoftBodyRigidBodyCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1)
|
||||
{
|
||||
|
||||
///try to handle the softbody interactions first
|
||||
|
||||
if ((proxyType0 == SOFTBODY_SHAPE_PROXYTYPE ) && (proxyType1==SOFTBODY_SHAPE_PROXYTYPE))
|
||||
{
|
||||
return m_softSoftCreateFunc;
|
||||
}
|
||||
|
||||
///other can't be also softbody, so assume rigid for now
|
||||
if (proxyType0 == SOFTBODY_SHAPE_PROXYTYPE )
|
||||
{
|
||||
return m_softRigidCreateFunc;
|
||||
}
|
||||
|
||||
///other can't be also softbody, so assume rigid for now
|
||||
if (proxyType1 == SOFTBODY_SHAPE_PROXYTYPE )
|
||||
{
|
||||
return m_swappedSoftRigidCreateFunc;
|
||||
}
|
||||
|
||||
///fallback to the regular rigid collision shape
|
||||
return btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(proxyType0,proxyType1);
|
||||
}
|
||||
46
Demos/SoftDemo/btSoftBodyRigidBodyCollisionConfiguration.h
Normal file
46
Demos/SoftDemo/btSoftBodyRigidBodyCollisionConfiguration.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFTBODY_RIGIDBODY_COLLISION_CONFIGURATION
|
||||
#define BT_SOFTBODY_RIGIDBODY_COLLISION_CONFIGURATION
|
||||
|
||||
#include "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h"
|
||||
|
||||
class btVoronoiSimplexSolver;
|
||||
class btGjkEpaPenetrationDepthSolver;
|
||||
|
||||
|
||||
///btSoftBodyRigidBodyCollisionConfiguration add softbody interaction on top of btDefaultCollisionConfiguration
|
||||
class btSoftBodyRigidBodyCollisionConfiguration : public btDefaultCollisionConfiguration
|
||||
{
|
||||
|
||||
//default CreationFunctions, filling the m_doubleDispatch table
|
||||
btCollisionAlgorithmCreateFunc* m_softSoftCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_softRigidCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_swappedSoftRigidCreateFunc;
|
||||
|
||||
public:
|
||||
|
||||
btSoftBodyRigidBodyCollisionConfiguration(btStackAlloc* stackAlloc=0,btPoolAllocator* persistentManifoldPool=0,btPoolAllocator* collisionAlgorithmPool=0);
|
||||
|
||||
virtual ~btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
///creation of soft-soft and soft-rigid, and otherwise fallback to base class implementation
|
||||
virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1);
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_SOFTBODY_RIGIDBODY_COLLISION_CONFIGURATION
|
||||
|
||||
94
Demos/SoftDemo/btSoftRigidCollisionAlgorithm.cpp
Normal file
94
Demos/SoftDemo/btSoftRigidCollisionAlgorithm.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "btSoftRigidCollisionAlgorithm.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||
#include "BulletCollision/CollisionShapes/btSphereShape.h"
|
||||
#include "BulletCollision/CollisionShapes/btBoxShape.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
#include "BulletDynamics/SoftBody/btSoftBody.h"
|
||||
///TODO: include all the shapes that the softbody can collide with
|
||||
///alternatively, implement special case collision algorithms (just like for rigid collision shapes)
|
||||
|
||||
//#include <stdio.h>
|
||||
|
||||
btSoftRigidCollisionAlgorithm::btSoftRigidCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped)
|
||||
: btCollisionAlgorithm(ci),
|
||||
//m_ownManifold(false),
|
||||
//m_manifoldPtr(mf),
|
||||
m_isSwapped(isSwapped)
|
||||
{
|
||||
|
||||
m_softBody = m_isSwapped? (btSoftBody*)col1 : (btSoftBody*)col0;
|
||||
m_rigidCollisionObject = m_isSwapped? col0 : col1;
|
||||
|
||||
//quick fix, add overlapping rigidbody to softbody, so it can be handled within btSoftBody::Step method
|
||||
m_softBody->m_overlappingRigidBodies.push_back(m_rigidCollisionObject);
|
||||
|
||||
///store the contacts straight into the btSoftBody for now?
|
||||
|
||||
/*if (!m_manifoldPtr && m_dispatcher->needsCollision(sphereObj,boxObj))
|
||||
{
|
||||
m_manifoldPtr = m_dispatcher->getNewManifold(sphereObj,boxObj);
|
||||
m_ownManifold = true;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
btSoftRigidCollisionAlgorithm::~btSoftRigidCollisionAlgorithm()
|
||||
{
|
||||
|
||||
m_softBody->m_overlappingRigidBodies.remove(m_rigidCollisionObject);
|
||||
|
||||
/*if (m_ownManifold)
|
||||
{
|
||||
if (m_manifoldPtr)
|
||||
m_dispatcher->releaseManifold(m_manifoldPtr);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void btSoftRigidCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
{
|
||||
(void)dispatchInfo;
|
||||
(void)resultOut;
|
||||
//printf("btSoftRigidCollisionAlgorithm\n");
|
||||
|
||||
btSoftBody* softBody = m_isSwapped? (btSoftBody*)body1 : (btSoftBody*)body0;
|
||||
btCollisionObject* rigidCollisionObject = m_isSwapped? body0 : body1;
|
||||
///do your stuff here
|
||||
|
||||
|
||||
}
|
||||
|
||||
btScalar btSoftRigidCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
{
|
||||
(void)resultOut;
|
||||
(void)dispatchInfo;
|
||||
(void)col0;
|
||||
(void)col1;
|
||||
|
||||
//not yet
|
||||
return btScalar(1.);
|
||||
}
|
||||
|
||||
69
Demos/SoftDemo/btSoftRigidCollisionAlgorithm.h
Normal file
69
Demos/SoftDemo/btSoftRigidCollisionAlgorithm.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SOFT_RIGID_COLLISION_ALGORITHM_H
|
||||
#define SOFT_RIGID_COLLISION_ALGORITHM_H
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||
class btPersistentManifold;
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||
|
||||
#include "LinearMath/btVector3.h"
|
||||
struct btSoftBody;
|
||||
|
||||
/// btSoftRigidCollisionAlgorithm provides collision detection between btSoftBody and btRigidBody
|
||||
class btSoftRigidCollisionAlgorithm : public btCollisionAlgorithm
|
||||
{
|
||||
// bool m_ownManifold;
|
||||
// btPersistentManifold* m_manifoldPtr;
|
||||
|
||||
btSoftBody* m_softBody;
|
||||
btCollisionObject* m_rigidCollisionObject;
|
||||
|
||||
///for rigid versus soft (instead of soft versus rigid), we use this swapped boolean
|
||||
bool m_isSwapped;
|
||||
|
||||
public:
|
||||
|
||||
btSoftRigidCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped);
|
||||
|
||||
virtual ~btSoftRigidCollisionAlgorithm();
|
||||
|
||||
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
|
||||
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
|
||||
{
|
||||
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSoftRigidCollisionAlgorithm));
|
||||
if (!m_swapped)
|
||||
{
|
||||
return new(mem) btSoftRigidCollisionAlgorithm(0,ci,body0,body1,false);
|
||||
} else
|
||||
{
|
||||
return new(mem) btSoftRigidCollisionAlgorithm(0,ci,body0,body1,true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif //SOFT_RIGID_COLLISION_ALGORITHM_H
|
||||
|
||||
104
Demos/SoftDemo/btSoftSoftCollisionAlgorithm.cpp
Normal file
104
Demos/SoftDemo/btSoftSoftCollisionAlgorithm.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "btSoftSoftCollisionAlgorithm.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||
#include "BulletCollision/CollisionShapes/btBoxShape.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
#include "BulletDynamics/SoftBody/btSoftBody.h"
|
||||
|
||||
#define USE_PERSISTENT_CONTACTS 1
|
||||
|
||||
btSoftSoftCollisionAlgorithm::btSoftSoftCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* obj0,btCollisionObject* obj1)
|
||||
: btCollisionAlgorithm(ci)
|
||||
//m_ownManifold(false),
|
||||
//m_manifoldPtr(mf)
|
||||
{
|
||||
m_softBody0 = (btSoftBody*) obj0;
|
||||
m_softBody1 = (btSoftBody*) obj1;
|
||||
|
||||
m_softBody0->m_overlappingSoftBodies.push_back(m_softBody1);
|
||||
m_softBody1->m_overlappingSoftBodies.push_back(m_softBody0);
|
||||
|
||||
/*if (!m_manifoldPtr && m_dispatcher->needsCollision(obj0,obj1))
|
||||
{
|
||||
m_manifoldPtr = m_dispatcher->getNewManifold(obj0,obj1);
|
||||
m_ownManifold = true;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
btSoftSoftCollisionAlgorithm::~btSoftSoftCollisionAlgorithm()
|
||||
{
|
||||
m_softBody0->m_overlappingSoftBodies.remove(m_softBody1);
|
||||
m_softBody1->m_overlappingSoftBodies.remove(m_softBody0);
|
||||
|
||||
//this gets called when the overlap stops.
|
||||
|
||||
//here is where contacts (manifolds) should be removed
|
||||
|
||||
/*
|
||||
if (m_ownManifold)
|
||||
{
|
||||
if (m_manifoldPtr)
|
||||
m_dispatcher->releaseManifold(m_manifoldPtr);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
void btSoftSoftCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
{
|
||||
|
||||
btCollisionObject* col0 = body0;
|
||||
btCollisionObject* col1 = body1;
|
||||
|
||||
/*
|
||||
btBoxShape* box0 = (btBoxShape*)col0->getCollisionShape();
|
||||
btBoxShape* box1 = (btBoxShape*)col1->getCollisionShape();
|
||||
|
||||
|
||||
|
||||
/// report a contact. internally this will be kept persistent, and contact reduction is done
|
||||
resultOut->setPersistentManifold(m_manifoldPtr);
|
||||
#ifndef USE_PERSISTENT_CONTACTS
|
||||
m_manifoldPtr->clearManifold();
|
||||
#endif //USE_PERSISTENT_CONTACTS
|
||||
|
||||
btDiscreteCollisionDetectorInterface::ClosestPointInput input;
|
||||
input.m_maximumDistanceSquared = 1e30f;
|
||||
input.m_transformA = body0->getWorldTransform();
|
||||
input.m_transformB = body1->getWorldTransform();
|
||||
|
||||
btBoxBoxDetector detector(box0,box1);
|
||||
detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
|
||||
|
||||
#ifdef USE_PERSISTENT_CONTACTS
|
||||
// refreshContactPoints is only necessary when using persistent contact points. otherwise all points are newly added
|
||||
if (m_ownManifold)
|
||||
{
|
||||
resultOut->refreshContactPoints();
|
||||
}
|
||||
#endif //USE_PERSISTENT_CONTACTS
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
btScalar btSoftSoftCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
{
|
||||
//not yet
|
||||
return 1.f;
|
||||
}
|
||||
62
Demos/SoftDemo/btSoftSoftCollisionAlgorithm.h
Normal file
62
Demos/SoftDemo/btSoftSoftCollisionAlgorithm.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SOFT_SOFT_COLLISION_ALGORITHM_H
|
||||
#define SOFT_SOFT_COLLISION_ALGORITHM_H
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||
|
||||
class btPersistentManifold;
|
||||
struct btSoftBody;
|
||||
|
||||
///collision detection between two btSoftBody shapes
|
||||
class btSoftSoftCollisionAlgorithm : public btCollisionAlgorithm
|
||||
{
|
||||
bool m_ownManifold;
|
||||
btPersistentManifold* m_manifoldPtr;
|
||||
|
||||
btSoftBody* m_softBody0;
|
||||
btSoftBody* m_softBody1;
|
||||
|
||||
|
||||
public:
|
||||
btSoftSoftCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
|
||||
: btCollisionAlgorithm(ci) {}
|
||||
|
||||
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
btSoftSoftCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
|
||||
|
||||
virtual ~btSoftSoftCollisionAlgorithm();
|
||||
|
||||
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
|
||||
{
|
||||
int bbsize = sizeof(btSoftSoftCollisionAlgorithm);
|
||||
void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize);
|
||||
return new(ptr) btSoftSoftCollisionAlgorithm(0,ci,body0,body1);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif //SOFT_SOFT_COLLISION_ALGORITHM_H
|
||||
|
||||
@@ -59,6 +59,8 @@ CONCAVE_SHAPES_END_HERE,
|
||||
|
||||
COMPOUND_SHAPE_PROXYTYPE,
|
||||
|
||||
SOFTBODY_SHAPE_PROXYTYPE,
|
||||
|
||||
MAX_BROADPHASE_COLLISION_TYPES
|
||||
};
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1);
|
||||
virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1);
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -17,6 +17,123 @@ subject to the following restrictions:
|
||||
#include "btSoftBody.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||
|
||||
|
||||
btSoftBody::btSoftBody(btSoftBody::btSoftBodyWorldInfo& worldInfo,int node_count, const btVector3* x, const btScalar* m)
|
||||
:m_worldInfo(worldInfo)
|
||||
{
|
||||
///for now, create a collision shape internally
|
||||
m_softBodyCollisionShape = new btSoftBodyCollisionShape();
|
||||
|
||||
setCollisionShape(m_softBodyCollisionShape);
|
||||
|
||||
/* Init */
|
||||
m_cfg.aeromodel = eAeroModel::V_Point;
|
||||
m_cfg.kDG = 0;
|
||||
m_cfg.kLF = 0;
|
||||
m_cfg.kDP = 0;
|
||||
m_cfg.kPR = 0;
|
||||
m_cfg.kVC = 0;
|
||||
m_cfg.kDF = (btScalar)0.2;
|
||||
m_cfg.kLST = 1;
|
||||
m_cfg.kMT = 0;
|
||||
m_cfg.kSOR = 1;
|
||||
m_cfg.kCHR = (btScalar)1.0;
|
||||
m_cfg.kAHR = (btScalar)0.5;
|
||||
m_cfg.timescale = 1;
|
||||
m_cfg.timestep = (btScalar)(1/60.);
|
||||
m_cfg.maxsteps = 60;
|
||||
m_cfg.iterations = 1;
|
||||
m_cfg.becollide = true;
|
||||
m_cfg.bscollide = false;
|
||||
m_pose.m_bvolume = false;
|
||||
m_pose.m_bframe = false;
|
||||
m_pose.m_volume = 0;
|
||||
m_pose.m_com = btVector3(0,0,0);
|
||||
m_pose.m_trs.setIdentity();
|
||||
m_tag = 0;
|
||||
m_timeacc = 0;
|
||||
m_bUpdateRtCst = true;
|
||||
m_bounds[0] = btVector3(0,0,0);
|
||||
m_bounds[1] = btVector3(0,0,0);
|
||||
/* Nodes */
|
||||
getNodes().resize(node_count);
|
||||
for(int i=0,ni=node_count;i<ni;++i)
|
||||
{
|
||||
Node& n=getNodes()[i];
|
||||
memset(&n,0,sizeof(n));
|
||||
n.m_x = x?*x++:btVector3(0,0,0);
|
||||
n.m_q = n.m_x;
|
||||
n.m_im = m?*m++:1;
|
||||
n.m_im = n.m_im>0?1/n.m_im:0;
|
||||
}
|
||||
updateTransform();
|
||||
///register to the broadphase
|
||||
setBroadphaseHandle( m_worldInfo.m_broadphase->createProxy(m_bounds[0],m_bounds[1],SOFTBODY_SHAPE_PROXYTYPE,this,1,1,m_worldInfo.m_dispatcher,0));
|
||||
|
||||
|
||||
}
|
||||
|
||||
///destructor
|
||||
btSoftBody::~btSoftBody()
|
||||
{
|
||||
//remove from broadphase
|
||||
m_worldInfo.m_broadphase->destroyProxy(getBroadphaseHandle(),m_worldInfo.m_dispatcher);
|
||||
|
||||
///for now, delete the internal shape
|
||||
delete m_softBodyCollisionShape;
|
||||
}
|
||||
|
||||
btVector3 btSoftBody::btSoftBodyCollisionShape::m_sScaling(0,0,0);
|
||||
|
||||
btSoftBody::btSoftBodyCollisionShape::btSoftBodyCollisionShape()
|
||||
{
|
||||
}
|
||||
|
||||
btSoftBody::btSoftBodyCollisionShape::~btSoftBodyCollisionShape()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void btSoftBody::btSoftBodyCollisionShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
|
||||
{
|
||||
//not yet
|
||||
btAssert(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
void btSoftBody::updateBounds()
|
||||
{
|
||||
if(getNodes().size()>0)
|
||||
{
|
||||
m_bounds[0]=
|
||||
m_bounds[1]=getNodes()[0].m_x;
|
||||
for(int i=1,ni=getNodes().size();i<ni;++i)
|
||||
{
|
||||
const btSoftBody::Node& n=getNodes()[i];
|
||||
m_bounds[0].setMin(n.m_x);
|
||||
m_bounds[1].setMax(n.m_x);
|
||||
m_bounds[0].setMin(n.m_q);
|
||||
m_bounds[1].setMax(n.m_q);
|
||||
}
|
||||
|
||||
if (getBroadphaseHandle())
|
||||
{
|
||||
m_worldInfo.m_broadphase->setAabb(getBroadphaseHandle(),m_bounds[0],m_bounds[1],m_worldInfo.m_dispatcher);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bounds[0]=
|
||||
m_bounds[1]=btVector3(0,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
namespace btsoftbody_internals
|
||||
{
|
||||
@@ -184,17 +301,17 @@ if(l>SIMD_EPSILON)
|
||||
static void PointersToIndices(btSoftBody* psb)
|
||||
{
|
||||
#define PTR2IDX(_p_,_b_) reinterpret_cast<btSoftBody::Node*>((_p_)-(_b_))
|
||||
btSoftBody::Node* base=&psb->m_nodes[0];
|
||||
for(int i=0,ni=psb->m_links.size();i<ni;++i)
|
||||
btSoftBody::Node* base=&psb->getNodes()[0];
|
||||
for(int i=0,ni=psb->getLinks().size();i<ni;++i)
|
||||
{
|
||||
psb->m_links[i].m_n[0]=PTR2IDX(psb->m_links[i].m_n[0],base);
|
||||
psb->m_links[i].m_n[1]=PTR2IDX(psb->m_links[i].m_n[1],base);
|
||||
psb->getLinks()[i].m_n[0]=PTR2IDX(psb->getLinks()[i].m_n[0],base);
|
||||
psb->getLinks()[i].m_n[1]=PTR2IDX(psb->getLinks()[i].m_n[1],base);
|
||||
}
|
||||
for(int i=0,ni=psb->m_faces.size();i<ni;++i)
|
||||
for(int i=0,ni=psb->getFaces().size();i<ni;++i)
|
||||
{
|
||||
psb->m_faces[i].m_n[0]=PTR2IDX(psb->m_faces[i].m_n[0],base);
|
||||
psb->m_faces[i].m_n[1]=PTR2IDX(psb->m_faces[i].m_n[1],base);
|
||||
psb->m_faces[i].m_n[2]=PTR2IDX(psb->m_faces[i].m_n[2],base);
|
||||
psb->getFaces()[i].m_n[0]=PTR2IDX(psb->getFaces()[i].m_n[0],base);
|
||||
psb->getFaces()[i].m_n[1]=PTR2IDX(psb->getFaces()[i].m_n[1],base);
|
||||
psb->getFaces()[i].m_n[2]=PTR2IDX(psb->getFaces()[i].m_n[2],base);
|
||||
}
|
||||
#undef PTR2IDX
|
||||
}
|
||||
@@ -203,17 +320,17 @@ for(int i=0,ni=psb->m_faces.size();i<ni;++i)
|
||||
static void IndicesToPointers(btSoftBody* psb)
|
||||
{
|
||||
#define IDX2PTR(_p_,_b_) ((_b_)+(((char*)_p_)-(char*)0))
|
||||
btSoftBody::Node* base=&psb->m_nodes[0];
|
||||
for(int i=0,ni=psb->m_links.size();i<ni;++i)
|
||||
btSoftBody::Node* base=&psb->getNodes()[0];
|
||||
for(int i=0,ni=psb->getLinks().size();i<ni;++i)
|
||||
{
|
||||
psb->m_links[i].m_n[0]=IDX2PTR(psb->m_links[i].m_n[0],base);
|
||||
psb->m_links[i].m_n[1]=IDX2PTR(psb->m_links[i].m_n[1],base);
|
||||
psb->getLinks()[i].m_n[0]=IDX2PTR(psb->getLinks()[i].m_n[0],base);
|
||||
psb->getLinks()[i].m_n[1]=IDX2PTR(psb->getLinks()[i].m_n[1],base);
|
||||
}
|
||||
for(int i=0,ni=psb->m_faces.size();i<ni;++i)
|
||||
for(int i=0,ni=psb->getFaces().size();i<ni;++i)
|
||||
{
|
||||
psb->m_faces[i].m_n[0]=IDX2PTR(psb->m_faces[i].m_n[0],base);
|
||||
psb->m_faces[i].m_n[1]=IDX2PTR(psb->m_faces[i].m_n[1],base);
|
||||
psb->m_faces[i].m_n[2]=IDX2PTR(psb->m_faces[i].m_n[2],base);
|
||||
psb->getFaces()[i].m_n[0]=IDX2PTR(psb->getFaces()[i].m_n[0],base);
|
||||
psb->getFaces()[i].m_n[1]=IDX2PTR(psb->getFaces()[i].m_n[1],base);
|
||||
psb->getFaces()[i].m_n[2]=IDX2PTR(psb->getFaces()[i].m_n[2],base);
|
||||
}
|
||||
#undef IDX2PTR
|
||||
}
|
||||
@@ -286,9 +403,9 @@ static int RaycastInternal(const btSoftBody* psb,
|
||||
{
|
||||
int cnt=0;
|
||||
mint=SIMD_INFINITY;
|
||||
for(int i=0,ni=psb->m_faces.size();i<ni;++i)
|
||||
for(int i=0,ni=psb->getFaces().size();i<ni;++i)
|
||||
{
|
||||
const btSoftBody::Face& f=psb->m_faces[i];
|
||||
const btSoftBody::Face& f=psb->getFaces()[i];
|
||||
const btScalar t=RayTriangle( org,dir,
|
||||
f.m_n[0]->m_x,
|
||||
f.m_n[1]->m_x,
|
||||
@@ -309,9 +426,9 @@ static btVector3 EvaluateCom(btSoftBody* psb)
|
||||
btVector3 com(0,0,0);
|
||||
if(psb->m_pose.m_bframe)
|
||||
{
|
||||
for(int i=0,ni=psb->m_nodes.size();i<ni;++i)
|
||||
for(int i=0,ni=psb->getNodes().size();i<ni;++i)
|
||||
{
|
||||
com+=psb->m_nodes[i].m_x*psb->m_pose.m_wgh[i];
|
||||
com+=psb->getNodes()[i].m_x*psb->m_pose.m_wgh[i];
|
||||
}
|
||||
}
|
||||
return(com);
|
||||
@@ -321,13 +438,13 @@ return(com);
|
||||
static void UpdateNormals(btSoftBody* psb)
|
||||
{
|
||||
const btVector3 zv(0,0,0);
|
||||
for(int i=0,ni=psb->m_nodes.size();i<ni;++i)
|
||||
for(int i=0,ni=psb->getNodes().size();i<ni;++i)
|
||||
{
|
||||
psb->m_nodes[i].m_n=zv;
|
||||
psb->getNodes()[i].m_n=zv;
|
||||
}
|
||||
for(int i=0,ni=psb->m_faces.size();i<ni;++i)
|
||||
for(int i=0,ni=psb->getFaces().size();i<ni;++i)
|
||||
{
|
||||
btSoftBody::Face& f=psb->m_faces[i];
|
||||
btSoftBody::Face& f=psb->getFaces()[i];
|
||||
const btVector3 n=cross(f.m_n[1]->m_x-f.m_n[0]->m_x,
|
||||
f.m_n[2]->m_x-f.m_n[0]->m_x);
|
||||
f.m_normal=n.normalized();
|
||||
@@ -335,40 +452,13 @@ for(int i=0,ni=psb->m_faces.size();i<ni;++i)
|
||||
f.m_n[1]->m_n+=n;
|
||||
f.m_n[2]->m_n+=n;
|
||||
}
|
||||
for(int i=0,ni=psb->m_nodes.size();i<ni;++i)
|
||||
for(int i=0,ni=psb->getNodes().size();i<ni;++i)
|
||||
{
|
||||
psb->m_nodes[i].m_n.normalize();
|
||||
psb->getNodes()[i].m_n.normalize();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
static void UpdateBounds(btSoftBody* psb)
|
||||
{
|
||||
if(psb->m_nodes.size()>0)
|
||||
{
|
||||
psb->m_bounds[0]=
|
||||
psb->m_bounds[1]=psb->m_nodes[0].m_x;
|
||||
for(int i=1,ni=psb->m_nodes.size();i<ni;++i)
|
||||
{
|
||||
const btSoftBody::Node& n=psb->m_nodes[i];
|
||||
psb->m_bounds[0].setMin(n.m_x);
|
||||
psb->m_bounds[1].setMax(n.m_x);
|
||||
psb->m_bounds[0].setMin(n.m_q);
|
||||
psb->m_bounds[1].setMax(n.m_q);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
psb->m_bounds[0]=
|
||||
psb->m_bounds[1]=btVector3(0,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
static void UpdateTransform(btSoftBody* psb)
|
||||
{
|
||||
UpdateBounds(psb);
|
||||
}
|
||||
|
||||
//
|
||||
static void UpdatePose(btSoftBody* psb)
|
||||
@@ -381,12 +471,12 @@ if(psb->m_pose.m_bframe)
|
||||
pose.m_com = com;
|
||||
/* Rotation */
|
||||
btMatrix3x3 Apq;
|
||||
const btScalar eps=1/(btScalar)(100*psb->m_nodes.size());
|
||||
const btScalar eps=1/(btScalar)(100*psb->getNodes().size());
|
||||
Apq[0]=Apq[1]=Apq[2]=btVector3(0,0,0);
|
||||
Apq[0].setX(eps);Apq[1].setY(eps*2);Apq[2].setZ(eps*3);
|
||||
for(int i=0,ni=psb->m_nodes.size();i<ni;++i)
|
||||
for(int i=0,ni=psb->getNodes().size();i<ni;++i)
|
||||
{
|
||||
const btVector3 a=pose.m_wgh[i]*(psb->m_nodes[i].m_x-com);
|
||||
const btVector3 a=pose.m_wgh[i]*(psb->getNodes()[i].m_x-com);
|
||||
const btVector3& b=pose.m_pos[i];
|
||||
Apq[0]+=a.x()*b;
|
||||
Apq[1]+=a.y()*b;
|
||||
@@ -402,42 +492,42 @@ if(psb->m_pose.m_bframe)
|
||||
static void UpdateConstants(btSoftBody* psb)
|
||||
{
|
||||
/* Links */
|
||||
for(int i=0,ni=psb->m_links.size();i<ni;++i)
|
||||
for(int i=0,ni=psb->getLinks().size();i<ni;++i)
|
||||
{
|
||||
btSoftBody::Link& l=psb->m_links[i];
|
||||
btSoftBody::Link& l=psb->getLinks()[i];
|
||||
l.m_rl = (l.m_n[0]->m_x-l.m_n[1]->m_x).length();
|
||||
l.m_c0 = l.m_n[0]->m_im+l.m_n[1]->m_im;
|
||||
l.m_c1 = l.m_rl*l.m_rl;
|
||||
}
|
||||
/* Faces */
|
||||
for(int i=0,ni=psb->m_faces.size();i<ni;++i)
|
||||
for(int i=0,ni=psb->getFaces().size();i<ni;++i)
|
||||
{
|
||||
btSoftBody::Face& f=psb->m_faces[i];
|
||||
btSoftBody::Face& f=psb->getFaces()[i];
|
||||
f.m_ra = AreaOf(f.m_n[0]->m_x,f.m_n[1]->m_x,f.m_n[2]->m_x);
|
||||
}
|
||||
/* Area's */
|
||||
btAlignedObjectArray<int> counts;
|
||||
counts.resize(psb->m_nodes.size(),0);
|
||||
for(int i=0,ni=psb->m_nodes.size();i<ni;++i)
|
||||
counts.resize(psb->getNodes().size(),0);
|
||||
for(int i=0,ni=psb->getNodes().size();i<ni;++i)
|
||||
{
|
||||
psb->m_nodes[i].m_area = 0;
|
||||
psb->getNodes()[i].m_area = 0;
|
||||
}
|
||||
for(int i=0,ni=psb->m_faces.size();i<ni;++i)
|
||||
for(int i=0,ni=psb->getFaces().size();i<ni;++i)
|
||||
{
|
||||
btSoftBody::Face& f=psb->m_faces[i];
|
||||
btSoftBody::Face& f=psb->getFaces()[i];
|
||||
for(int j=0;j<3;++j)
|
||||
{
|
||||
const int index=(int)(f.m_n[j]-&psb->m_nodes[0]);
|
||||
const int index=(int)(f.m_n[j]-&psb->getNodes()[0]);
|
||||
counts[index]++;
|
||||
f.m_n[j]->m_area+=btFabs(f.m_ra);
|
||||
}
|
||||
}
|
||||
for(int i=0,ni=psb->m_nodes.size();i<ni;++i)
|
||||
for(int i=0,ni=psb->getNodes().size();i<ni;++i)
|
||||
{
|
||||
if(counts[i]>0)
|
||||
psb->m_nodes[i].m_area/=(btScalar)counts[i];
|
||||
psb->getNodes()[i].m_area/=(btScalar)counts[i];
|
||||
else
|
||||
psb->m_nodes[i].m_area=0;
|
||||
psb->getNodes()[i].m_area=0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,7 +572,7 @@ const bool use_volume= as_pressure ||
|
||||
btScalar volume=0;
|
||||
btScalar ivolumetp=0;
|
||||
btScalar dvolumetv=0;
|
||||
btSoftBody::ISoftBody::sMedium medium;
|
||||
btSoftBody::sMedium medium;
|
||||
if(use_volume)
|
||||
{
|
||||
volume = psb->GetVolume();
|
||||
@@ -490,14 +580,14 @@ if(use_volume)
|
||||
dvolumetv = (psb->m_pose.m_volume-volume)*kVC;
|
||||
}
|
||||
/* Per vertex forces */
|
||||
for(int i=0,ni=psb->m_nodes.size();i<ni;++i)
|
||||
for(int i=0,ni=psb->getNodes().size();i<ni;++i)
|
||||
{
|
||||
btSoftBody::Node& n=psb->m_nodes[i];
|
||||
btSoftBody::Node& n=psb->getNodes()[i];
|
||||
if(n.m_im>0)
|
||||
{
|
||||
if(use_medium)
|
||||
{
|
||||
psb->m_isb->EvaluateMedium(n.m_x,medium);
|
||||
psb->EvaluateMedium(n.m_x,medium);
|
||||
/* Aerodynamics */
|
||||
if(as_vaero)
|
||||
{
|
||||
@@ -541,14 +631,14 @@ for(int i=0,ni=psb->m_nodes.size();i<ni;++i)
|
||||
}
|
||||
}
|
||||
/* Per face forces */
|
||||
for(int i=0,ni=psb->m_faces.size();i<ni;++i)
|
||||
for(int i=0,ni=psb->getFaces().size();i<ni;++i)
|
||||
{
|
||||
btSoftBody::Face& f=psb->m_faces[i];
|
||||
btSoftBody::Face& f=psb->getFaces()[i];
|
||||
if(as_faero)
|
||||
{
|
||||
const btVector3 v=(f.m_n[0]->m_v+f.m_n[1]->m_v+f.m_n[2]->m_v)/3;
|
||||
const btVector3 x=(f.m_n[0]->m_x+f.m_n[1]->m_x+f.m_n[2]->m_x)/3;
|
||||
psb->m_isb->EvaluateMedium(x,medium);
|
||||
psb->EvaluateMedium(x,medium);
|
||||
const btVector3 rel_v=v-medium.m_velocity;
|
||||
const btScalar rel_v2=rel_v.length2();
|
||||
if(rel_v2>SIMD_EPSILON)
|
||||
@@ -603,7 +693,7 @@ const btScalar kCHR=psb->m_cfg.kCHR;
|
||||
for(int i=0,ni=psb->m_contacts.size();i<ni;++i)
|
||||
{
|
||||
const btSoftBody::Contact& c=psb->m_contacts[i];
|
||||
const btSoftBody::ISoftBody::sCti& cti=c.m_cti;
|
||||
const btSoftBody::sCti& cti=c.m_cti;
|
||||
const btVector3 va=cti.m_body->getVelocityInLocalPoint(c.m_c1)*sdt;
|
||||
const btVector3 vb=c.m_node->m_x-c.m_node->m_q;
|
||||
const btVector3 vr=vb-va;
|
||||
@@ -622,9 +712,9 @@ for(int i=0,ni=psb->m_contacts.size();i<ni;++i)
|
||||
//
|
||||
static void PSolve_Links(btSoftBody* psb,btScalar w)
|
||||
{
|
||||
for(int i=0,ni=psb->m_links.size();i<ni;++i)
|
||||
for(int i=0,ni=psb->getLinks().size();i<ni;++i)
|
||||
{
|
||||
btSoftBody::Link& l=psb->m_links[i];
|
||||
btSoftBody::Link& l=psb->getLinks()[i];
|
||||
if(l.m_c0>0)
|
||||
{
|
||||
btSoftBody::Node& a=*l.m_n[0];
|
||||
@@ -647,79 +737,26 @@ using namespace btsoftbody_internals;
|
||||
// Api
|
||||
//
|
||||
|
||||
//
|
||||
btSoftBody* btSoftBody::Create( ISoftBody* isoftbody,
|
||||
int node_count,
|
||||
const btVector3* x,
|
||||
const btScalar* m)
|
||||
{
|
||||
btSoftBody* sb=new btSoftBody();
|
||||
/* Init */
|
||||
sb->m_cfg.aeromodel = eAeroModel::V_Point;
|
||||
sb->m_cfg.kDG = 0;
|
||||
sb->m_cfg.kLF = 0;
|
||||
sb->m_cfg.kDP = 0;
|
||||
sb->m_cfg.kPR = 0;
|
||||
sb->m_cfg.kVC = 0;
|
||||
sb->m_cfg.kDF = (btScalar)0.2;
|
||||
sb->m_cfg.kLST = 1;
|
||||
sb->m_cfg.kMT = 0;
|
||||
sb->m_cfg.kSOR = 1;
|
||||
sb->m_cfg.kCHR = (btScalar)1.0;
|
||||
sb->m_cfg.kAHR = (btScalar)0.5;
|
||||
sb->m_cfg.timescale = 1;
|
||||
sb->m_cfg.timestep = (btScalar)(1/60.);
|
||||
sb->m_cfg.maxsteps = 60;
|
||||
sb->m_cfg.iterations = 1;
|
||||
sb->m_cfg.becollide = true;
|
||||
sb->m_cfg.bscollide = false;
|
||||
sb->m_pose.m_bvolume = false;
|
||||
sb->m_pose.m_bframe = false;
|
||||
sb->m_pose.m_volume = 0;
|
||||
sb->m_pose.m_com = btVector3(0,0,0);
|
||||
sb->m_pose.m_trs.setIdentity();
|
||||
sb->m_isb = isoftbody?isoftbody:new ISoftBody();
|
||||
sb->m_tag = 0;
|
||||
sb->m_timeacc = 0;
|
||||
sb->m_bUpdateRtCst = true;
|
||||
sb->m_bounds[0] = btVector3(0,0,0);
|
||||
sb->m_bounds[1] = btVector3(0,0,0);
|
||||
/* Nodes */
|
||||
sb->m_nodes.resize(node_count);
|
||||
for(int i=0,ni=node_count;i<ni;++i)
|
||||
{
|
||||
Node& n=sb->m_nodes[i];
|
||||
memset(&n,0,sizeof(n));
|
||||
n.m_x = x?*x++:btVector3(0,0,0);
|
||||
n.m_q = n.m_x;
|
||||
n.m_im = m?*m++:1;
|
||||
n.m_im = n.m_im>0?1/n.m_im:0;
|
||||
}
|
||||
UpdateTransform(sb);
|
||||
sb->m_isb->Attach(sb);
|
||||
return(sb);
|
||||
}
|
||||
|
||||
//
|
||||
void btSoftBody::Delete()
|
||||
{
|
||||
m_isb->Detach(this);
|
||||
delete this;
|
||||
}
|
||||
|
||||
//
|
||||
bool btSoftBody::CheckLink(int node0,int node1) const
|
||||
{
|
||||
return(CheckLink(&m_nodes[node0],&m_nodes[node1]));
|
||||
return(CheckLink(&getNodes()[node0],&getNodes()[node1]));
|
||||
}
|
||||
|
||||
//
|
||||
bool btSoftBody::CheckLink(const Node* node0,const Node* node1) const
|
||||
{
|
||||
const Node* n[]={node0,node1};
|
||||
for(int i=0,ni=m_links.size();i<ni;++i)
|
||||
for(int i=0,ni=getLinks().size();i<ni;++i)
|
||||
{
|
||||
const Link& l=m_links[i];
|
||||
const Link& l=getLinks()[i];
|
||||
if( (l.m_n[0]==n[0]&&l.m_n[1]==n[1])||
|
||||
(l.m_n[0]==n[1]&&l.m_n[1]==n[0]))
|
||||
{
|
||||
@@ -732,12 +769,12 @@ return(false);
|
||||
//
|
||||
bool btSoftBody::CheckFace(int node0,int node1,int node2) const
|
||||
{
|
||||
const Node* n[]={ &m_nodes[node0],
|
||||
&m_nodes[node1],
|
||||
&m_nodes[node2]};
|
||||
for(int i=0,ni=m_faces.size();i<ni;++i)
|
||||
const Node* n[]={ &getNodes()[node0],
|
||||
&getNodes()[node1],
|
||||
&getNodes()[node2]};
|
||||
for(int i=0,ni=getFaces().size();i<ni;++i)
|
||||
{
|
||||
const Face& f=m_faces[i];
|
||||
const Face& f=getFaces()[i];
|
||||
int c=0;
|
||||
for(int j=0;j<3;++j)
|
||||
{
|
||||
@@ -757,7 +794,7 @@ void btSoftBody::AppendLink( int node0,
|
||||
eLType::_ type,
|
||||
bool bcheckexist)
|
||||
{
|
||||
AppendLink(&m_nodes[node0],&m_nodes[node1],kST,type,bcheckexist);
|
||||
AppendLink(&getNodes()[node0],&getNodes()[node1],kST,type,bcheckexist);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -778,7 +815,7 @@ if((!bcheckexist)||(!CheckLink(node0,node1)))
|
||||
l.m_c1 = 0;
|
||||
l.m_type = type;
|
||||
l.m_tag = 0;
|
||||
m_links.push_back(l);
|
||||
getLinks().push_back(l);
|
||||
m_bUpdateRtCst=true;
|
||||
}
|
||||
}
|
||||
@@ -787,14 +824,14 @@ if((!bcheckexist)||(!CheckLink(node0,node1)))
|
||||
void btSoftBody::AppendFace(int node0,int node1,int node2)
|
||||
{
|
||||
Face f;
|
||||
f.m_n[0] = &m_nodes[node0];
|
||||
f.m_n[1] = &m_nodes[node1];
|
||||
f.m_n[2] = &m_nodes[node2];
|
||||
f.m_n[0] = &getNodes()[node0];
|
||||
f.m_n[1] = &getNodes()[node1];
|
||||
f.m_n[2] = &getNodes()[node2];
|
||||
f.m_ra = AreaOf( f.m_n[0]->m_x,
|
||||
f.m_n[1]->m_x,
|
||||
f.m_n[2]->m_x);
|
||||
f.m_tag = 0;
|
||||
m_faces.push_back(f);
|
||||
getFaces().push_back(f);
|
||||
m_bUpdateRtCst=true;
|
||||
}
|
||||
|
||||
@@ -802,7 +839,7 @@ m_bUpdateRtCst=true;
|
||||
void btSoftBody::AppendAnchor(int node,btRigidBody* body)
|
||||
{
|
||||
Anchor a;
|
||||
a.m_node = &m_nodes[node];
|
||||
a.m_node = &getNodes()[node];
|
||||
a.m_body = body;
|
||||
a.m_local = body->getWorldTransform().inverse()*a.m_node->m_x;
|
||||
a.m_node->m_battach = 1;
|
||||
@@ -812,13 +849,13 @@ m_anchors.push_back(a);
|
||||
//
|
||||
void btSoftBody::AddForce(const btVector3& force)
|
||||
{
|
||||
for(int i=0,ni=m_nodes.size();i<ni;++i) AddForce(force,i);
|
||||
for(int i=0,ni=getNodes().size();i<ni;++i) AddForce(force,i);
|
||||
}
|
||||
|
||||
//
|
||||
void btSoftBody::AddForce(const btVector3& force,int node)
|
||||
{
|
||||
Node& n=m_nodes[node];
|
||||
Node& n=getNodes()[node];
|
||||
if(n.m_im>0)
|
||||
{
|
||||
n.m_f += force;
|
||||
@@ -828,13 +865,13 @@ if(n.m_im>0)
|
||||
//
|
||||
void btSoftBody::AddVelocity(const btVector3& velocity)
|
||||
{
|
||||
for(int i=0,ni=m_nodes.size();i<ni;++i) AddVelocity(velocity,i);
|
||||
for(int i=0,ni=getNodes().size();i<ni;++i) AddVelocity(velocity,i);
|
||||
}
|
||||
|
||||
//
|
||||
void btSoftBody::AddVelocity(const btVector3& velocity,int node)
|
||||
{
|
||||
Node& n=m_nodes[node];
|
||||
Node& n=getNodes()[node];
|
||||
if(n.m_im>0)
|
||||
{
|
||||
n.m_v += velocity;
|
||||
@@ -844,21 +881,21 @@ if(n.m_im>0)
|
||||
//
|
||||
void btSoftBody::SetMass(int node,btScalar mass)
|
||||
{
|
||||
m_nodes[node].m_im=mass>0?1/mass:0;
|
||||
getNodes()[node].m_im=mass>0?1/mass:0;
|
||||
m_bUpdateRtCst=true;
|
||||
}
|
||||
|
||||
//
|
||||
btScalar btSoftBody::GetMass(int node) const
|
||||
{
|
||||
return(m_nodes[node].m_im>0?1/m_nodes[node].m_im:0);
|
||||
return(getNodes()[node].m_im>0?1/getNodes()[node].m_im:0);
|
||||
}
|
||||
|
||||
//
|
||||
btScalar btSoftBody::GetTotalMass() const
|
||||
{
|
||||
btScalar mass=0;
|
||||
for(int i=0;i<m_nodes.size();++i)
|
||||
for(int i=0;i<getNodes().size();++i)
|
||||
{
|
||||
mass+=GetMass(i);
|
||||
}
|
||||
@@ -870,13 +907,13 @@ void btSoftBody::SetTotalMass(btScalar mass,bool fromfaces)
|
||||
{
|
||||
if(fromfaces)
|
||||
{
|
||||
for(int i=0;i<m_nodes.size();++i)
|
||||
for(int i=0;i<getNodes().size();++i)
|
||||
{
|
||||
m_nodes[i].m_im=0;
|
||||
getNodes()[i].m_im=0;
|
||||
}
|
||||
for(int i=0;i<m_faces.size();++i)
|
||||
for(int i=0;i<getFaces().size();++i)
|
||||
{
|
||||
const Face& f=m_faces[i];
|
||||
const Face& f=getFaces()[i];
|
||||
const btScalar twicearea=AreaOf( f.m_n[0]->m_x,
|
||||
f.m_n[1]->m_x,
|
||||
f.m_n[2]->m_x);
|
||||
@@ -885,16 +922,16 @@ if(fromfaces)
|
||||
f.m_n[j]->m_im+=twicearea;
|
||||
}
|
||||
}
|
||||
for(int i=0;i<m_nodes.size();++i)
|
||||
for(int i=0;i<getNodes().size();++i)
|
||||
{
|
||||
m_nodes[i].m_im=1/m_nodes[i].m_im;
|
||||
getNodes()[i].m_im=1/getNodes()[i].m_im;
|
||||
}
|
||||
}
|
||||
const btScalar tm=GetTotalMass();
|
||||
const btScalar itm=1/tm;
|
||||
for(int i=0;i<m_nodes.size();++i)
|
||||
for(int i=0;i<getNodes().size();++i)
|
||||
{
|
||||
m_nodes[i].m_im/=itm*mass;
|
||||
getNodes()[i].m_im/=itm*mass;
|
||||
}
|
||||
m_bUpdateRtCst=true;
|
||||
}
|
||||
@@ -908,29 +945,29 @@ SetTotalMass(GetVolume()*density,true);
|
||||
//
|
||||
void btSoftBody::Transform(const btTransform& trs)
|
||||
{
|
||||
for(int i=0,ni=m_nodes.size();i<ni;++i)
|
||||
for(int i=0,ni=getNodes().size();i<ni;++i)
|
||||
{
|
||||
Node& n=m_nodes[i];
|
||||
Node& n=getNodes()[i];
|
||||
n.m_x=trs*n.m_x;
|
||||
n.m_q=trs*n.m_q;
|
||||
n.m_n=trs.getBasis()*n.m_n;
|
||||
}
|
||||
UpdateNormals(this);
|
||||
UpdateTransform(this);
|
||||
updateTransform();
|
||||
UpdateConstants(this);
|
||||
}
|
||||
|
||||
//
|
||||
void btSoftBody::Scale(const btVector3& scl)
|
||||
{
|
||||
for(int i=0,ni=m_nodes.size();i<ni;++i)
|
||||
for(int i=0,ni=getNodes().size();i<ni;++i)
|
||||
{
|
||||
Node& n=m_nodes[i];
|
||||
Node& n=getNodes()[i];
|
||||
n.m_x*=scl;
|
||||
n.m_q*=scl;
|
||||
}
|
||||
UpdateNormals(this);
|
||||
UpdateTransform(this);
|
||||
updateTransform();
|
||||
UpdateConstants(this);
|
||||
}
|
||||
|
||||
@@ -941,26 +978,26 @@ m_pose.m_bvolume = bvolume;
|
||||
m_pose.m_bframe = bframe;
|
||||
/* Weights */
|
||||
const btScalar omass=GetTotalMass();
|
||||
const btScalar kmass=omass*m_nodes.size()*1000;
|
||||
const btScalar kmass=omass*getNodes().size()*1000;
|
||||
btScalar tmass=omass;
|
||||
m_pose.m_wgh.resize(m_nodes.size());
|
||||
for(int i=0,ni=m_nodes.size();i<ni;++i)
|
||||
m_pose.m_wgh.resize(getNodes().size());
|
||||
for(int i=0,ni=getNodes().size();i<ni;++i)
|
||||
{
|
||||
if(m_nodes[i].m_im<=0) tmass+=kmass;
|
||||
if(getNodes()[i].m_im<=0) tmass+=kmass;
|
||||
}
|
||||
for(int i=0,ni=m_nodes.size();i<ni;++i)
|
||||
for(int i=0,ni=getNodes().size();i<ni;++i)
|
||||
{
|
||||
Node& n=m_nodes[i];
|
||||
Node& n=getNodes()[i];
|
||||
m_pose.m_wgh[i]= n.m_im>0 ?
|
||||
1/(m_nodes[i].m_im*tmass) :
|
||||
1/(getNodes()[i].m_im*tmass) :
|
||||
kmass/tmass;
|
||||
}
|
||||
/* Pos */
|
||||
const btVector3 com=EvaluateCom(this);
|
||||
m_pose.m_pos.resize(m_nodes.size());
|
||||
for(int i=0,ni=m_nodes.size();i<ni;++i)
|
||||
m_pose.m_pos.resize(getNodes().size());
|
||||
for(int i=0,ni=getNodes().size();i<ni;++i)
|
||||
{
|
||||
m_pose.m_pos[i]=m_nodes[i].m_x-com;
|
||||
m_pose.m_pos[i]=getNodes()[i].m_x-com;
|
||||
}
|
||||
m_pose.m_volume = bvolume?GetVolume():0;
|
||||
m_pose.m_com = com;
|
||||
@@ -972,12 +1009,12 @@ UpdateConstants(this);
|
||||
btScalar btSoftBody::GetVolume() const
|
||||
{
|
||||
btScalar vol=0;
|
||||
if(m_nodes.size()>0)
|
||||
if(getNodes().size()>0)
|
||||
{
|
||||
const btVector3 org=m_nodes[0].m_x;
|
||||
for(int i=0,ni=m_faces.size();i<ni;++i)
|
||||
const btVector3 org=getNodes()[0].m_x;
|
||||
for(int i=0,ni=getFaces().size();i<ni;++i)
|
||||
{
|
||||
const Face& f=m_faces[i];
|
||||
const Face& f=getFaces()[i];
|
||||
vol+=dot(f.m_n[0]->m_x-org,cross(f.m_n[1]->m_x-org,f.m_n[2]->m_x-org));
|
||||
}
|
||||
vol/=(btScalar)6;
|
||||
@@ -992,7 +1029,7 @@ int btSoftBody::GenerateBendingConstraints( int distance,
|
||||
if(distance>1)
|
||||
{
|
||||
/* Build graph */
|
||||
const int n=m_nodes.size();
|
||||
const int n=getNodes().size();
|
||||
const unsigned inf=(~(unsigned)0)>>1;
|
||||
unsigned* adj=new unsigned[n*n];
|
||||
#define IDX(_x_,_y_) ((_y_)*n+(_x_))
|
||||
@@ -1005,12 +1042,12 @@ if(distance>1)
|
||||
adj[IDX(i,j)]=adj[IDX(j,i)]=0;
|
||||
}
|
||||
}
|
||||
for(int i=0;i<m_links.size();++i)
|
||||
for(int i=0;i<getLinks().size();++i)
|
||||
{
|
||||
if(m_links[i].m_type==eLType::Structural)
|
||||
if(getLinks()[i].m_type==eLType::Structural)
|
||||
{
|
||||
const int ia=(int)(m_links[i].m_n[0]-&m_nodes[0]);
|
||||
const int ib=(int)(m_links[i].m_n[1]-&m_nodes[0]);
|
||||
const int ia=(int)(getLinks()[i].m_n[0]-&getNodes()[0]);
|
||||
const int ib=(int)(getLinks()[i].m_n[1]-&getNodes()[0]);
|
||||
adj[IDX(ia,ib)]=1;
|
||||
adj[IDX(ib,ia)]=1;
|
||||
}
|
||||
@@ -1051,13 +1088,13 @@ return(0);
|
||||
//
|
||||
void btSoftBody::RandomizeConstraints()
|
||||
{
|
||||
for(int i=0,ni=m_links.size();i<ni;++i)
|
||||
for(int i=0,ni=getLinks().size();i<ni;++i)
|
||||
{
|
||||
btSwap(m_links[i],m_links[rand()%ni]);
|
||||
btSwap(getLinks()[i],getLinks()[rand()%ni]);
|
||||
}
|
||||
for(int i=0,ni=m_faces.size();i<ni;++i)
|
||||
for(int i=0,ni=getFaces().size();i<ni;++i)
|
||||
{
|
||||
btSwap(m_faces[i],m_faces[rand()%ni]);
|
||||
btSwap(getFaces()[i],getFaces()[rand()%ni]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1090,11 +1127,11 @@ while(m_timeacc>=m_cfg.timestep)
|
||||
const btScalar iit = 1/(btScalar)m_cfg.iterations;
|
||||
const btScalar sdt = m_cfg.timestep*m_cfg.timescale;
|
||||
const btScalar isdt = 1/sdt;
|
||||
Node* pnodes = m_nodes.size()>0?&m_nodes[0]:0;
|
||||
Node* pnodes = getNodes().size()>0?&getNodes()[0]:0;
|
||||
/* Forces */
|
||||
ApplyForces(this,sdt);
|
||||
/* Integrate */
|
||||
for(int i=0,ni=m_nodes.size();i<ni;++i)
|
||||
for(int i=0,ni=getNodes().size();i<ni;++i)
|
||||
{
|
||||
Node& n=pnodes[i];
|
||||
n.m_q = n.m_x;
|
||||
@@ -1106,7 +1143,7 @@ while(m_timeacc>=m_cfg.timestep)
|
||||
/* Match */
|
||||
if(m_pose.m_bframe&&(m_cfg.kMT>0))
|
||||
{
|
||||
for(int i=0,ni=m_nodes.size();i<ni;++i)
|
||||
for(int i=0,ni=getNodes().size();i<ni;++i)
|
||||
{
|
||||
Node& n=pnodes[i];
|
||||
if(n.m_im>0)
|
||||
@@ -1119,14 +1156,16 @@ while(m_timeacc>=m_cfg.timestep)
|
||||
}
|
||||
/* External collide */
|
||||
m_contacts.resize(0);
|
||||
|
||||
if(m_cfg.becollide)
|
||||
{
|
||||
m_isb->StartCollide(m_bounds[0],m_bounds[1]);
|
||||
for(int i=0,ni=m_nodes.size();i<ni;++i)
|
||||
StartCollide(m_bounds[0],m_bounds[1]);
|
||||
|
||||
for(int i=0,ni=getNodes().size();i<ni;++i)
|
||||
{
|
||||
Node& n=pnodes[i];
|
||||
Contact c;
|
||||
if((!n.m_battach)&&m_isb->CheckContact(n.m_x,c.m_cti))
|
||||
if((!n.m_battach)&&CheckContact(n.m_x,c.m_cti))
|
||||
{
|
||||
const btRigidBody* prb=c.m_cti.m_body;
|
||||
const btScalar ima=n.m_im;
|
||||
@@ -1152,7 +1191,7 @@ while(m_timeacc>=m_cfg.timestep)
|
||||
}
|
||||
}
|
||||
}
|
||||
m_isb->EndCollide();
|
||||
EndCollide();
|
||||
}
|
||||
/* Prepare anchors */
|
||||
for(int i=0,ni=m_anchors.size();i<ni;++i)
|
||||
@@ -1177,13 +1216,42 @@ while(m_timeacc>=m_cfg.timestep)
|
||||
}
|
||||
/* Velocities */
|
||||
const btScalar vc=isdt*(1-m_cfg.kDP);
|
||||
for(int i=0,ni=m_nodes.size();i<ni;++i)
|
||||
for(int i=0,ni=getNodes().size();i<ni;++i)
|
||||
{
|
||||
pnodes[i].m_v = (pnodes[i].m_x-pnodes[i].m_q)*vc;
|
||||
pnodes[i].m_f = btVector3(0,0,0);
|
||||
}
|
||||
/* Update */
|
||||
UpdateTransform(this);
|
||||
updateTransform();
|
||||
UpdateNormals(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
bool btSoftBody::CheckContact( const btVector3& x,
|
||||
btSoftBody::sCti& cti)
|
||||
{
|
||||
btScalar maxdepth=0;
|
||||
btGjkEpaSolver2::sResults res;
|
||||
for(int i=0,ni=m_overlappingRigidBodies.size();i<ni;++i)
|
||||
{
|
||||
btVector3 nrm;
|
||||
btRigidBody* prb=btRigidBody::upcast(m_overlappingRigidBodies[i]);
|
||||
|
||||
btCollisionShape* shp=prb->getCollisionShape();
|
||||
btConvexShape* csh=static_cast<btConvexShape*>(shp);
|
||||
const btTransform& wtr=prb->getWorldTransform();
|
||||
btScalar dst=m_worldInfo.m_sparsesdf.Evaluate(wtr.invXform(x),csh,nrm);
|
||||
nrm=wtr.getBasis()*nrm;
|
||||
btVector3 wit=x-nrm*dst;
|
||||
if(dst<maxdepth)
|
||||
{
|
||||
maxdepth = dst;
|
||||
cti.m_body = prb;
|
||||
cti.m_normal = nrm;
|
||||
cti.m_offset = -dot(cti.m_normal,wit);
|
||||
}
|
||||
}
|
||||
return(maxdepth<0);
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ subject to the following restrictions:
|
||||
*/
|
||||
///btSoftBody implementation by Nathanael Presson
|
||||
|
||||
#ifndef _312AEEF3_52DA_4ff6_B804_FCF937182E46_
|
||||
#define _312AEEF3_52DA_4ff6_B804_FCF937182E46_
|
||||
#ifndef _BT_SOFT_BODY_H
|
||||
#define _BT_SOFT_BODY_H
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "LinearMath/btPoint3.h"
|
||||
@@ -23,67 +23,100 @@ subject to the following restrictions:
|
||||
#include "LinearMath/btIDebugDraw.h"
|
||||
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
||||
|
||||
//
|
||||
// btSoftBody
|
||||
//
|
||||
struct btSoftBody
|
||||
#include "BulletCollision/CollisionShapes/btConcaveShape.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||
#include "BulletDynamics/SoftBody/btSparseSDF.h"
|
||||
|
||||
class btBroadphaseInterface;
|
||||
class btCollisionDispatcher;
|
||||
|
||||
/// btSoftBody is work-in-progress
|
||||
struct btSoftBody : public btCollisionObject
|
||||
{
|
||||
|
||||
//
|
||||
// Enumerations
|
||||
//
|
||||
|
||||
/* eLType */
|
||||
///eLType
|
||||
struct eLType { enum _ {
|
||||
Structural, /* Master constraints */
|
||||
Bending, /* Secondary constraints */
|
||||
Structural, ///Master constraints
|
||||
Bending, ///Secondary constraints
|
||||
};};
|
||||
|
||||
/* eAeroModel */
|
||||
////eAeroModel
|
||||
struct eAeroModel { enum _ {
|
||||
V_Point, /* Vertex normals are oriented toward velocity */
|
||||
V_TwoSided, /* Vertex normals are fliped to match velocity */
|
||||
V_OneSided, /* Vertex normals are taken as it is */
|
||||
F_TwoSided, /* Face normals are fliped to match velocity */
|
||||
F_OneSided, /* Face normals are taken as it is */
|
||||
V_Point, ///Vertex normals are oriented toward velocity
|
||||
V_TwoSided, ///Vertex normals are fliped to match velocity
|
||||
V_OneSided, ///Vertex normals are taken as it is
|
||||
F_TwoSided, ///Face normals are fliped to match velocity
|
||||
F_OneSided, ///Face normals are taken as it is
|
||||
};};
|
||||
|
||||
//
|
||||
// Interfaces
|
||||
//
|
||||
|
||||
/* ISoftBody */
|
||||
struct ISoftBody
|
||||
struct btSoftBodyWorldInfo
|
||||
{
|
||||
btScalar air_density;
|
||||
btScalar water_density;
|
||||
btScalar water_offset;
|
||||
btVector3 water_normal;
|
||||
btBroadphaseInterface* m_broadphase;
|
||||
btCollisionDispatcher* m_dispatcher;
|
||||
|
||||
btSparseSdf<3> m_sparsesdf;
|
||||
};
|
||||
|
||||
//reference or copy?
|
||||
btSoftBodyWorldInfo& m_worldInfo;
|
||||
|
||||
///constructor
|
||||
|
||||
btSoftBody(btSoftBody::btSoftBodyWorldInfo& worldInfo,int node_count,
|
||||
const btVector3* x,
|
||||
const btScalar* m);
|
||||
|
||||
|
||||
///sCti is Softbody contact info
|
||||
struct sCti
|
||||
{
|
||||
btRigidBody* m_body; /* Rigid body */
|
||||
btVector3 m_normal; /* Outward normal */
|
||||
btScalar m_offset; /* Offset from origin */
|
||||
};
|
||||
|
||||
|
||||
void StartCollide(const btVector3& aabbMin,const btVector3& aabbMax)
|
||||
{
|
||||
//??
|
||||
}
|
||||
void EndCollide()
|
||||
{
|
||||
//??
|
||||
}
|
||||
|
||||
//
|
||||
bool CheckContact( const btVector3& x, btSoftBody::sCti& cti);
|
||||
////
|
||||
|
||||
///destructor
|
||||
virtual ~btSoftBody();
|
||||
|
||||
|
||||
|
||||
struct sMedium
|
||||
{
|
||||
btVector3 m_velocity; /* Velocity */
|
||||
btScalar m_pressure; /* Pressure */
|
||||
btScalar m_density; /* Density */
|
||||
};
|
||||
virtual void Attach(btSoftBody*)
|
||||
{}
|
||||
virtual void Detach(btSoftBody*)
|
||||
{ delete this; }
|
||||
virtual void StartCollide( const btVector3& /*minbounds*/,
|
||||
const btVector3& /*maxbounds*/)
|
||||
{}
|
||||
virtual bool CheckContact (const btVector3& /*position*/,
|
||||
sCti& /*contact*/)
|
||||
{ return(false); }
|
||||
virtual void EndCollide()
|
||||
{}
|
||||
virtual void EvaluateMedium( const btVector3& /*position*/,
|
||||
sMedium& medium)
|
||||
{ medium.m_velocity=btVector3(0,0,0);
|
||||
|
||||
virtual void EvaluateMedium( const btVector3& /*position*/, sMedium& medium)
|
||||
{
|
||||
medium.m_velocity=btVector3(0,0,0);
|
||||
medium.m_pressure=0;
|
||||
medium.m_density=0; }
|
||||
};
|
||||
medium.m_density=0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Internal types
|
||||
@@ -97,7 +130,7 @@ struct btSoftBody
|
||||
{
|
||||
void* m_tag; // User data
|
||||
};
|
||||
/* Node */
|
||||
///Node
|
||||
struct Node : Element
|
||||
{
|
||||
btVector3 m_x; // Position
|
||||
@@ -117,7 +150,7 @@ struct btSoftBody
|
||||
btScalar m_kST; // Stiffness coefficient
|
||||
btScalar m_c0; // (ima+imb)*kLST
|
||||
btScalar m_c1; // rl^2
|
||||
eLType::_ m_type; // Link type
|
||||
btSoftBody::eLType::_ m_type; // Link type
|
||||
};
|
||||
/* Face */
|
||||
struct Face : Element
|
||||
@@ -129,7 +162,7 @@ struct btSoftBody
|
||||
/* Contact */
|
||||
struct Contact
|
||||
{
|
||||
ISoftBody::sCti m_cti; // Contact infos
|
||||
btSoftBody::sCti m_cti; // Contact infos
|
||||
Node* m_node; // Owner node
|
||||
btMatrix3x3 m_c0; // Impulse matrix
|
||||
btVector3 m_c1; // Relative anchor
|
||||
@@ -160,7 +193,7 @@ struct btSoftBody
|
||||
/* Config */
|
||||
struct Config
|
||||
{
|
||||
eAeroModel::_ aeromodel; // Aerodynamic model (default: V_Point)
|
||||
btSoftBody::eAeroModel::_ aeromodel; // Aerodynamic model (default: V_Point)
|
||||
btScalar kLST; // Linear stiffness coefficient [0,1]
|
||||
btScalar kDP; // Damping coefficient [0,1]
|
||||
btScalar kDG; // Drag coefficient [0,+inf]
|
||||
@@ -196,11 +229,99 @@ struct btSoftBody
|
||||
|
||||
Config m_cfg; // Configuration
|
||||
Pose m_pose; // Pose
|
||||
ISoftBody* m_isb; // ISoftBody
|
||||
void* m_tag; // User data
|
||||
|
||||
//////////////////////
|
||||
|
||||
///btSoftBodyCollisionShape is work-in-progress collision shape for softbodies
|
||||
class btSoftBodyCollisionShape : public btConcaveShape
|
||||
{
|
||||
static btVector3 m_sScaling;
|
||||
public:
|
||||
|
||||
tNodeArray m_nodes; // Nodes
|
||||
tLinkArray m_links; // Links
|
||||
tFaceArray m_faces; // Faces
|
||||
|
||||
btSoftBodyCollisionShape();
|
||||
|
||||
virtual ~btSoftBodyCollisionShape();
|
||||
|
||||
virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
|
||||
|
||||
///getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t.
|
||||
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
|
||||
{
|
||||
///not yet
|
||||
btAssert(0);
|
||||
}
|
||||
|
||||
virtual int getShapeType() const
|
||||
{
|
||||
return SOFTBODY_SHAPE_PROXYTYPE;
|
||||
}
|
||||
virtual void setLocalScaling(const btVector3& scaling)
|
||||
{
|
||||
///not yet
|
||||
btAssert(0);
|
||||
}
|
||||
virtual const btVector3& getLocalScaling() const
|
||||
{
|
||||
///not yet
|
||||
btAssert(0);
|
||||
return m_sScaling;
|
||||
}
|
||||
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const
|
||||
{
|
||||
///not yet
|
||||
btAssert(0);
|
||||
}
|
||||
virtual const char* getName()const
|
||||
{
|
||||
return "SoftBody";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
btSoftBodyCollisionShape* m_softBodyCollisionShape;
|
||||
|
||||
btCollisionObjectArray m_overlappingRigidBodies;
|
||||
|
||||
btAlignedObjectArray<btSoftBody*> m_overlappingSoftBodies;
|
||||
|
||||
|
||||
//////////////////////
|
||||
|
||||
inline tNodeArray& getNodes()
|
||||
{
|
||||
return m_softBodyCollisionShape->m_nodes;
|
||||
}
|
||||
inline const tNodeArray& getNodes() const
|
||||
{
|
||||
return m_softBodyCollisionShape->m_nodes;
|
||||
}
|
||||
|
||||
inline tLinkArray& getLinks()
|
||||
{
|
||||
return m_softBodyCollisionShape->m_links;
|
||||
}
|
||||
inline const tLinkArray& getLinks() const
|
||||
{
|
||||
return m_softBodyCollisionShape->m_links;
|
||||
}
|
||||
|
||||
inline tFaceArray& getFaces()
|
||||
{
|
||||
return m_softBodyCollisionShape->m_faces;
|
||||
}
|
||||
|
||||
inline const tFaceArray& getFaces() const
|
||||
{
|
||||
return m_softBodyCollisionShape->m_faces;
|
||||
}
|
||||
|
||||
|
||||
tAnchorArray m_anchors; // Anchors
|
||||
tContactArray m_contacts; // Contacts
|
||||
btScalar m_timeacc; // Time accumulator
|
||||
@@ -211,11 +332,6 @@ struct btSoftBody
|
||||
// Api
|
||||
//
|
||||
|
||||
/* Create a soft body */
|
||||
static btSoftBody* Create( ISoftBody* isoftbody,
|
||||
int node_count,
|
||||
const btVector3* x=0,
|
||||
const btScalar* m=0);
|
||||
/* Delete a body */
|
||||
void Delete();
|
||||
/* Check for existing link */
|
||||
@@ -287,70 +403,16 @@ struct btSoftBody
|
||||
/* Step */
|
||||
void Step( btScalar dt);
|
||||
|
||||
void updateBounds();
|
||||
|
||||
void updateTransform()
|
||||
{
|
||||
updateBounds();
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Helpers
|
||||
//
|
||||
|
||||
/* fDrawFlags */
|
||||
struct fDrawFlags { enum _ {
|
||||
Nodes = 0x0001,
|
||||
SLinks = 0x0002,
|
||||
BLinks = 0x0004,
|
||||
Faces = 0x0008,
|
||||
Tetras = 0x0010,
|
||||
Normals = 0x0020,
|
||||
Contacts = 0x0040,
|
||||
Anchors = 0x0080,
|
||||
/* presets */
|
||||
Links = SLinks+BLinks,
|
||||
Std = SLinks+Faces+Anchors,
|
||||
StdTetra = Std-Faces+Tetras,
|
||||
};};
|
||||
|
||||
/* Draw body */
|
||||
void Draw( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
int drawflags=fDrawFlags::Std);
|
||||
/* Draw body infos */
|
||||
void DrawInfos( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
bool masses,
|
||||
bool areas,
|
||||
bool stress);
|
||||
/* Draw rigid frame */
|
||||
void DrawFrame( btSoftBody* psb,
|
||||
btIDebugDraw* idraw);
|
||||
/* Create a rope */
|
||||
btSoftBody* CreateRope( btSoftBody::ISoftBody* isoftbody,
|
||||
const btVector3& from,
|
||||
const btVector3& to,
|
||||
int res,
|
||||
int fixeds);
|
||||
/* Create a patch */
|
||||
btSoftBody* CreatePatch( btSoftBody::ISoftBody* isoftbody,
|
||||
const btVector3& corner00,
|
||||
const btVector3& corner10,
|
||||
const btVector3& corner01,
|
||||
const btVector3& corner11,
|
||||
int resx,
|
||||
int resy,
|
||||
int fixeds,
|
||||
bool gendiags);
|
||||
/* Create an ellipsoid */
|
||||
btSoftBody* CreateEllipsoid(btSoftBody::ISoftBody* isoftbody,
|
||||
const btVector3& center,
|
||||
const btVector3& radius,
|
||||
int res);
|
||||
/* Create from convex-hull */
|
||||
btSoftBody* CreateFromConvexHull( btSoftBody::ISoftBody* isoftbody,
|
||||
const btVector3* vertices,
|
||||
int nvertices);
|
||||
/* Create from trimesh */
|
||||
btSoftBody* CreateFromTriMesh( btSoftBody::ISoftBody* isoftbody,
|
||||
const btScalar* vertices,
|
||||
const int* triangles,
|
||||
int ntriangles);
|
||||
|
||||
#endif
|
||||
#endif //_BT_SOFT_BODY_H
|
||||
|
||||
@@ -17,12 +17,10 @@ subject to the following restrictions:
|
||||
#include "btSoftBody.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace btsoftbody_internals
|
||||
{
|
||||
#include "btSoftBodyHelpers.h"
|
||||
|
||||
//
|
||||
static void drawVertex( btIDebugDraw* idraw,
|
||||
void btSoftBodyHelpers::drawVertex( btIDebugDraw* idraw,
|
||||
const btVector3& x,btScalar s,const btVector3& c)
|
||||
{
|
||||
idraw->drawLine(x-btVector3(s,0,0),x+btVector3(s,0,0),c);
|
||||
@@ -31,7 +29,7 @@ idraw->drawLine(x-btVector3(0,0,s),x+btVector3(0,0,s),c);
|
||||
}
|
||||
|
||||
//
|
||||
static btVector3 stresscolor(btScalar stress)
|
||||
btVector3 btSoftBodyHelpers::stresscolor(btScalar stress)
|
||||
{
|
||||
static const btVector3 spectrum[]= {
|
||||
btVector3(1,0,1),
|
||||
@@ -50,12 +48,10 @@ const btScalar frc=stress-sel;
|
||||
return(spectrum[sel]+(spectrum[sel+1]-spectrum[sel])*frc);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using namespace btsoftbody_internals;
|
||||
|
||||
//
|
||||
void Draw( btSoftBody* psb,
|
||||
void btSoftBodyHelpers::Draw( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
int drawflags)
|
||||
{
|
||||
@@ -69,9 +65,9 @@ const btVector3 ccolor=btVector3(1,0,0);
|
||||
/* Nodes */
|
||||
if(0!=(drawflags&fDrawFlags::Nodes))
|
||||
{
|
||||
for(int i=0;i<psb->m_nodes.size();++i)
|
||||
for(int i=0;i<psb->getNodes().size();++i)
|
||||
{
|
||||
const btSoftBody::Node& n=psb->m_nodes[i];
|
||||
const btSoftBody::Node& n=psb->getNodes()[i];
|
||||
idraw->drawLine(n.m_x-btVector3(scl,0,0),n.m_x+btVector3(scl,0,0),btVector3(1,0,0));
|
||||
idraw->drawLine(n.m_x-btVector3(0,scl,0),n.m_x+btVector3(0,scl,0),btVector3(0,1,0));
|
||||
idraw->drawLine(n.m_x-btVector3(0,0,scl),n.m_x+btVector3(0,0,scl),btVector3(0,0,1));
|
||||
@@ -80,9 +76,9 @@ if(0!=(drawflags&fDrawFlags::Nodes))
|
||||
/* Links */
|
||||
if(0!=(drawflags&fDrawFlags::Links))
|
||||
{
|
||||
for(int i=0;i<psb->m_links.size();++i)
|
||||
for(int i=0;i<psb->getLinks().size();++i)
|
||||
{
|
||||
const btSoftBody::Link& l=psb->m_links[i];
|
||||
const btSoftBody::Link& l=psb->getLinks()[i];
|
||||
switch(l.m_type)
|
||||
{
|
||||
case btSoftBody::eLType::Structural:
|
||||
@@ -95,9 +91,9 @@ if(0!=(drawflags&fDrawFlags::Links))
|
||||
/* Normals */
|
||||
if(0!=(drawflags&fDrawFlags::Normals))
|
||||
{
|
||||
for(int i=0;i<psb->m_nodes.size();++i)
|
||||
for(int i=0;i<psb->getNodes().size();++i)
|
||||
{
|
||||
const btSoftBody::Node& n=psb->m_nodes[i];
|
||||
const btSoftBody::Node& n=psb->getNodes()[i];
|
||||
const btVector3 d=n.m_n*nscl;
|
||||
idraw->drawLine(n.m_x,n.m_x+d,ncolor);
|
||||
idraw->drawLine(n.m_x,n.m_x-d,ncolor*0.5);
|
||||
@@ -132,9 +128,9 @@ if(0!=(drawflags&fDrawFlags::Anchors))
|
||||
drawVertex(idraw,q,0.25,btVector3(0,1,0));
|
||||
idraw->drawLine(a.m_node->m_x,q,btVector3(1,1,1));
|
||||
}
|
||||
for(int i=0;i<psb->m_nodes.size();++i)
|
||||
for(int i=0;i<psb->getNodes().size();++i)
|
||||
{
|
||||
const btSoftBody::Node& n=psb->m_nodes[i];
|
||||
const btSoftBody::Node& n=psb->getNodes()[i];
|
||||
if(n.m_im<=0)
|
||||
{
|
||||
drawVertex(idraw,n.m_x,0.25,btVector3(1,0,0));
|
||||
@@ -147,9 +143,9 @@ if(0!=(drawflags&fDrawFlags::Faces))
|
||||
const btScalar scl=(btScalar)0.7;
|
||||
const btScalar alp=(btScalar)1;
|
||||
const btVector3 col(0,(btScalar)0.7,0);
|
||||
for(int i=0;i<psb->m_faces.size();++i)
|
||||
for(int i=0;i<psb->getFaces().size();++i)
|
||||
{
|
||||
const btSoftBody::Face& f=psb->m_faces[i];
|
||||
const btSoftBody::Face& f=psb->getFaces()[i];
|
||||
const btVector3 x[]={f.m_n[0]->m_x,f.m_n[1]->m_x,f.m_n[2]->m_x};
|
||||
const btVector3 c=(x[0]+x[1]+x[2])/3;
|
||||
idraw->drawTriangle((x[0]-c)*scl+c,
|
||||
@@ -162,15 +158,15 @@ if(0!=(drawflags&fDrawFlags::Faces))
|
||||
}
|
||||
|
||||
//
|
||||
void DrawInfos( btSoftBody* psb,
|
||||
void btSoftBodyHelpers::DrawInfos( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
bool masses,
|
||||
bool areas,
|
||||
bool stress)
|
||||
{
|
||||
for(int i=0;i<psb->m_nodes.size();++i)
|
||||
for(int i=0;i<psb->getNodes().size();++i)
|
||||
{
|
||||
const btSoftBody::Node& n=psb->m_nodes[i];
|
||||
const btSoftBody::Node& n=psb->getNodes()[i];
|
||||
char text[2048]={0};
|
||||
char buff[1024];
|
||||
if(masses)
|
||||
@@ -188,7 +184,7 @@ for(int i=0;i<psb->m_nodes.size();++i)
|
||||
}
|
||||
|
||||
//
|
||||
void DrawFrame( btSoftBody* psb,
|
||||
void btSoftBodyHelpers::DrawFrame( btSoftBody* psb,
|
||||
btIDebugDraw* idraw)
|
||||
{
|
||||
if(psb->m_pose.m_bframe)
|
||||
@@ -214,8 +210,7 @@ if(psb->m_pose.m_bframe)
|
||||
}
|
||||
|
||||
//
|
||||
btSoftBody* CreateRope( btSoftBody::ISoftBody* isoftbody,
|
||||
const btVector3& from,
|
||||
btSoftBody* btSoftBodyHelpers::CreateRope( btSoftBody::btSoftBodyWorldInfo& worldInfo, const btVector3& from,
|
||||
const btVector3& to,
|
||||
int res,
|
||||
int fixeds)
|
||||
@@ -230,7 +225,7 @@ for(int i=0;i<r;++i)
|
||||
x[i]=lerp(from,to,t);
|
||||
m[i]=1;
|
||||
}
|
||||
btSoftBody* psb=btSoftBody::Create(isoftbody,r,x,m);
|
||||
btSoftBody* psb= new btSoftBody(worldInfo,r,x,m);
|
||||
if(fixeds&1) psb->SetMass(0,0);
|
||||
if(fixeds&2) psb->SetMass(r-1,0);
|
||||
delete[] x;
|
||||
@@ -245,8 +240,7 @@ return(psb);
|
||||
}
|
||||
|
||||
//
|
||||
btSoftBody* CreatePatch( btSoftBody::ISoftBody* isoftbody,
|
||||
const btVector3& corner00,
|
||||
btSoftBody* btSoftBodyHelpers::CreatePatch(btSoftBody::btSoftBodyWorldInfo& worldInfo,const btVector3& corner00,
|
||||
const btVector3& corner10,
|
||||
const btVector3& corner01,
|
||||
const btVector3& corner11,
|
||||
@@ -275,7 +269,7 @@ for(int iy=0;iy<ry;++iy)
|
||||
m[IDX(ix,iy)]=1;
|
||||
}
|
||||
}
|
||||
btSoftBody* psb=btSoftBody::Create(isoftbody,tot,x,m);
|
||||
btSoftBody* psb=new btSoftBody(worldInfo,tot,x,m);
|
||||
if(fixeds&1) psb->SetMass(IDX(0,0),0);
|
||||
if(fixeds&2) psb->SetMass(IDX(rx-1,0),0);
|
||||
if(fixeds&4) psb->SetMass(IDX(0,ry-1),0);
|
||||
@@ -325,8 +319,7 @@ return(psb);
|
||||
}
|
||||
|
||||
//
|
||||
btSoftBody* CreateEllipsoid(btSoftBody::ISoftBody* isoftbody,
|
||||
const btVector3& center,
|
||||
btSoftBody* btSoftBodyHelpers::CreateEllipsoid(btSoftBody::btSoftBodyWorldInfo& worldInfo,const btVector3& center,
|
||||
const btVector3& radius,
|
||||
int res)
|
||||
{
|
||||
@@ -352,14 +345,13 @@ for(int i=0;i<vtx.size();++i)
|
||||
{
|
||||
vtx[i]=vtx[i]*radius+center;
|
||||
}
|
||||
return(CreateFromConvexHull(isoftbody,&vtx[0],vtx.size()));
|
||||
return(CreateFromConvexHull(worldInfo,&vtx[0],vtx.size()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
btSoftBody* CreateFromTriMesh( btSoftBody::ISoftBody* isoftbody,
|
||||
const btScalar* vertices,
|
||||
btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBody::btSoftBodyWorldInfo& worldInfo,const btScalar* vertices,
|
||||
const int* triangles,
|
||||
int ntriangles)
|
||||
{
|
||||
@@ -377,7 +369,7 @@ for(int i=0,j=0,ni=maxidx*3;i<ni;++j,i+=3)
|
||||
{
|
||||
vtx[j]=btVector3(vertices[i],vertices[i+1],vertices[i+2]);
|
||||
}
|
||||
btSoftBody* psb=btSoftBody::Create(isoftbody,vtx.size(),&vtx[0],0);
|
||||
btSoftBody* psb=new btSoftBody(worldInfo,vtx.size(),&vtx[0],0);
|
||||
for(int i=0,ni=ntriangles*3;i<ni;i+=3)
|
||||
{
|
||||
const int idx[]={triangles[i],triangles[i+1],triangles[i+2]};
|
||||
|
||||
90
src/BulletDynamics/SoftBody/btSoftBodyHelpers.h
Normal file
90
src/BulletDynamics/SoftBody/btSoftBodyHelpers.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2008 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SOFT_BODY_HELPERS_H
|
||||
#define SOFT_BODY_HELPERS_H
|
||||
|
||||
#include "btSoftBody.h"
|
||||
|
||||
//
|
||||
// Helpers
|
||||
//
|
||||
|
||||
/* fDrawFlags */
|
||||
struct fDrawFlags { enum _ {
|
||||
Nodes = 0x0001,
|
||||
SLinks = 0x0002,
|
||||
BLinks = 0x0004,
|
||||
Faces = 0x0008,
|
||||
Tetras = 0x0010,
|
||||
Normals = 0x0020,
|
||||
Contacts = 0x0040,
|
||||
Anchors = 0x0080,
|
||||
/* presets */
|
||||
Links = SLinks+BLinks,
|
||||
Std = SLinks+Faces+Anchors,
|
||||
StdTetra = Std-Faces+Tetras,
|
||||
};};
|
||||
|
||||
struct btSoftBodyHelpers
|
||||
{
|
||||
|
||||
static btVector3 stresscolor(btScalar stress);
|
||||
|
||||
static void drawVertex( btIDebugDraw* idraw,
|
||||
const btVector3& x,btScalar s,const btVector3& c);
|
||||
|
||||
|
||||
/* Draw body */
|
||||
static void Draw( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
int drawflags=fDrawFlags::Std);
|
||||
/* Draw body infos */
|
||||
static void DrawInfos( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
bool masses,
|
||||
bool areas,
|
||||
bool stress);
|
||||
/* Draw rigid frame */
|
||||
static void DrawFrame( btSoftBody* psb,
|
||||
btIDebugDraw* idraw);
|
||||
/* Create a rope */
|
||||
static btSoftBody* CreateRope( btSoftBody::btSoftBodyWorldInfo& worldInfo,const btVector3& from,
|
||||
const btVector3& to,
|
||||
int res,
|
||||
int fixeds);
|
||||
/* Create a patch */
|
||||
static btSoftBody* CreatePatch( btSoftBody::btSoftBodyWorldInfo& worldInfo,const btVector3& corner00,
|
||||
const btVector3& corner10,
|
||||
const btVector3& corner01,
|
||||
const btVector3& corner11,
|
||||
int resx,
|
||||
int resy,
|
||||
int fixeds,
|
||||
bool gendiags);
|
||||
/* Create an ellipsoid */
|
||||
static btSoftBody* CreateEllipsoid(btSoftBody::btSoftBodyWorldInfo& worldInfo,const btVector3& center,
|
||||
const btVector3& radius,
|
||||
int res);
|
||||
/* Create from convex-hull */
|
||||
static btSoftBody* CreateFromConvexHull( btSoftBody::btSoftBodyWorldInfo& worldInfo, const btVector3* vertices,
|
||||
int nvertices);
|
||||
/* Create from trimesh */
|
||||
static btSoftBody* CreateFromTriMesh( btSoftBody::btSoftBodyWorldInfo& worldInfo, const btScalar* vertices,
|
||||
const int* triangles,
|
||||
int ntriangles);
|
||||
};
|
||||
|
||||
#endif //SOFT_BODY_HELPERS_H
|
||||
Reference in New Issue
Block a user