+Added btDbvtBroadphase, this very fast/efficient broadphase is based on Dynamic AABB tree (btDbvt).
+SoftBody improvements by Nathanael Presson: +Add tetrahedralization +Add support for tearing/slicing cloth and deformable volumes. Uncomment the line in Bullet/src/BulletSoftBody/btSoftBodyHelpers.h: //#define BT_SOFTBODY_USE_STL 1
This commit is contained in:
@@ -34,6 +34,21 @@ void GLDebugDrawer::drawLine(const btVector3& from,const btVector3& to,const btV
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLDebugDrawer::drawTriangle(const btVector3& a,const btVector3& b,const btVector3& c,const btVector3& color,btScalar alpha)
|
||||||
|
{
|
||||||
|
// if (m_debugMode > 0)
|
||||||
|
{
|
||||||
|
const btVector3 n=cross(b-a,c-a).normalized();
|
||||||
|
glBegin(GL_TRIANGLES);
|
||||||
|
glColor4f(color.getX(), color.getY(), color.getZ(),alpha);
|
||||||
|
glNormal3d(n.getX(),n.getY(),n.getZ());
|
||||||
|
glVertex3d(a.getX(),a.getY(),a.getZ());
|
||||||
|
glVertex3d(b.getX(),b.getY(),b.getZ());
|
||||||
|
glVertex3d(c.getX(),c.getY(),c.getZ());
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GLDebugDrawer::setDebugMode(int debugMode)
|
void GLDebugDrawer::setDebugMode(int debugMode)
|
||||||
{
|
{
|
||||||
m_debugMode = debugMode;
|
m_debugMode = debugMode;
|
||||||
@@ -76,3 +91,4 @@ void GLDebugDrawer::drawContactPoint(const btVector3& pointOnB,const btVector3&
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ public:
|
|||||||
|
|
||||||
virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color);
|
virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color);
|
||||||
|
|
||||||
|
virtual void drawTriangle(const btVector3& a,const btVector3& b,const btVector3& c,const btVector3& color,btScalar alpha);
|
||||||
|
|
||||||
virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color);
|
virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color);
|
||||||
|
|
||||||
virtual void reportErrorWarning(const char* warningString);
|
virtual void reportErrorWarning(const char* warningString);
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ void SoftDemo::clientMoveAndDisplay()
|
|||||||
|
|
||||||
if (m_dynamicsWorld)
|
if (m_dynamicsWorld)
|
||||||
{
|
{
|
||||||
//#define FIXED_STEP
|
#define FIXED_STEP
|
||||||
#ifdef FIXED_STEP
|
#ifdef FIXED_STEP
|
||||||
m_dynamicsWorld->stepSimulation(dt=1.0f/60.f,0);
|
m_dynamicsWorld->stepSimulation(dt=1.0f/60.f,0);
|
||||||
|
|
||||||
@@ -186,7 +186,36 @@ void SoftDemo::displayCallback(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// ImplicitShape
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
struct ImplicitSphere : btSoftBody::ImplicitFn
|
||||||
|
{
|
||||||
|
btVector3 center;
|
||||||
|
btScalar sqradius;
|
||||||
|
ImplicitSphere() {}
|
||||||
|
ImplicitSphere(const btVector3& c,btScalar r) : center(c),sqradius(r*r) {}
|
||||||
|
btScalar Eval(const btVector3& x)
|
||||||
|
{
|
||||||
|
return((x-center).length2()-sqradius);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tetra meshes
|
||||||
|
//
|
||||||
|
|
||||||
|
struct TetraBunny
|
||||||
|
{
|
||||||
|
#include "bunny.inl"
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TetraCube
|
||||||
|
{
|
||||||
|
#include "cube.inl"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -282,7 +311,7 @@ static btSoftBody* Ctor_SoftBox(SoftDemo* pdemo,const btVector3& p,const btVecto
|
|||||||
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=btSoftBodyHelpers::CreateFromConvexHull(pdemo->m_softBodyWorldInfo,c,8);
|
btSoftBody* psb=btSoftBodyHelpers::CreateFromConvexHull(pdemo->m_softBodyWorldInfo,c,8);
|
||||||
psb->generateBendingConstraints(2,1);
|
psb->generateBendingConstraints(2);
|
||||||
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
||||||
|
|
||||||
return(psb);
|
return(psb);
|
||||||
@@ -300,7 +329,7 @@ static btSoftBody* Ctor_SoftBoulder(SoftDemo* pdemo,const btVector3& p,const btV
|
|||||||
pts.push_back(Vector3Rand()*s+p);
|
pts.push_back(Vector3Rand()*s+p);
|
||||||
}
|
}
|
||||||
btSoftBody* psb=btSoftBodyHelpers::CreateFromConvexHull(pdemo->m_softBodyWorldInfo,&pts[0],pts.size());
|
btSoftBody* psb=btSoftBodyHelpers::CreateFromConvexHull(pdemo->m_softBodyWorldInfo,&pts[0],pts.size());
|
||||||
psb->generateBendingConstraints(2,1);
|
psb->generateBendingConstraints(2);
|
||||||
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
||||||
|
|
||||||
return(psb);
|
return(psb);
|
||||||
@@ -321,8 +350,8 @@ static void Init_Ropes(SoftDemo* pdemo)
|
|||||||
btVector3(10,0,i*0.25),
|
btVector3(10,0,i*0.25),
|
||||||
16,
|
16,
|
||||||
1+2);
|
1+2);
|
||||||
psb->m_cfg.iterations = 4;
|
psb->m_cfg.piterations = 4;
|
||||||
psb->m_cfg.kLST = 0.1+(i/(btScalar)(n-1))*0.9;
|
psb->m_materials[0]->m_kLST = 0.1+(i/(btScalar)(n-1))*0.9;
|
||||||
psb->setTotalMass(20);
|
psb->setTotalMass(20);
|
||||||
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
||||||
|
|
||||||
@@ -335,6 +364,7 @@ static void Init_Ropes(SoftDemo* pdemo)
|
|||||||
static void Init_RopeAttach(SoftDemo* pdemo)
|
static void Init_RopeAttach(SoftDemo* pdemo)
|
||||||
{
|
{
|
||||||
//TRACEDEMO
|
//TRACEDEMO
|
||||||
|
pdemo->m_softBodyWorldInfo.m_sparsesdf.RemoveReferences(0);
|
||||||
struct Functors
|
struct Functors
|
||||||
{
|
{
|
||||||
static btSoftBody* CtorRope(SoftDemo* pdemo,const btVector3& p)
|
static btSoftBody* CtorRope(SoftDemo* pdemo,const btVector3& p)
|
||||||
@@ -351,8 +381,8 @@ static void Init_RopeAttach(SoftDemo* pdemo)
|
|||||||
btRigidBody* body=pdemo->localCreateRigidBody(50,startTransform,new btBoxShape(btVector3(2,6,2)));
|
btRigidBody* body=pdemo->localCreateRigidBody(50,startTransform,new btBoxShape(btVector3(2,6,2)));
|
||||||
btSoftBody* psb0=Functors::CtorRope(pdemo,btVector3(0,8,-1));
|
btSoftBody* psb0=Functors::CtorRope(pdemo,btVector3(0,8,-1));
|
||||||
btSoftBody* psb1=Functors::CtorRope(pdemo,btVector3(0,8,+1));
|
btSoftBody* psb1=Functors::CtorRope(pdemo,btVector3(0,8,+1));
|
||||||
psb0->appendAnchor(psb0->getNodes().size()-1,body);
|
psb0->appendAnchor(psb0->m_nodes.size()-1,body);
|
||||||
psb1->appendAnchor(psb1->getNodes().size()-1,body);
|
psb1->appendAnchor(psb1->m_nodes.size()-1,body);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -376,6 +406,7 @@ static void Init_ClothAttach(SoftDemo* pdemo)
|
|||||||
btRigidBody* body=pdemo->localCreateRigidBody(20,startTransform,new btBoxShape(btVector3(s,1,3)));
|
btRigidBody* body=pdemo->localCreateRigidBody(20,startTransform,new btBoxShape(btVector3(s,1,3)));
|
||||||
psb->appendAnchor(0,body);
|
psb->appendAnchor(0,body);
|
||||||
psb->appendAnchor(r-1,body);
|
psb->appendAnchor(r-1,body);
|
||||||
|
pdemo->m_cutting=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -409,8 +440,8 @@ static void Init_Collide(SoftDemo* pdemo)
|
|||||||
btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVertices,
|
btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVertices,
|
||||||
&gIndices[0][0],
|
&gIndices[0][0],
|
||||||
NUM_TRIANGLES);
|
NUM_TRIANGLES);
|
||||||
psb->generateBendingConstraints(2,1);
|
psb->generateBendingConstraints(2);
|
||||||
psb->m_cfg.iterations=2;
|
psb->m_cfg.piterations=2;
|
||||||
psb->m_cfg.collisions|=btSoftBody::fCollision::VF_SS;
|
psb->m_cfg.collisions|=btSoftBody::fCollision::VF_SS;
|
||||||
psb->randomizeConstraints();
|
psb->randomizeConstraints();
|
||||||
btMatrix3x3 m;
|
btMatrix3x3 m;
|
||||||
@@ -426,6 +457,7 @@ static void Init_Collide(SoftDemo* pdemo)
|
|||||||
{
|
{
|
||||||
Functor::Create(pdemo,btVector3(3*i,2,0),btVector3(SIMD_PI/2*(1-(i&1)),SIMD_PI/2*(i&1),0));
|
Functor::Create(pdemo,btVector3(3*i,2,0),btVector3(SIMD_PI/2*(1-(i&1)),SIMD_PI/2*(i&1),0));
|
||||||
}
|
}
|
||||||
|
pdemo->m_cutting=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -441,8 +473,11 @@ static void Init_Collide2(SoftDemo* pdemo)
|
|||||||
btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVerticesBunny,
|
btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVerticesBunny,
|
||||||
&gIndicesBunny[0][0],
|
&gIndicesBunny[0][0],
|
||||||
BUNNY_NUM_TRIANGLES);
|
BUNNY_NUM_TRIANGLES);
|
||||||
psb->generateBendingConstraints(2,0.5);
|
btSoftBody::Material* pm=psb->appendMaterial();
|
||||||
psb->m_cfg.iterations = 2;
|
pm->m_kLST = 0.5;
|
||||||
|
pm->m_flags -= btSoftBody::fMaterial::DebugDraw;
|
||||||
|
psb->generateBendingConstraints(2,pm);
|
||||||
|
psb->m_cfg.piterations = 2;
|
||||||
psb->m_cfg.kDF = 0.5;
|
psb->m_cfg.kDF = 0.5;
|
||||||
psb->m_cfg.collisions |= btSoftBody::fCollision::VF_SS;
|
psb->m_cfg.collisions |= btSoftBody::fCollision::VF_SS;
|
||||||
psb->randomizeConstraints();
|
psb->randomizeConstraints();
|
||||||
@@ -459,6 +494,7 @@ static void Init_Collide2(SoftDemo* pdemo)
|
|||||||
{
|
{
|
||||||
Functor::Create(pdemo,btVector3(0,-1+5*i,0),btVector3(0,SIMD_PI/2*(i&1),0));
|
Functor::Create(pdemo,btVector3(0,-1+5*i,0),btVector3(0,SIMD_PI/2*(i&1),0));
|
||||||
}
|
}
|
||||||
|
pdemo->m_cutting=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -474,25 +510,29 @@ static void Init_Collide3(SoftDemo* pdemo)
|
|||||||
btVector3(-s,0,+s),
|
btVector3(-s,0,+s),
|
||||||
btVector3(+s,0,+s),
|
btVector3(+s,0,+s),
|
||||||
15,15,1+2+4+8,true);
|
15,15,1+2+4+8,true);
|
||||||
psb->m_cfg.kLST = 0.4;
|
psb->m_materials[0]->m_kLST = 0.4;
|
||||||
psb->m_cfg.collisions |= btSoftBody::fCollision::VF_SS;
|
psb->m_cfg.collisions |= btSoftBody::fCollision::VF_SS;
|
||||||
psb->setTotalMass(150);
|
psb->setTotalMass(150);
|
||||||
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const btScalar s=4;
|
const btScalar s=4;
|
||||||
const btVector3 o=btVector3(4,10,0);
|
const btVector3 o=btVector3(5,10,0);
|
||||||
btSoftBody* psb=btSoftBodyHelpers::CreatePatch( pdemo->m_softBodyWorldInfo,
|
btSoftBody* psb=btSoftBodyHelpers::CreatePatch( pdemo->m_softBodyWorldInfo,
|
||||||
btVector3(-s,0,-s)+o,
|
btVector3(-s,0,-s)+o,
|
||||||
btVector3(+s,0,-s)+o,
|
btVector3(+s,0,-s)+o,
|
||||||
btVector3(-s,0,+s)+o,
|
btVector3(-s,0,+s)+o,
|
||||||
btVector3(+s,0,+s)+o,
|
btVector3(+s,0,+s)+o,
|
||||||
7,7,0,true);
|
7,7,0,true);
|
||||||
psb->generateBendingConstraints(2,0.5);
|
btSoftBody::Material* pm=psb->appendMaterial();
|
||||||
psb->m_cfg.kLST = 0.4;
|
pm->m_kLST = 0.1;
|
||||||
|
pm->m_flags -= btSoftBody::fMaterial::DebugDraw;
|
||||||
|
psb->generateBendingConstraints(2,pm);
|
||||||
|
psb->m_materials[0]->m_kLST = 0.5;
|
||||||
psb->m_cfg.collisions |= btSoftBody::fCollision::VF_SS;
|
psb->m_cfg.collisions |= btSoftBody::fCollision::VF_SS;
|
||||||
psb->setTotalMass(150);
|
psb->setTotalMass(150);
|
||||||
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
||||||
|
pdemo->m_cutting=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -514,7 +554,7 @@ static void Init_Aero(SoftDemo* pdemo)
|
|||||||
btVector3(+s,h,+s),
|
btVector3(+s,h,+s),
|
||||||
segments,segments,
|
segments,segments,
|
||||||
0,true);
|
0,true);
|
||||||
psb->generateBendingConstraints(2,1);
|
psb->generateBendingConstraints(2);
|
||||||
psb->m_cfg.kLF = 0.004;
|
psb->m_cfg.kLF = 0.004;
|
||||||
psb->m_cfg.kDG = 0.0003;
|
psb->m_cfg.kDG = 0.0003;
|
||||||
psb->m_cfg.aeromodel = btSoftBody::eAeroModel::V_TwoSided;
|
psb->m_cfg.aeromodel = btSoftBody::eAeroModel::V_TwoSided;
|
||||||
@@ -561,7 +601,7 @@ static void Init_Pressure(SoftDemo* pdemo)
|
|||||||
btSoftBody* psb=btSoftBodyHelpers::CreateEllipsoid(pdemo->m_softBodyWorldInfo,btVector3(35,25,0),
|
btSoftBody* psb=btSoftBodyHelpers::CreateEllipsoid(pdemo->m_softBodyWorldInfo,btVector3(35,25,0),
|
||||||
btVector3(1,1,1)*3,
|
btVector3(1,1,1)*3,
|
||||||
512);
|
512);
|
||||||
psb->m_cfg.kLST = 0.1;
|
psb->m_materials[0]->m_kLST = 0.1;
|
||||||
psb->m_cfg.kDF = 1;
|
psb->m_cfg.kDF = 1;
|
||||||
psb->m_cfg.kDP = 0.001; // fun factor...
|
psb->m_cfg.kDP = 0.001; // fun factor...
|
||||||
psb->m_cfg.kPR = 2500;
|
psb->m_cfg.kPR = 2500;
|
||||||
@@ -582,7 +622,7 @@ static void Init_Volume(SoftDemo* pdemo)
|
|||||||
btSoftBody* psb=btSoftBodyHelpers::CreateEllipsoid(pdemo->m_softBodyWorldInfo,btVector3(35,25,0),
|
btSoftBody* psb=btSoftBodyHelpers::CreateEllipsoid(pdemo->m_softBodyWorldInfo,btVector3(35,25,0),
|
||||||
btVector3(1,1,1)*3,
|
btVector3(1,1,1)*3,
|
||||||
512);
|
512);
|
||||||
psb->m_cfg.kLST = 0.45;
|
psb->m_materials[0]->m_kLST = 0.45;
|
||||||
psb->m_cfg.kVC = 20;
|
psb->m_cfg.kVC = 20;
|
||||||
psb->setTotalMass(50,true);
|
psb->setTotalMass(50,true);
|
||||||
psb->setPose(true,false);
|
psb->setPose(true,false);
|
||||||
@@ -615,12 +655,11 @@ static void Init_Sticks(SoftDemo* pdemo)
|
|||||||
org+btVector3(hg*0.001,hg,0),
|
org+btVector3(hg*0.001,hg,0),
|
||||||
sg,
|
sg,
|
||||||
1);
|
1);
|
||||||
psb->m_cfg.iterations = 1;
|
|
||||||
psb->m_cfg.kDP = 0.005;
|
psb->m_cfg.kDP = 0.005;
|
||||||
psb->m_cfg.kCHR = 0.1;
|
psb->m_cfg.kCHR = 0.1;
|
||||||
for(int i=0;i<3;++i)
|
for(int i=0;i<3;++i)
|
||||||
{
|
{
|
||||||
psb->generateBendingConstraints(2+i,1);
|
psb->generateBendingConstraints(2+i);
|
||||||
}
|
}
|
||||||
psb->setMass(1,0);
|
psb->setMass(1,0);
|
||||||
psb->setTotalMass(0.01);
|
psb->setTotalMass(0.01);
|
||||||
@@ -646,12 +685,15 @@ static void Init_Cloth(SoftDemo* pdemo)
|
|||||||
|
|
||||||
// 31,31,
|
// 31,31,
|
||||||
1+2+4+8,true);
|
1+2+4+8,true);
|
||||||
psb->generateBendingConstraints(2,1);
|
btSoftBody::Material* pm=psb->appendMaterial();
|
||||||
psb->m_cfg.kLST = 0.4;
|
pm->m_kLST = 0.4;
|
||||||
|
pm->m_flags -= btSoftBody::fMaterial::DebugDraw;
|
||||||
|
psb->generateBendingConstraints(2,pm);
|
||||||
psb->setTotalMass(150);
|
psb->setTotalMass(150);
|
||||||
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
||||||
|
|
||||||
Ctor_RbUpStack(pdemo,10);
|
Ctor_RbUpStack(pdemo,10);
|
||||||
|
pdemo->m_cutting=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -663,8 +705,11 @@ static void Init_Bunny(SoftDemo* pdemo)
|
|||||||
btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVerticesBunny,
|
btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVerticesBunny,
|
||||||
&gIndicesBunny[0][0],
|
&gIndicesBunny[0][0],
|
||||||
BUNNY_NUM_TRIANGLES);
|
BUNNY_NUM_TRIANGLES);
|
||||||
psb->generateBendingConstraints(2,0.5);
|
btSoftBody::Material* pm=psb->appendMaterial();
|
||||||
psb->m_cfg.iterations = 2;
|
pm->m_kLST = 0.5;
|
||||||
|
pm->m_flags -= btSoftBody::fMaterial::DebugDraw;
|
||||||
|
psb->generateBendingConstraints(2,pm);
|
||||||
|
psb->m_cfg.piterations = 2;
|
||||||
psb->m_cfg.kDF = 0.5;
|
psb->m_cfg.kDF = 0.5;
|
||||||
psb->randomizeConstraints();
|
psb->randomizeConstraints();
|
||||||
psb->scale(btVector3(6,6,6));
|
psb->scale(btVector3(6,6,6));
|
||||||
@@ -683,7 +728,7 @@ static void Init_BunnyMatch(SoftDemo* pdemo)
|
|||||||
&gIndicesBunny[0][0],
|
&gIndicesBunny[0][0],
|
||||||
BUNNY_NUM_TRIANGLES);
|
BUNNY_NUM_TRIANGLES);
|
||||||
psb->m_cfg.kDF = 0.5;
|
psb->m_cfg.kDF = 0.5;
|
||||||
psb->m_cfg.kLST = 0.1;
|
psb->m_materials[0]->m_kLST = 0.1;
|
||||||
psb->m_cfg.kMT = 0.05;
|
psb->m_cfg.kMT = 0.05;
|
||||||
psb->randomizeConstraints();
|
psb->randomizeConstraints();
|
||||||
psb->scale(btVector3(6,6,6));
|
psb->scale(btVector3(6,6,6));
|
||||||
@@ -702,8 +747,8 @@ static void Init_Torus(SoftDemo* pdemo)
|
|||||||
btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh( pdemo->m_softBodyWorldInfo, gVertices,
|
btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh( pdemo->m_softBodyWorldInfo, gVertices,
|
||||||
&gIndices[0][0],
|
&gIndices[0][0],
|
||||||
NUM_TRIANGLES);
|
NUM_TRIANGLES);
|
||||||
psb->generateBendingConstraints(2,1);
|
psb->generateBendingConstraints(2);
|
||||||
psb->m_cfg.iterations=2;
|
psb->m_cfg.piterations=2;
|
||||||
psb->randomizeConstraints();
|
psb->randomizeConstraints();
|
||||||
btMatrix3x3 m;
|
btMatrix3x3 m;
|
||||||
m.setEulerZYX(SIMD_PI/2,0,0);
|
m.setEulerZYX(SIMD_PI/2,0,0);
|
||||||
@@ -723,7 +768,7 @@ static void Init_TorusMatch(SoftDemo* pdemo)
|
|||||||
btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo, gVertices,
|
btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo, gVertices,
|
||||||
&gIndices[0][0],
|
&gIndices[0][0],
|
||||||
NUM_TRIANGLES);
|
NUM_TRIANGLES);
|
||||||
psb->m_cfg.kLST=0.1;
|
psb->m_materials[0]->m_kLST = 0.1;
|
||||||
psb->m_cfg.kMT = 0.05;
|
psb->m_cfg.kMT = 0.05;
|
||||||
psb->randomizeConstraints();
|
psb->randomizeConstraints();
|
||||||
btMatrix3x3 m;
|
btMatrix3x3 m;
|
||||||
@@ -733,11 +778,176 @@ static void Init_TorusMatch(SoftDemo* pdemo)
|
|||||||
psb->setTotalMass(50,true);
|
psb->setTotalMass(50,true);
|
||||||
psb->setPose(true,true);
|
psb->setPose(true,true);
|
||||||
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned current_demo=0;
|
//
|
||||||
|
// Cutting1
|
||||||
|
//
|
||||||
|
static void Init_Cutting1(SoftDemo* pdemo)
|
||||||
|
{
|
||||||
|
const btScalar s=6;
|
||||||
|
const btScalar h=2;
|
||||||
|
const int r=16;
|
||||||
|
const btVector3 p[]={ btVector3(+s,h,-s),
|
||||||
|
btVector3(-s,h,-s),
|
||||||
|
btVector3(+s,h,+s),
|
||||||
|
btVector3(-s,h,+s)};
|
||||||
|
btSoftBody* psb=btSoftBodyHelpers::CreatePatch(pdemo->m_softBodyWorldInfo,p[0],p[1],p[2],p[3],r,r,1+2+4+8,true);
|
||||||
|
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
||||||
|
psb->m_cfg.piterations=1;
|
||||||
|
pdemo->m_cutting=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BT_SOFTBODY_USE_STL
|
||||||
|
//
|
||||||
|
// TetraBunny
|
||||||
|
//
|
||||||
|
static void Init_TetraBunny(SoftDemo* pdemo)
|
||||||
|
{
|
||||||
|
btSoftBody* psb=btSoftBodyHelpers::CreateFromTetGenData(pdemo->m_softBodyWorldInfo,
|
||||||
|
TetraBunny::getElements(),
|
||||||
|
0,
|
||||||
|
TetraBunny::getNodes(),
|
||||||
|
false,true,true);
|
||||||
|
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
||||||
|
psb->rotate(btQuaternion(SIMD_PI/2,0,0));
|
||||||
|
psb->setVolumeMass(150);
|
||||||
|
psb->m_cfg.piterations=2;
|
||||||
|
pdemo->m_cutting=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// TetraCube
|
||||||
|
//
|
||||||
|
static void Init_TetraCube(SoftDemo* pdemo)
|
||||||
|
{
|
||||||
|
btSoftBody* psb=btSoftBodyHelpers::CreateFromTetGenData(pdemo->m_softBodyWorldInfo,
|
||||||
|
TetraCube::getElements(),
|
||||||
|
0,
|
||||||
|
TetraCube::getNodes(),
|
||||||
|
false,true,true);
|
||||||
|
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
||||||
|
psb->scale(btVector3(4,4,4));
|
||||||
|
psb->translate(btVector3(0,5,0));
|
||||||
|
psb->setVolumeMass(300);
|
||||||
|
psb->setMass(0,0);
|
||||||
|
/*psb->setMass(10,0);
|
||||||
|
psb->setMass(20,0);*/
|
||||||
|
psb->m_cfg.piterations=1;
|
||||||
|
//psb->m_materials[0]->m_kLST=0.05;
|
||||||
|
pdemo->m_cutting=true;
|
||||||
|
}
|
||||||
|
#endif //BT_SOFTBODY_USE_STL
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tetra
|
||||||
|
//
|
||||||
|
static void Init_Tetra(SoftDemo* pdemo)
|
||||||
|
{
|
||||||
|
//TRACEDEMO
|
||||||
|
#if 0
|
||||||
|
{
|
||||||
|
btVector3 pts[]={ btVector3(-1,-1,-1),
|
||||||
|
btVector3(+1,-1,-1),
|
||||||
|
btVector3(+1,+1,-1),
|
||||||
|
btVector3(-1,+1,-1),
|
||||||
|
btVector3(-1,-1,+1),
|
||||||
|
btVector3(+1,-1,+1),
|
||||||
|
btVector3(+1,+1,+1),
|
||||||
|
btVector3(-1,+1,+1)};
|
||||||
|
btSoftBody* psb=btSoftBodyHelpers::CreateFromConvexHull(pdemo->m_softBodyWorldInfo,pts,8);
|
||||||
|
btSoftBodyHelpers::ExportAsSMeshFile(psb,"C:/HomeH/Oss/tetgen/Release/cube.smesh");
|
||||||
|
delete psb;
|
||||||
|
/*btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh( pdemo->m_softBodyWorldInfo,gVerticesBunny,
|
||||||
|
&gIndicesBunny[0][0],
|
||||||
|
BUNNY_NUM_TRIANGLES);
|
||||||
|
psb->scale(btVector3(6,6,6));
|
||||||
|
btSoftBodyHelpers::ExportAsSMeshFile(psb,"C:/HomeH/Oss/tetgen/Release/bunny.smesh");
|
||||||
|
delete psb;*/
|
||||||
|
}
|
||||||
|
btSoftBody* psb=btSoftBodyHelpers::CreateFromTetGenFile(pdemo->m_softBodyWorldInfo,
|
||||||
|
/*"C:/HomeH/Oss/tetgen/Release/bunny.1.ele",
|
||||||
|
"C:/HomeH/Oss/tetgen/Release/bunny.1.face",
|
||||||
|
"C:/HomeH/Oss/tetgen/Release/bunny.1.node",*/
|
||||||
|
"C:/HomeH/Oss/tetgen/Release/cube.1.ele",
|
||||||
|
0/*"C:/HomeH/Oss/tetgen/Release/cube.1.face"*/,
|
||||||
|
"C:/HomeH/Oss/tetgen/Release/cube.1.node",
|
||||||
|
true,true);
|
||||||
|
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
||||||
|
psb->scale(btVector3(4,4,4));
|
||||||
|
/*psb->rotate(btQuaternion(SIMD_PI/4,SIMD_PI/4,0));
|
||||||
|
psb->translate(btVector3(0,10,0));*/
|
||||||
|
psb->setVolumeMass(30);
|
||||||
|
psb->m_cfg.piterations=1;
|
||||||
|
psb->m_cfg.kKHR=1;
|
||||||
|
//psb->addVelocity(btVector3(0,50,0));
|
||||||
|
//psb->m_tetras.clear();
|
||||||
|
ImplicitSphere fnc;
|
||||||
|
fnc.center = btVector3(4,4,4);
|
||||||
|
fnc.radius = 4;
|
||||||
|
psb->refine(&fnc,0.001,true);
|
||||||
|
//psb->m_tetras.clear();
|
||||||
|
printf("Nodes: %u\r\n",psb->m_nodes.size());
|
||||||
|
printf("Links: %u\r\n",psb->m_links.size());
|
||||||
|
printf("Faces: %u\r\n",psb->m_faces.size());
|
||||||
|
printf("Tetras: %u\r\n",psb->m_tetras.size());
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
const btScalar s=4;
|
||||||
|
const int r=32;
|
||||||
|
const btVector3 p[]={ btVector3(+s,0,-s),
|
||||||
|
btVector3(-s,0,-s),
|
||||||
|
btVector3(+s,0,+s),
|
||||||
|
btVector3(-s,0,+s)};
|
||||||
|
btSoftBody* psb=btSoftBodyHelpers::CreatePatch(pdemo->m_softBodyWorldInfo,p[0],p[1],p[2],p[3],r,r,1+2+4+8,true);
|
||||||
|
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
||||||
|
psb->m_cfg.piterations=2;
|
||||||
|
/*ImplicitSphere fnc;
|
||||||
|
fnc.center = btVector3(0,0,0);
|
||||||
|
fnc.radius = 1.5;
|
||||||
|
psb->refine(&fnc,0.001,true);*/
|
||||||
|
//psb->m_faces.clear();
|
||||||
|
/*fnc.center = btVector3(4,0,4);
|
||||||
|
fnc.radius = 2;
|
||||||
|
psb->refine(&fnc,0.001,true);*/
|
||||||
|
#else
|
||||||
|
const btScalar s=4;
|
||||||
|
const btVector3 p[]={ btVector3(+s,-s,0),
|
||||||
|
btVector3(-s,0,0),
|
||||||
|
btVector3(0,0,+s),
|
||||||
|
btVector3(0,+s,0)};
|
||||||
|
btSoftBody* psb=new btSoftBody(&pdemo->m_softBodyWorldInfo,4,p,0);
|
||||||
|
psb->appendTetra(0,1,2,3);
|
||||||
|
psb->appendLink(0,1,1,btSoftBody::eLType::Structural);
|
||||||
|
psb->appendLink(1,2,1,btSoftBody::eLType::Structural);
|
||||||
|
psb->appendLink(2,0,1,btSoftBody::eLType::Structural);
|
||||||
|
psb->appendLink(0,3,1,btSoftBody::eLType::Structural);
|
||||||
|
psb->appendLink(1,3,1,btSoftBody::eLType::Structural);
|
||||||
|
psb->appendLink(2,3,1,btSoftBody::eLType::Structural);
|
||||||
|
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
||||||
|
psb->setSolver(btSoftBody::eSolverPresets::Velocities);
|
||||||
|
psb->m_cfg.viterations=1;
|
||||||
|
psb->m_cfg.diterations=1;
|
||||||
|
psb->m_cfg.kDF=0;
|
||||||
|
psb->m_cfg.kLST=0.000001;
|
||||||
|
//psb1->m_cfg.diterations=1;
|
||||||
|
/*btSoftBody* psb0=btSoftBodyHelpers::CreateRope( pdemo->m_softBodyWorldInfo,
|
||||||
|
btVector3(0,0,0),btVector3(5,0,0),16,1);
|
||||||
|
pdemo->getSoftDynamicsWorld()->addSoftBody(psb0);
|
||||||
|
|
||||||
|
btSoftBody* psb1=btSoftBodyHelpers::CreateRope( pdemo->m_softBodyWorldInfo,
|
||||||
|
btVector3(0,0,2),btVector3(5,0,2),16,1);
|
||||||
|
psb1->m_cfg.viterations=1;
|
||||||
|
psb1->m_cfg.diterations=1;
|
||||||
|
psb1->setSolver(btSoftBody::eSolverPresets::Velocities);
|
||||||
|
pdemo->getSoftDynamicsWorld()->addSoftBody(psb1);*/
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
pdemo->toggleIdle();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned current_demo=1;
|
||||||
|
|
||||||
void SoftDemo::clientResetScene()
|
void SoftDemo::clientResetScene()
|
||||||
{
|
{
|
||||||
@@ -766,6 +976,11 @@ void SoftDemo::clientResetScene()
|
|||||||
/* Init */
|
/* Init */
|
||||||
void (*demofncs[])(SoftDemo*)=
|
void (*demofncs[])(SoftDemo*)=
|
||||||
{
|
{
|
||||||
|
Init_Cutting1,
|
||||||
|
#ifdef BT_SOFTBODY_USE_STL
|
||||||
|
Init_TetraBunny,
|
||||||
|
Init_TetraCube,
|
||||||
|
#endif //BT_SOFTBODY_USE_STL
|
||||||
Init_Cloth,
|
Init_Cloth,
|
||||||
Init_Pressure,
|
Init_Pressure,
|
||||||
Init_Volume,
|
Init_Volume,
|
||||||
@@ -796,6 +1011,7 @@ void SoftDemo::clientResetScene()
|
|||||||
|
|
||||||
m_autocam = false;
|
m_autocam = false;
|
||||||
m_raycast = false;
|
m_raycast = false;
|
||||||
|
m_cutting = false;
|
||||||
demofncs[current_demo](this);
|
demofncs[current_demo](this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -813,10 +1029,10 @@ void SoftDemo::renderme()
|
|||||||
for(int ib=0;ib<sbs.size();++ib)
|
for(int ib=0;ib<sbs.size();++ib)
|
||||||
{
|
{
|
||||||
btSoftBody* psb=sbs[ib];
|
btSoftBody* psb=sbs[ib];
|
||||||
nps+=psb->getNodes().size();
|
nps+=psb->m_nodes.size();
|
||||||
for(int i=0;i<psb->getNodes().size();++i)
|
for(int i=0;i<psb->m_nodes.size();++i)
|
||||||
{
|
{
|
||||||
ps+=psb->getNodes()[i].m_x;
|
ps+=psb->m_nodes[i].m_x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ps/=nps;
|
ps/=nps;
|
||||||
@@ -927,10 +1143,69 @@ void SoftDemo::keyboardCallback(unsigned char key, int x, int y)
|
|||||||
case '[': --current_demo;clientResetScene();break;
|
case '[': --current_demo;clientResetScene();break;
|
||||||
case ',': m_raycast=!m_raycast;break;
|
case ',': m_raycast=!m_raycast;break;
|
||||||
case ';': m_autocam=!m_autocam;break;
|
case ';': m_autocam=!m_autocam;break;
|
||||||
|
case '`':
|
||||||
|
{
|
||||||
|
btSoftBodyArray& sbs=getSoftDynamicsWorld()->getSoftBodyArray();
|
||||||
|
for(int ib=0;ib<sbs.size();++ib)
|
||||||
|
{
|
||||||
|
btSoftBody* psb=sbs[ib];
|
||||||
|
psb->staticSolve(128);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default: DemoApplication::keyboardCallback(key,x,y);
|
default: DemoApplication::keyboardCallback(key,x,y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void SoftDemo::mouseFunc(int button, int state, int x, int y)
|
||||||
|
{
|
||||||
|
if(m_cutting&&(state==0)&&(button==0))
|
||||||
|
{
|
||||||
|
const btVector3 rayFrom=m_cameraPosition;
|
||||||
|
const btVector3 rayTo=getRayTo(x,y);
|
||||||
|
const btVector3 rayDir=(rayTo-rayFrom).normalized();
|
||||||
|
btSoftBodyArray& sbs=getSoftDynamicsWorld()->getSoftBodyArray();
|
||||||
|
btSoftBody::sRayCast results;
|
||||||
|
results.time=SIMD_INFINITY;
|
||||||
|
for(int ib=0;ib<sbs.size();++ib)
|
||||||
|
{
|
||||||
|
btSoftBody* psb=sbs[ib];
|
||||||
|
btSoftBody::sRayCast res;
|
||||||
|
if(psb->rayCast(rayFrom,rayDir,res,results.time))
|
||||||
|
{
|
||||||
|
results=res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(results.time<SIMD_INFINITY)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
const btVector3 x=rayFrom+rayDir*results.time;
|
||||||
|
const btSoftBody::Face& f=results.body->m_faces[results.index];
|
||||||
|
btScalar bestarea=SIMD_INFINITY;
|
||||||
|
const btSoftBody::Node* n[2]={0,0};
|
||||||
|
for(int i=2,j=0;j<3;i=j++)
|
||||||
|
{
|
||||||
|
const btScalar a2=cross(f.m_n[i]->m_x-x,f.m_n[j]->m_x-x).length2();
|
||||||
|
if(a2<bestarea)
|
||||||
|
{
|
||||||
|
bestarea=a2;
|
||||||
|
n[0]=f.m_n[i];
|
||||||
|
n[1]=f.m_n[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
results.body->cutLink(n[0],n[1],0.5);
|
||||||
|
#endif
|
||||||
|
ImplicitSphere isphere(rayFrom+rayDir*results.time,1);
|
||||||
|
printf("Mass before: %f\r\n",results.body->getTotalMass());
|
||||||
|
results.body->refine(&isphere,0.0001,true);
|
||||||
|
printf("Mass after: %f\r\n",results.body->getTotalMass());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DemoApplication::mouseFunc(button,state,x,y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SoftDemo::initPhysics()
|
void SoftDemo::initPhysics()
|
||||||
{
|
{
|
||||||
@@ -1051,3 +1326,4 @@ void SoftDemo::exitPhysics()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
bool m_autocam;
|
bool m_autocam;
|
||||||
|
bool m_cutting;
|
||||||
bool m_raycast;
|
bool m_raycast;
|
||||||
btScalar m_animtime;
|
btScalar m_animtime;
|
||||||
btClock m_clock;
|
btClock m_clock;
|
||||||
@@ -116,6 +117,7 @@ public:
|
|||||||
void clientResetScene();
|
void clientResetScene();
|
||||||
void renderme();
|
void renderme();
|
||||||
void keyboardCallback(unsigned char key, int x, int y);
|
void keyboardCallback(unsigned char key, int x, int y);
|
||||||
|
void mouseFunc(int button, int state, int x, int y);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -158,3 +160,4 @@ MACRO_SOFT_DEMO(16)//Init_BunnyMatch
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ subject to the following restrictions:
|
|||||||
#include "RenderingHelpers.h"
|
#include "RenderingHelpers.h"
|
||||||
#include "GLFontRenderer.h"
|
#include "GLFontRenderer.h"
|
||||||
#include "btBulletCollisionCommon.h"
|
#include "btBulletCollisionCommon.h"
|
||||||
|
#include "BulletSoftBody/btDbvtBroadphase.h"
|
||||||
|
|
||||||
int numParts =2;
|
int numParts =2;
|
||||||
|
|
||||||
@@ -99,7 +100,10 @@ BulletSAPCompleteBoxPruningTest::BulletSAPCompleteBoxPruningTest(int numBoxes,in
|
|||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 7:
|
||||||
|
m_broadphase = new btDbvtBroadphase();
|
||||||
|
methodname = "btDbvtBroadphase";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
m_broadphase = new btAxisSweep3(aabbMin,aabbMax,numBoxes,new btNullPairCache());
|
m_broadphase = new btAxisSweep3(aabbMin,aabbMax,numBoxes,new btNullPairCache());
|
||||||
@@ -179,7 +183,7 @@ bool BulletSAPCompleteBoxPruningTest::UpdateBoxes(int numBoxes)
|
|||||||
{
|
{
|
||||||
static bool once=true;
|
static bool once=true;
|
||||||
|
|
||||||
for(udword i=0;i<numBoxes;i++)
|
for(udword i=0;i<(udword)numBoxes;i++)
|
||||||
{
|
{
|
||||||
mBoxTime[i] += mSpeed;
|
mBoxTime[i] += mSpeed;
|
||||||
|
|
||||||
@@ -195,19 +199,20 @@ bool BulletSAPCompleteBoxPruningTest::UpdateBoxes(int numBoxes)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
extern int doTree;
|
extern int doTree;
|
||||||
|
extern int percentUpdate;
|
||||||
|
|
||||||
void BulletSAPCompleteBoxPruningTest::PerformTest()
|
void BulletSAPCompleteBoxPruningTest::PerformTest()
|
||||||
{
|
{
|
||||||
int numUpdatedBoxes = (mNbBoxes*10)/100;
|
int numUpdatedBoxes = (mNbBoxes*percentUpdate)/100;
|
||||||
if (m_firstTime)
|
if (m_firstTime)
|
||||||
{
|
{
|
||||||
numUpdatedBoxes = mNbBoxes;
|
numUpdatedBoxes = mNbBoxes;
|
||||||
m_firstTime = false;
|
m_firstTime = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mProfiler.Start();
|
mProfiler.Start();
|
||||||
UpdateBoxes(numUpdatedBoxes);
|
UpdateBoxes(numUpdatedBoxes);
|
||||||
|
|
||||||
|
|
||||||
mPairs.ResetPairs();
|
mPairs.ResetPairs();
|
||||||
|
|
||||||
//CompleteBoxPruning(mNbBoxes, mBoxPtrs, mPairs, Axes(AXES_XZY));
|
//CompleteBoxPruning(mNbBoxes, mBoxPtrs, mPairs, Axes(AXES_XZY));
|
||||||
@@ -240,7 +245,7 @@ void BulletSAPCompleteBoxPruningTest::PerformTest()
|
|||||||
btOverlappingPairCache* pairCache = m_broadphase->getOverlappingPairCache();
|
btOverlappingPairCache* pairCache = m_broadphase->getOverlappingPairCache();
|
||||||
const btBroadphasePair* pairPtr = pairCache->getOverlappingPairArrayPtr();
|
const btBroadphasePair* pairPtr = pairCache->getOverlappingPairArrayPtr();
|
||||||
|
|
||||||
for(udword i=0;i<pairCache->getNumOverlappingPairs();i++)
|
for(udword i=0;i<(udword)pairCache->getNumOverlappingPairs();i++)
|
||||||
{
|
{
|
||||||
// Flags[pairPtr[i].m_pProxy0->getUid()-1] = true;
|
// Flags[pairPtr[i].m_pProxy0->getUid()-1] = true;
|
||||||
// Flags[pairPtr[i].m_pProxy1->getUid()-1] = true;
|
// Flags[pairPtr[i].m_pProxy1->getUid()-1] = true;
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ subject to the following restrictions:
|
|||||||
//#define NUM_SAP_BOXES 8192
|
//#define NUM_SAP_BOXES 8192
|
||||||
//#define NUM_SAP_BOXES 4096
|
//#define NUM_SAP_BOXES 4096
|
||||||
|
|
||||||
#define NUM_SAP_BOXES 4096
|
#define NUM_SAP_BOXES 8192
|
||||||
|
|
||||||
|
int percentUpdate = 10;
|
||||||
|
|
||||||
//Broadphase comparison
|
//Broadphase comparison
|
||||||
//Static case (updating 10% of objects to same position ( -> no swaps)
|
//Static case (updating 10% of objects to same position ( -> no swaps)
|
||||||
@@ -73,8 +74,8 @@ enum TestIndex
|
|||||||
MAX_NB_TESTS
|
MAX_NB_TESTS
|
||||||
};
|
};
|
||||||
|
|
||||||
static int gTest = TEST_BULLET_MULTISAP_8192;
|
static int gTest = TEST_DBVT_8192;//TEST_BULLET_MULTISAP_8192;
|
||||||
static int gSelectedTest = TEST_BULLET_MULTISAP_8192;
|
static int gSelectedTest = TEST_DBVT_8192;//TEST_BULLET_MULTISAP_8192;
|
||||||
static CollisionTest* gCollisionTests[MAX_NB_TESTS];
|
static CollisionTest* gCollisionTests[MAX_NB_TESTS];
|
||||||
|
|
||||||
static GLFontRenderer gFnt;
|
static GLFontRenderer gFnt;
|
||||||
@@ -300,6 +301,7 @@ int main(int argc, char** argv)
|
|||||||
};
|
};
|
||||||
TwType testType = TwDefineEnum("CollisionTest", testEV, MAX_NB_TESTS);
|
TwType testType = TwDefineEnum("CollisionTest", testEV, MAX_NB_TESTS);
|
||||||
TwAddVarRW(gMainBar, "CollisionTests", testType, &gSelectedTest, "");
|
TwAddVarRW(gMainBar, "CollisionTests", testType, &gSelectedTest, "");
|
||||||
|
TwAddVarRW(gMainBar, "% of updates",TW_TYPE_INT32,&percentUpdate,"min=0 max=100");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create tests
|
// Create tests
|
||||||
@@ -315,7 +317,7 @@ int main(int argc, char** argv)
|
|||||||
// gCollisionTests[TEST_BULLET_SAP_SORTEDPAIRS_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,3);
|
// gCollisionTests[TEST_BULLET_SAP_SORTEDPAIRS_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,3);
|
||||||
gCollisionTests[TEST_BULLET_MULTISAP_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,6);
|
gCollisionTests[TEST_BULLET_MULTISAP_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,6);
|
||||||
// gCollisionTests[TEST_BIPARTITE_BOX_PRUNING] = new BipartiteBoxPruningTest;
|
// gCollisionTests[TEST_BIPARTITE_BOX_PRUNING] = new BipartiteBoxPruningTest;
|
||||||
gCollisionTests[TEST_DBVT_8192] = new DbvtTest(NUM_SAP_BOXES);
|
gCollisionTests[TEST_DBVT_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,7);
|
||||||
|
|
||||||
for(int i=0;i<MAX_NB_TESTS;i++)
|
for(int i=0;i<MAX_NB_TESTS;i++)
|
||||||
gCollisionTests[i]->Init();
|
gCollisionTests[i]->Init();
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ subject to the following restrictions:
|
|||||||
#include "btDispatcher.h"
|
#include "btDispatcher.h"
|
||||||
#include "btCollisionAlgorithm.h"
|
#include "btCollisionAlgorithm.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
int gOverlappingPairs = 0;
|
int gOverlappingPairs = 0;
|
||||||
|
|
||||||
int gRemovePairs =0;
|
int gRemovePairs =0;
|
||||||
@@ -133,12 +135,12 @@ void btHashedOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroad
|
|||||||
btBroadphasePair* btHashedOverlappingPairCache::findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
|
btBroadphasePair* btHashedOverlappingPairCache::findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
|
||||||
{
|
{
|
||||||
gFindPairs++;
|
gFindPairs++;
|
||||||
|
if(proxy0>proxy1) btSwap(proxy0,proxy1);
|
||||||
int proxyId1 = proxy0->getUid();
|
int proxyId1 = proxy0->getUid();
|
||||||
int proxyId2 = proxy1->getUid();
|
int proxyId2 = proxy1->getUid();
|
||||||
|
|
||||||
if (proxyId1 > proxyId2)
|
/*if (proxyId1 > proxyId2)
|
||||||
btSwap(proxyId1, proxyId2);
|
btSwap(proxyId1, proxyId2);*/
|
||||||
|
|
||||||
int hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1);
|
int hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1);
|
||||||
|
|
||||||
@@ -196,8 +198,8 @@ void btHashedOverlappingPairCache::growTables()
|
|||||||
const btBroadphasePair& pair = m_overlappingPairArray[i];
|
const btBroadphasePair& pair = m_overlappingPairArray[i];
|
||||||
int proxyId1 = pair.m_pProxy0->getUid();
|
int proxyId1 = pair.m_pProxy0->getUid();
|
||||||
int proxyId2 = pair.m_pProxy1->getUid();
|
int proxyId2 = pair.m_pProxy1->getUid();
|
||||||
if (proxyId1 > proxyId2)
|
/*if (proxyId1 > proxyId2)
|
||||||
btSwap(proxyId1, proxyId2);
|
btSwap(proxyId1, proxyId2);*/
|
||||||
int hashValue = getHash(proxyId1,proxyId2) & (m_overlappingPairArray.capacity()-1); // New hash value with new mask
|
int hashValue = getHash(proxyId1,proxyId2) & (m_overlappingPairArray.capacity()-1); // New hash value with new mask
|
||||||
m_next[i] = m_hashTable[hashValue];
|
m_next[i] = m_hashTable[hashValue];
|
||||||
m_hashTable[hashValue] = i;
|
m_hashTable[hashValue] = i;
|
||||||
@@ -209,11 +211,12 @@ void btHashedOverlappingPairCache::growTables()
|
|||||||
|
|
||||||
btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
|
btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
|
||||||
{
|
{
|
||||||
|
if(proxy0>proxy1) btSwap(proxy0,proxy1);
|
||||||
int proxyId1 = proxy0->getUid();
|
int proxyId1 = proxy0->getUid();
|
||||||
int proxyId2 = proxy1->getUid();
|
int proxyId2 = proxy1->getUid();
|
||||||
|
|
||||||
if (proxyId1 > proxyId2)
|
/*if (proxyId1 > proxyId2)
|
||||||
btSwap(proxyId1, proxyId2);
|
btSwap(proxyId1, proxyId2);*/
|
||||||
|
|
||||||
int hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1);
|
int hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1);
|
||||||
|
|
||||||
@@ -224,7 +227,15 @@ btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProx
|
|||||||
{
|
{
|
||||||
return pair;
|
return pair;
|
||||||
}
|
}
|
||||||
|
/*for(int i=0;i<m_overlappingPairArray.size();++i)
|
||||||
|
{
|
||||||
|
if( (m_overlappingPairArray[i].m_pProxy0==proxy0)&&
|
||||||
|
(m_overlappingPairArray[i].m_pProxy1==proxy1))
|
||||||
|
{
|
||||||
|
printf("Adding duplicated %u<>%u\r\n",proxyId1,proxyId2);
|
||||||
|
internalFindPair(proxy0, proxy1, hash);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
int count = m_overlappingPairArray.size();
|
int count = m_overlappingPairArray.size();
|
||||||
int oldCapacity = m_overlappingPairArray.capacity();
|
int oldCapacity = m_overlappingPairArray.capacity();
|
||||||
void* mem = &m_overlappingPairArray.expand();
|
void* mem = &m_overlappingPairArray.expand();
|
||||||
@@ -255,12 +266,12 @@ btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProx
|
|||||||
void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1,btDispatcher* dispatcher)
|
void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1,btDispatcher* dispatcher)
|
||||||
{
|
{
|
||||||
gRemovePairs++;
|
gRemovePairs++;
|
||||||
|
if(proxy0>proxy1) btSwap(proxy0,proxy1);
|
||||||
int proxyId1 = proxy0->getUid();
|
int proxyId1 = proxy0->getUid();
|
||||||
int proxyId2 = proxy1->getUid();
|
int proxyId2 = proxy1->getUid();
|
||||||
|
|
||||||
if (proxyId1 > proxyId2)
|
/*if (proxyId1 > proxyId2)
|
||||||
btSwap(proxyId1, proxyId2);
|
btSwap(proxyId1, proxyId2);*/
|
||||||
|
|
||||||
int hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1);
|
int hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1);
|
||||||
|
|
||||||
@@ -316,6 +327,7 @@ void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* pro
|
|||||||
|
|
||||||
// Remove the last pair from the hash table.
|
// Remove the last pair from the hash table.
|
||||||
const btBroadphasePair* last = &m_overlappingPairArray[lastPairIndex];
|
const btBroadphasePair* last = &m_overlappingPairArray[lastPairIndex];
|
||||||
|
/* missing swap here too, Nat. */
|
||||||
int lastHash = getHash(last->m_pProxy0->getUid(), last->m_pProxy1->getUid()) & (m_overlappingPairArray.capacity()-1);
|
int lastHash = getHash(last->m_pProxy0->getUid(), last->m_pProxy1->getUid()) & (m_overlappingPairArray.capacity()-1);
|
||||||
|
|
||||||
index = m_hashTable[lastHash];
|
index = m_hashTable[lastHash];
|
||||||
@@ -416,6 +428,7 @@ btBroadphasePair* btSortedOverlappingPairCache::addOverlappingPair(btBroadphaseP
|
|||||||
void* mem = &m_overlappingPairArray.expand();
|
void* mem = &m_overlappingPairArray.expand();
|
||||||
btBroadphasePair* pair = new (mem) btBroadphasePair(*proxy0,*proxy1);
|
btBroadphasePair* pair = new (mem) btBroadphasePair(*proxy0,*proxy1);
|
||||||
gOverlappingPairs++;
|
gOverlappingPairs++;
|
||||||
|
gAddedPairs++;
|
||||||
return pair;
|
return pair;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -500,6 +513,7 @@ void btSortedOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair,b
|
|||||||
pair.m_algorithm->~btCollisionAlgorithm();
|
pair.m_algorithm->~btCollisionAlgorithm();
|
||||||
dispatcher->freeCollisionAlgorithm(pair.m_algorithm);
|
dispatcher->freeCollisionAlgorithm(pair.m_algorithm);
|
||||||
pair.m_algorithm=0;
|
pair.m_algorithm=0;
|
||||||
|
gRemovePairs--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -225,8 +225,10 @@ private:
|
|||||||
{
|
{
|
||||||
int proxyId1 = proxy0->getUid();
|
int proxyId1 = proxy0->getUid();
|
||||||
int proxyId2 = proxy1->getUid();
|
int proxyId2 = proxy1->getUid();
|
||||||
|
#if 0 // wrong, 'equalsPair' use unsorted uids, copy-past devil striked again. Nat.
|
||||||
if (proxyId1 > proxyId2)
|
if (proxyId1 > proxyId2)
|
||||||
btSwap(proxyId1, proxyId2);
|
btSwap(proxyId1, proxyId2);
|
||||||
|
#endif
|
||||||
|
|
||||||
int index = m_hashTable[hash];
|
int index = m_hashTable[hash];
|
||||||
|
|
||||||
@@ -432,3 +434,4 @@ public:
|
|||||||
#endif //OVERLAPPING_PAIR_CACHE_H
|
#endif //OVERLAPPING_PAIR_CACHE_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ ADD_LIBRARY(LibBulletSoftBody
|
|||||||
btSoftBody.h
|
btSoftBody.h
|
||||||
btSoftBodyHelpers.cpp
|
btSoftBodyHelpers.cpp
|
||||||
btSparseSDF.h
|
btSparseSDF.h
|
||||||
|
btDbvtBroadphase.cpp
|
||||||
|
btDbvtBroadphase.h
|
||||||
btDbvt.cpp
|
btDbvt.cpp
|
||||||
btDbvt.h
|
btDbvt.h
|
||||||
btSoftBodyHelpers.h
|
btSoftBodyHelpers.h
|
||||||
@@ -16,6 +18,8 @@ ADD_LIBRARY(LibBulletSoftBody
|
|||||||
btSoftRigidCollisionAlgorithm.h
|
btSoftRigidCollisionAlgorithm.h
|
||||||
btSoftSoftCollisionAlgorithm.cpp
|
btSoftSoftCollisionAlgorithm.cpp
|
||||||
btSoftSoftCollisionAlgorithm.h
|
btSoftSoftCollisionAlgorithm.h
|
||||||
|
btSoftBodyConcaveCollisionAlgorithm.cpp
|
||||||
|
btSoftBodyConcaveCollisionAlgorithm.h
|
||||||
btSoftRigidDynamicsWorld.h
|
btSoftRigidDynamicsWorld.h
|
||||||
btSoftRigidDynamicsWorld.cpp
|
btSoftRigidDynamicsWorld.cpp
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
///btDbvt implementation by Nathanael Presson
|
||||||
|
|
||||||
#include "btDbvt.h"
|
#include "btDbvt.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -10,16 +26,16 @@ return(node->parent->childs[1]==node);
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
static inline btDbvt::Aabb merge( const btDbvt::Aabb& a,
|
static inline btDbvt::Volume merge( const btDbvt::Volume& a,
|
||||||
const btDbvt::Aabb& b)
|
const btDbvt::Volume& b)
|
||||||
{
|
{
|
||||||
btDbvt::Aabb res;
|
btDbvt::Volume res;
|
||||||
Merge(a,b,res);
|
Merge(a,b,res);
|
||||||
return(res);
|
return(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
// volume+edge lengths
|
// volume+edge lengths
|
||||||
static inline btScalar size(const btDbvt::Aabb& a)
|
static inline btScalar size(const btDbvt::Volume& a)
|
||||||
{
|
{
|
||||||
const btVector3 edges=a.Lengths();
|
const btVector3 edges=a.Lengths();
|
||||||
return( edges.x()*edges.y()*edges.z()+
|
return( edges.x()*edges.y()*edges.z()+
|
||||||
@@ -50,7 +66,7 @@ deletenode(pdbvt,node);
|
|||||||
//
|
//
|
||||||
static inline btDbvt::Node* createnode( btDbvt* pdbvt,
|
static inline btDbvt::Node* createnode( btDbvt* pdbvt,
|
||||||
btDbvt::Node* parent,
|
btDbvt::Node* parent,
|
||||||
const btDbvt::Aabb& box,
|
const btDbvt::Volume& volume,
|
||||||
void* data)
|
void* data)
|
||||||
{
|
{
|
||||||
btDbvt::Node* node;
|
btDbvt::Node* node;
|
||||||
@@ -59,7 +75,7 @@ if(pdbvt->m_free)
|
|||||||
else
|
else
|
||||||
{ node=new btDbvt::Node(); }
|
{ node=new btDbvt::Node(); }
|
||||||
node->parent = parent;
|
node->parent = parent;
|
||||||
node->box = box;
|
node->volume = volume;
|
||||||
node->data = data;
|
node->data = data;
|
||||||
node->childs[1] = 0;
|
node->childs[1] = 0;
|
||||||
return(node);
|
return(node);
|
||||||
@@ -80,25 +96,25 @@ if(!pdbvt->m_root)
|
|||||||
if(!root->isleaf())
|
if(!root->isleaf())
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
if( Proximity(root->childs[0]->box,leaf->box)<
|
if( Proximity(root->childs[0]->volume,leaf->volume)<
|
||||||
Proximity(root->childs[1]->box,leaf->box))
|
Proximity(root->childs[1]->volume,leaf->volume))
|
||||||
root=root->childs[0];
|
root=root->childs[0];
|
||||||
else
|
else
|
||||||
root=root->childs[1];
|
root=root->childs[1];
|
||||||
} while(!root->isleaf());
|
} while(!root->isleaf());
|
||||||
}
|
}
|
||||||
btDbvt::Node* prev=root->parent;
|
btDbvt::Node* prev=root->parent;
|
||||||
btDbvt::Node* node=createnode(pdbvt,prev,merge(leaf->box,root->box),0);
|
btDbvt::Node* node=createnode(pdbvt,prev,merge(leaf->volume,root->volume),0);
|
||||||
if(prev)
|
if(prev)
|
||||||
{
|
{
|
||||||
prev->childs[indexof(root)] = node;
|
prev->childs[indexof(root)] = node;
|
||||||
node->childs[0] = root;root->parent=node;
|
node->childs[0] = root;root->parent=node;
|
||||||
node->childs[1] = leaf;leaf->parent=node;
|
node->childs[1] = leaf;leaf->parent=node;
|
||||||
do {
|
do {
|
||||||
if(prev->box.Contain(node->box))
|
if(prev->volume.Contain(node->volume))
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
Merge(prev->childs[0]->box,prev->childs[1]->box,prev->box);
|
Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
|
||||||
node=prev;
|
node=prev;
|
||||||
} while(0!=(prev=node->parent));
|
} while(0!=(prev=node->parent));
|
||||||
}
|
}
|
||||||
@@ -132,9 +148,9 @@ if(leaf==pdbvt->m_root)
|
|||||||
deletenode(pdbvt,parent);
|
deletenode(pdbvt,parent);
|
||||||
while(prev)
|
while(prev)
|
||||||
{
|
{
|
||||||
const btDbvt::Aabb pb=prev->box;
|
const btDbvt::Volume pb=prev->volume;
|
||||||
Merge(prev->childs[0]->box,prev->childs[1]->box,prev->box);
|
Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
|
||||||
if(NotEqual(pb,prev->box))
|
if(NotEqual(pb,prev->volume))
|
||||||
{
|
{
|
||||||
sibling = prev;
|
sibling = prev;
|
||||||
prev = prev->parent;
|
prev = prev->parent;
|
||||||
@@ -170,17 +186,6 @@ if(root->isinternal()&&depth)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
static int leafcount(btDbvt::Node* root)
|
|
||||||
{
|
|
||||||
if(root->isinternal())
|
|
||||||
{
|
|
||||||
return( leafcount(root->childs[0])+
|
|
||||||
leafcount(root->childs[1]));
|
|
||||||
}
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
static void split( const tNodeArray& leafs,
|
static void split( const tNodeArray& leafs,
|
||||||
tNodeArray& left,
|
tNodeArray& left,
|
||||||
@@ -192,7 +197,7 @@ left.resize(0);
|
|||||||
right.resize(0);
|
right.resize(0);
|
||||||
for(int i=0,ni=leafs.size();i<ni;++i)
|
for(int i=0,ni=leafs.size();i<ni;++i)
|
||||||
{
|
{
|
||||||
if(dot(axis,leafs[i]->box.Center()-org)<0)
|
if(dot(axis,leafs[i]->volume.Center()-org)<0)
|
||||||
left.push_back(leafs[i]);
|
left.push_back(leafs[i]);
|
||||||
else
|
else
|
||||||
right.push_back(leafs[i]);
|
right.push_back(leafs[i]);
|
||||||
@@ -200,14 +205,14 @@ for(int i=0,ni=leafs.size();i<ni;++i)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
static btDbvt::Aabb bounds( const tNodeArray& leafs)
|
static btDbvt::Volume bounds( const tNodeArray& leafs)
|
||||||
{
|
{
|
||||||
btDbvt::Aabb box=leafs[0]->box;
|
btDbvt::Volume volume=leafs[0]->volume;
|
||||||
for(int i=1,ni=leafs.size();i<ni;++i)
|
for(int i=1,ni=leafs.size();i<ni;++i)
|
||||||
{
|
{
|
||||||
box=merge(box,leafs[i]->box);
|
volume=merge(volume,leafs[i]->volume);
|
||||||
}
|
}
|
||||||
return(box);
|
return(volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -222,7 +227,7 @@ while(leafs.size()>1)
|
|||||||
{
|
{
|
||||||
for(int j=i+1;j<leafs.size();++j)
|
for(int j=i+1;j<leafs.size();++j)
|
||||||
{
|
{
|
||||||
const btScalar sz=size(merge(leafs[i]->box,leafs[j]->box));
|
const btScalar sz=size(merge(leafs[i]->volume,leafs[j]->volume));
|
||||||
if(sz<minsize)
|
if(sz<minsize)
|
||||||
{
|
{
|
||||||
minsize = sz;
|
minsize = sz;
|
||||||
@@ -232,7 +237,7 @@ while(leafs.size()>1)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
btDbvt::Node* n[] = {leafs[minidx[0]],leafs[minidx[1]]};
|
btDbvt::Node* n[] = {leafs[minidx[0]],leafs[minidx[1]]};
|
||||||
btDbvt::Node* p = createnode(pdbvt,0,merge(n[0]->box,n[1]->box),0);
|
btDbvt::Node* p = createnode(pdbvt,0,merge(n[0]->volume,n[1]->volume),0);
|
||||||
p->childs[0] = n[0];
|
p->childs[0] = n[0];
|
||||||
p->childs[1] = n[1];
|
p->childs[1] = n[1];
|
||||||
n[0]->parent = p;
|
n[0]->parent = p;
|
||||||
@@ -255,15 +260,15 @@ if(leafs.size()>1)
|
|||||||
{
|
{
|
||||||
if(leafs.size()>bu_treshold)
|
if(leafs.size()>bu_treshold)
|
||||||
{
|
{
|
||||||
const btDbvt::Aabb box=bounds(leafs);
|
const btDbvt::Volume vol=bounds(leafs);
|
||||||
const btVector3 org=box.Center();
|
const btVector3 org=vol.Center();
|
||||||
tNodeArray sets[2];
|
tNodeArray sets[2];
|
||||||
int bestaxis=-1;
|
int bestaxis=-1;
|
||||||
int bestmidp=leafs.size();
|
int bestmidp=leafs.size();
|
||||||
int splitcount[3][2]={0,0,0,0,0,0};
|
int splitcount[3][2]={0,0,0,0,0,0};
|
||||||
for(int i=0;i<leafs.size();++i)
|
for(int i=0;i<leafs.size();++i)
|
||||||
{
|
{
|
||||||
const btVector3 x=leafs[i]->box.Center()-org;
|
const btVector3 x=leafs[i]->volume.Center()-org;
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
{
|
{
|
||||||
++splitcount[j][dot(x,axis[j])>0?1:0];
|
++splitcount[j][dot(x,axis[j])>0?1:0];
|
||||||
@@ -296,7 +301,7 @@ if(leafs.size()>1)
|
|||||||
sets[i&1].push_back(leafs[i]);
|
sets[i&1].push_back(leafs[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
btDbvt::Node* node=createnode(pdbvt,0,box,0);
|
btDbvt::Node* node=createnode(pdbvt,0,vol,0);
|
||||||
node->childs[0]=topdown(pdbvt,sets[0],bu_treshold);
|
node->childs[0]=topdown(pdbvt,sets[0],bu_treshold);
|
||||||
node->childs[1]=topdown(pdbvt,sets[1],bu_treshold);
|
node->childs[1]=topdown(pdbvt,sets[1],bu_treshold);
|
||||||
node->childs[0]->parent=node;
|
node->childs[0]->parent=node;
|
||||||
@@ -344,6 +349,7 @@ return(node);
|
|||||||
m_root = 0;
|
m_root = 0;
|
||||||
m_free = 0;
|
m_free = 0;
|
||||||
m_lkhd = 2;
|
m_lkhd = 2;
|
||||||
|
m_leafs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -360,21 +366,13 @@ delete m_free;
|
|||||||
m_free=0;
|
m_free=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
int btDbvt::leafCount() const
|
|
||||||
{
|
|
||||||
if(m_root) return(leafcount(m_root));
|
|
||||||
else
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
void btDbvt::optimizeBottomUp()
|
void btDbvt::optimizeBottomUp()
|
||||||
{
|
{
|
||||||
if(m_root)
|
if(m_root)
|
||||||
{
|
{
|
||||||
tNodeArray leafs;
|
tNodeArray leafs;
|
||||||
leafs.reserve(leafCount());
|
leafs.reserve(m_leafs);
|
||||||
fetchleafs(this,m_root,leafs);
|
fetchleafs(this,m_root,leafs);
|
||||||
bottomup(this,leafs);
|
bottomup(this,leafs);
|
||||||
m_root=leafs[0];
|
m_root=leafs[0];
|
||||||
@@ -387,22 +385,37 @@ void btDbvt::optimizeTopDown(int bu_treshold)
|
|||||||
if(m_root)
|
if(m_root)
|
||||||
{
|
{
|
||||||
tNodeArray leafs;
|
tNodeArray leafs;
|
||||||
leafs.reserve(leafCount());
|
leafs.reserve(m_leafs);
|
||||||
fetchleafs(this,m_root,leafs);
|
fetchleafs(this,m_root,leafs);
|
||||||
m_root=topdown(this,leafs,bu_treshold);
|
m_root=topdown(this,leafs,bu_treshold);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
btDbvt::Node* btDbvt::insert(const Aabb& box,void* data)
|
btDbvt::Node* btDbvt::insert(const Volume& volume,void* data)
|
||||||
{
|
{
|
||||||
Node* leaf=createnode(this,0,box,data);
|
Node* leaf=createnode(this,0,volume,data);
|
||||||
insertleaf(this,m_root,leaf);
|
insertleaf(this,m_root,leaf);
|
||||||
|
++m_leafs;
|
||||||
return(leaf);
|
return(leaf);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
void btDbvt::update(Node* leaf,const Aabb& box)
|
void btDbvt::update(Node* leaf,int lookahead)
|
||||||
|
{
|
||||||
|
Node* root=removeleaf(this,leaf);
|
||||||
|
if(root)
|
||||||
|
{
|
||||||
|
for(int i=0;(i<lookahead)&&root->parent;++i)
|
||||||
|
{
|
||||||
|
root=root->parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
insertleaf(this,root,leaf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void btDbvt::update(Node* leaf,const Volume& volume)
|
||||||
{
|
{
|
||||||
Node* root=removeleaf(this,leaf);
|
Node* root=removeleaf(this,leaf);
|
||||||
if(root)
|
if(root)
|
||||||
@@ -412,19 +425,35 @@ if(root)
|
|||||||
root=root->parent;
|
root=root->parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
leaf->box=box;
|
leaf->volume=volume;
|
||||||
insertleaf(this,root,leaf);
|
insertleaf(this,root,leaf);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
bool btDbvt::update(Node* leaf,Aabb box,const btVector3& velocity,btScalar margin)
|
bool btDbvt::update(Node* leaf,Volume volume,const btVector3& velocity,btScalar margin)
|
||||||
{
|
{
|
||||||
if(leaf->box.Contain(box)) return(false);
|
if(leaf->volume.Contain(volume)) return(false);
|
||||||
if(margin>0)
|
volume.Expand(btVector3(margin,margin,margin));
|
||||||
box.Expand(btVector3(margin,margin,margin));
|
volume.SignedExpand(velocity);
|
||||||
if(velocity.length2()>0)
|
update(leaf,volume);
|
||||||
box.SignedExpand(velocity);
|
return(true);
|
||||||
update(leaf,box);
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool btDbvt::update(Node* leaf,Volume volume,const btVector3& velocity)
|
||||||
|
{
|
||||||
|
if(leaf->volume.Contain(volume)) return(false);
|
||||||
|
volume.SignedExpand(velocity);
|
||||||
|
update(leaf,volume);
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool btDbvt::update(Node* leaf,Volume volume,btScalar margin)
|
||||||
|
{
|
||||||
|
if(leaf->volume.Contain(volume)) return(false);
|
||||||
|
volume.Expand(btVector3(margin,margin,margin));
|
||||||
|
update(leaf,volume);
|
||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,109 +462,32 @@ void btDbvt::remove(Node* leaf)
|
|||||||
{
|
{
|
||||||
removeleaf(this,leaf);
|
removeleaf(this,leaf);
|
||||||
deletenode(this,leaf);
|
deletenode(this,leaf);
|
||||||
|
--m_leafs;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
void btDbvt::collide(btDbvt* tree,
|
void btDbvt::collide(btDbvt* tree,
|
||||||
ICollide* icollide) const
|
ICollide* icollide) const
|
||||||
{
|
{
|
||||||
if(tree->m_root&&m_root)
|
collideGeneric(tree,GCollide(icollide));
|
||||||
{
|
|
||||||
btAlignedObjectArray<sStkElm> stack;
|
|
||||||
stack.reserve(128);
|
|
||||||
stack.push_back(sStkElm(m_root,tree->m_root));
|
|
||||||
do {
|
|
||||||
sStkElm p=stack[stack.size()-1];
|
|
||||||
stack.pop_back();
|
|
||||||
if(p.a==p.b)
|
|
||||||
{
|
|
||||||
if(p.a->isinternal())
|
|
||||||
{
|
|
||||||
stack.push_back(sStkElm(p.a->childs[0],p.a->childs[0]));
|
|
||||||
stack.push_back(sStkElm(p.a->childs[1],p.a->childs[1]));
|
|
||||||
stack.push_back(sStkElm(p.a->childs[0],p.a->childs[1]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(Intersect(p.a->box,p.b->box))
|
|
||||||
{
|
|
||||||
if(p.a->isinternal())
|
|
||||||
{
|
|
||||||
if(p.b->isinternal())
|
|
||||||
{
|
|
||||||
stack.push_back(sStkElm(p.a->childs[0],p.b->childs[0]));
|
|
||||||
stack.push_back(sStkElm(p.a->childs[1],p.b->childs[0]));
|
|
||||||
stack.push_back(sStkElm(p.a->childs[0],p.b->childs[1]));
|
|
||||||
stack.push_back(sStkElm(p.a->childs[1],p.b->childs[1]));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stack.push_back(sStkElm(p.a->childs[0],p.b));
|
|
||||||
stack.push_back(sStkElm(p.a->childs[1],p.b));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(p.b->isinternal())
|
|
||||||
{
|
|
||||||
stack.push_back(sStkElm(p.a,p.b->childs[0]));
|
|
||||||
stack.push_back(sStkElm(p.a,p.b->childs[1]));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
icollide->Process(p.a,p.b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while(stack.size()>0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
void btDbvt::collide(const Aabb& box,
|
void btDbvt::collide(btDbvt::Node* node,
|
||||||
ICollide* icollide) const
|
ICollide* icollide) const
|
||||||
{
|
{
|
||||||
if(m_root)
|
collideGeneric(node,GCollide(icollide));
|
||||||
{
|
|
||||||
btAlignedObjectArray<const Node*> stack;
|
|
||||||
stack.reserve(64);
|
|
||||||
stack.push_back(m_root);
|
|
||||||
do {
|
|
||||||
const Node* n=stack[stack.size()-1];
|
|
||||||
stack.pop_back();
|
|
||||||
if(Intersect(n->box,box))
|
|
||||||
{
|
|
||||||
if(n->isinternal())
|
|
||||||
{
|
|
||||||
stack.push_back(n->childs[0]);
|
|
||||||
stack.push_back(n->childs[1]);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
//
|
||||||
|
void btDbvt::collide(const Volume& volume,
|
||||||
|
ICollide* icollide) const
|
||||||
{
|
{
|
||||||
icollide->Process(n);
|
collideGeneric(volume,GCollide(icollide));
|
||||||
}
|
|
||||||
}
|
|
||||||
} while(stack.size()>0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
void btDbvt::collide(ICollide* icollide) const
|
void btDbvt::collide(ICollide* icollide) const
|
||||||
{
|
{
|
||||||
if(m_root)
|
collideGeneric(GCollide(icollide));
|
||||||
{
|
|
||||||
btAlignedObjectArray<const Node*> stack;
|
|
||||||
stack.reserve(64);
|
|
||||||
stack.push_back(m_root);
|
|
||||||
do {
|
|
||||||
const Node* n=stack[stack.size()-1];
|
|
||||||
stack.pop_back();
|
|
||||||
if(icollide->Descent(n))
|
|
||||||
{
|
|
||||||
if(n->isinternal())
|
|
||||||
{ stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); }
|
|
||||||
else
|
|
||||||
{ icollide->Process(n); }
|
|
||||||
}
|
|
||||||
} while(stack.size()>0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ subject to the following restrictions:
|
|||||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
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.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
///btSoftBody implementation by Nathanael Presson
|
///btDbvt implementation by Nathanael Presson
|
||||||
|
|
||||||
#ifndef BT_DYNAMIC_BOUNDING_VOLUME_TREE_H
|
#ifndef BT_DYNAMIC_BOUNDING_VOLUME_TREE_H
|
||||||
#define BT_DYNAMIC_BOUNDING_VOLUME_TREE_H
|
#define BT_DYNAMIC_BOUNDING_VOLUME_TREE_H
|
||||||
@@ -21,45 +21,51 @@ subject to the following restrictions:
|
|||||||
#include "LinearMath/btVector3.h"
|
#include "LinearMath/btVector3.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
// Dynamic bounding volume tree
|
// Defaults volumes
|
||||||
//
|
//
|
||||||
struct btDbvt
|
|
||||||
{
|
|
||||||
// Types
|
|
||||||
|
|
||||||
/* Aabb */
|
/* btDbvtAabbMm */
|
||||||
struct Aabb
|
struct btDbvtAabbMm
|
||||||
{
|
{
|
||||||
inline btVector3 Center() const { return((mi+mx)/2); }
|
inline btVector3 Center() const { return((mi+mx)/2); }
|
||||||
inline btVector3 Extent() const { return((mx-mi)/2); }
|
inline btVector3 Extent() const { return((mx-mi)/2); }
|
||||||
inline const btVector3& Mins() const { return(mi); }
|
inline const btVector3& Mins() const { return(mi); }
|
||||||
inline const btVector3& Maxs() const { return(mx); }
|
inline const btVector3& Maxs() const { return(mx); }
|
||||||
inline btVector3 Lengths() const { return(mx-mi); }
|
inline btVector3 Lengths() const { return(mx-mi); }
|
||||||
static inline Aabb FromCE(const btVector3& c,const btVector3& e);
|
static inline btDbvtAabbMm FromCE(const btVector3& c,const btVector3& e);
|
||||||
static inline Aabb FromCR(const btVector3& c,btScalar r);
|
static inline btDbvtAabbMm FromCR(const btVector3& c,btScalar r);
|
||||||
static inline Aabb FromMM(const btVector3& mi,const btVector3& mx);
|
static inline btDbvtAabbMm FromMM(const btVector3& mi,const btVector3& mx);
|
||||||
static inline Aabb FromPoints(const btVector3* pts,int n);
|
static inline btDbvtAabbMm FromPoints(const btVector3* pts,int n);
|
||||||
static inline Aabb FromPoints(const btVector3** ppts,int n);
|
static inline btDbvtAabbMm FromPoints(const btVector3** ppts,int n);
|
||||||
inline void Expand(const btVector3 e);
|
inline void Expand(const btVector3 e);
|
||||||
inline void SignedExpand(const btVector3 e);
|
inline void SignedExpand(const btVector3 e);
|
||||||
inline bool Contain(const Aabb& a) const;
|
inline bool Contain(const btDbvtAabbMm& a) const;
|
||||||
inline friend bool Intersect( const Aabb& a,
|
inline friend bool Intersect( const btDbvtAabbMm& a,
|
||||||
const Aabb& b);
|
const btDbvtAabbMm& b);
|
||||||
inline friend bool Intersect( const Aabb& a,
|
inline friend bool Intersect( const btDbvtAabbMm& a,
|
||||||
const btVector3& b);
|
const btVector3& b);
|
||||||
inline friend btScalar Proximity( const Aabb& a,
|
inline friend btScalar Proximity( const btDbvtAabbMm& a,
|
||||||
const Aabb& b);
|
const btDbvtAabbMm& b);
|
||||||
inline friend void Merge( const Aabb& a,
|
inline friend void Merge( const btDbvtAabbMm& a,
|
||||||
const Aabb& b,
|
const btDbvtAabbMm& b,
|
||||||
Aabb& r);
|
btDbvtAabbMm& r);
|
||||||
inline friend bool NotEqual( const Aabb& a,
|
inline friend bool NotEqual( const btDbvtAabbMm& a,
|
||||||
const Aabb& b);
|
const btDbvtAabbMm& b);
|
||||||
|
private:
|
||||||
btVector3 mi,mx;
|
btVector3 mi,mx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Dynamic bounding volume tree
|
||||||
|
//
|
||||||
|
struct btDbvt
|
||||||
|
{
|
||||||
|
// Types
|
||||||
|
typedef btDbvtAabbMm Volume;
|
||||||
/* Node */
|
/* Node */
|
||||||
struct Node
|
struct Node
|
||||||
{
|
{
|
||||||
Aabb box;
|
Volume volume;
|
||||||
Node* parent;
|
Node* parent;
|
||||||
bool isleaf() const { return(childs[1]==0); }
|
bool isleaf() const { return(childs[1]==0); }
|
||||||
bool isinternal() const { return(!isleaf()); }
|
bool isinternal() const { return(!isleaf()); }
|
||||||
@@ -85,39 +91,312 @@ struct btDbvt
|
|||||||
virtual void Process(const Node*) {}
|
virtual void Process(const Node*) {}
|
||||||
virtual bool Descent(const Node*) { return(false); }
|
virtual bool Descent(const Node*) { return(false); }
|
||||||
};
|
};
|
||||||
|
/* GCollide */
|
||||||
|
struct GCollide
|
||||||
|
{
|
||||||
|
ICollide* icollide;
|
||||||
|
GCollide(ICollide* ic) : icollide(ic) {}
|
||||||
|
void Process(const Node* a,const Node* b) { icollide->Process(a,b); }
|
||||||
|
void Process(const Node* a) { icollide->Process(a); }
|
||||||
|
bool Descent(const Node* a) { return(icollide->Descent(a)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
enum {
|
||||||
|
TREETREE_STACKSIZE = 128,
|
||||||
|
VOLUMETREE_STACKSIZE = 64,
|
||||||
|
};
|
||||||
|
|
||||||
// Fields
|
// Fields
|
||||||
Node* m_root;
|
Node* m_root;
|
||||||
Node* m_free;
|
Node* m_free;
|
||||||
int m_lkhd;
|
int m_lkhd;
|
||||||
|
int m_leafs;
|
||||||
// Methods
|
// Methods
|
||||||
btDbvt();
|
btDbvt();
|
||||||
~btDbvt();
|
~btDbvt();
|
||||||
void clear();
|
void clear();
|
||||||
bool empty() const { return(0==m_root); }
|
bool empty() const { return(0==m_root); }
|
||||||
int leafCount() const;
|
|
||||||
void optimizeBottomUp();
|
void optimizeBottomUp();
|
||||||
void optimizeTopDown(int bu_treshold=128);
|
void optimizeTopDown(int bu_treshold=128);
|
||||||
Node* insert(const Aabb& box,void* data);
|
Node* insert(const Volume& box,void* data);
|
||||||
void update(Node* leaf,const Aabb& box);
|
void update(Node* leaf,int lookahead=1);
|
||||||
bool update(Node* leaf,Aabb box,const btVector3& velocity,btScalar margin);
|
void update(Node* leaf,const Volume& volume);
|
||||||
|
bool update(Node* leaf,Volume volume,const btVector3& velocity,btScalar margin);
|
||||||
|
bool update(Node* leaf,Volume volume,const btVector3& velocity);
|
||||||
|
bool update(Node* leaf,Volume volume,btScalar margin);
|
||||||
void remove(Node* leaf);
|
void remove(Node* leaf);
|
||||||
void collide(btDbvt* tree,
|
void collide(btDbvt* tree,
|
||||||
ICollide* icollide) const;
|
ICollide* icollide) const;
|
||||||
void collide(const Aabb& box,
|
void collide(btDbvt::Node* node,
|
||||||
|
ICollide* icollide) const;
|
||||||
|
void collide(const Volume& volume,
|
||||||
ICollide* icollide) const;
|
ICollide* icollide) const;
|
||||||
void collide(const btVector3& org,
|
void collide(const btVector3& org,
|
||||||
const btVector3& dir,
|
const btVector3& dir,
|
||||||
ICollide* icollide) const;
|
ICollide* icollide) const;
|
||||||
void collide(ICollide* icollide) const;
|
void collide(ICollide* icollide) const;
|
||||||
// Generics
|
// Generics : T must implement ICollide
|
||||||
template <typename T/* must implement ICollide*/>
|
template <typename T>
|
||||||
void collideGeneric(T& policy) const
|
void collideGeneric( btDbvt* tree,T& policy) const;
|
||||||
|
template <typename T>
|
||||||
|
void collideGeneric( btDbvt::Node* node,T& policy) const;
|
||||||
|
template <typename T>
|
||||||
|
void collideGeneric(const Volume& volume,T& policy) const;
|
||||||
|
template <typename T>
|
||||||
|
void collideGeneric(T& policy) const;
|
||||||
|
//
|
||||||
|
private:
|
||||||
|
btDbvt(const btDbvt&) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inline's
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
inline btDbvtAabbMm btDbvtAabbMm::FromCE(const btVector3& c,const btVector3& e)
|
||||||
|
{
|
||||||
|
btDbvtAabbMm box;
|
||||||
|
box.mi=c-e;box.mx=c+e;
|
||||||
|
return(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
inline btDbvtAabbMm btDbvtAabbMm::FromCR(const btVector3& c,btScalar r)
|
||||||
|
{
|
||||||
|
return(FromCE(c,btVector3(r,r,r)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
inline btDbvtAabbMm btDbvtAabbMm::FromMM(const btVector3& mi,const btVector3& mx)
|
||||||
|
{
|
||||||
|
btDbvtAabbMm box;
|
||||||
|
box.mi=mi;box.mx=mx;
|
||||||
|
return(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
inline btDbvtAabbMm btDbvtAabbMm::FromPoints(const btVector3* pts,int n)
|
||||||
|
{
|
||||||
|
btDbvtAabbMm box;
|
||||||
|
box.mi=box.mx=pts[0];
|
||||||
|
for(int i=1;i<n;++i)
|
||||||
|
{
|
||||||
|
box.mi.setMin(pts[i]);
|
||||||
|
box.mx.setMax(pts[i]);
|
||||||
|
}
|
||||||
|
return(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
inline btDbvtAabbMm btDbvtAabbMm::FromPoints(const btVector3** ppts,int n)
|
||||||
|
{
|
||||||
|
btDbvtAabbMm box;
|
||||||
|
box.mi=box.mx=*ppts[0];
|
||||||
|
for(int i=1;i<n;++i)
|
||||||
|
{
|
||||||
|
box.mi.setMin(*ppts[i]);
|
||||||
|
box.mx.setMax(*ppts[i]);
|
||||||
|
}
|
||||||
|
return(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
inline void btDbvtAabbMm::Expand(const btVector3 e)
|
||||||
|
{
|
||||||
|
mi-=e;mx+=e;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
inline void btDbvtAabbMm::SignedExpand(const btVector3 e)
|
||||||
|
{
|
||||||
|
if(e.x()>0) mx.setX(mx.x()+e.x()); else mi.setX(mi.x()+e.x());
|
||||||
|
if(e.y()>0) mx.setY(mx.y()+e.y()); else mi.setY(mi.y()+e.y());
|
||||||
|
if(e.z()>0) mx.setZ(mx.z()+e.z()); else mi.setZ(mi.z()+e.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
inline bool btDbvtAabbMm::Contain(const btDbvtAabbMm& a) const
|
||||||
|
{
|
||||||
|
return( (mi.x()<=a.mi.x())&&
|
||||||
|
(mi.y()<=a.mi.y())&&
|
||||||
|
(mi.z()<=a.mi.z())&&
|
||||||
|
(mx.x()>=a.mx.x())&&
|
||||||
|
(mx.y()>=a.mx.y())&&
|
||||||
|
(mx.z()>=a.mx.z()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
inline bool Intersect( const btDbvtAabbMm& a,
|
||||||
|
const btDbvtAabbMm& b)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
const btScalar mi[]={ b.mx.x()-a.mi.x(),
|
||||||
|
b.mx.y()-a.mi.y(),
|
||||||
|
b.mx.z()-a.mi.z()};
|
||||||
|
const unsigned* imi=(const unsigned*)mi;
|
||||||
|
if((imi[0]|imi[1]|imi[2])&0x80000000) return(false);
|
||||||
|
const btScalar mx[]={ a.mx.x()-b.mi.x(),
|
||||||
|
a.mx.y()-b.mi.y(),
|
||||||
|
a.mx.z()-b.mi.z()};
|
||||||
|
const unsigned* imx=(const unsigned*)mx;
|
||||||
|
if((imx[0]|imx[1]|imx[2])&0x80000000) return(false);
|
||||||
|
return(true);
|
||||||
|
#else
|
||||||
|
return( (a.mi.x()<=b.mx.x())&&
|
||||||
|
(a.mi.y()<=b.mx.y())&&
|
||||||
|
(a.mi.z()<=b.mx.z())&&
|
||||||
|
(a.mx.x()>=b.mi.x())&&
|
||||||
|
(a.mx.y()>=b.mi.y())&&
|
||||||
|
(a.mx.z()>=b.mi.z()));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
inline bool Intersect( const btDbvtAabbMm& a,
|
||||||
|
const btVector3& b)
|
||||||
|
{
|
||||||
|
return( (b.x()>=a.mi.x())&&
|
||||||
|
(b.y()>=a.mi.y())&&
|
||||||
|
(b.z()>=a.mi.z())&&
|
||||||
|
(b.x()<=a.mx.x())&&
|
||||||
|
(b.y()<=a.mx.y())&&
|
||||||
|
(b.z()<=a.mx.z()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
inline btScalar Proximity( const btDbvtAabbMm& a,
|
||||||
|
const btDbvtAabbMm& b)
|
||||||
|
{
|
||||||
|
const btVector3 d=(a.mi+a.mx)-(b.mi+b.mx);
|
||||||
|
return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
inline void Merge( const btDbvtAabbMm& a,
|
||||||
|
const btDbvtAabbMm& b,
|
||||||
|
btDbvtAabbMm& r)
|
||||||
|
{
|
||||||
|
r=a;
|
||||||
|
r.mi.setMin(b.mi);
|
||||||
|
r.mx.setMax(b.mx);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
inline bool NotEqual( const btDbvtAabbMm& a,
|
||||||
|
const btDbvtAabbMm& b)
|
||||||
|
{
|
||||||
|
return( (a.mi.x()!=b.mi.x())||
|
||||||
|
(a.mi.y()!=b.mi.y())||
|
||||||
|
(a.mi.z()!=b.mi.z())||
|
||||||
|
(a.mx.x()!=b.mx.x())||
|
||||||
|
(a.mx.y()!=b.mx.y())||
|
||||||
|
(a.mx.z()!=b.mx.z()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Generic's
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
template <typename T>
|
||||||
|
inline void btDbvt::collideGeneric( btDbvt::Node* node,T& policy) const
|
||||||
|
{
|
||||||
|
if(m_root&&node)
|
||||||
|
{
|
||||||
|
btAlignedObjectArray<sStkElm> stack;
|
||||||
|
stack.reserve(TREETREE_STACKSIZE);
|
||||||
|
stack.push_back(sStkElm(m_root,node));
|
||||||
|
do {
|
||||||
|
sStkElm p=stack[stack.size()-1];
|
||||||
|
stack.pop_back();
|
||||||
|
if(p.a==p.b)
|
||||||
|
{
|
||||||
|
if(p.a->isinternal())
|
||||||
|
{
|
||||||
|
stack.push_back(sStkElm(p.a->childs[0],p.a->childs[0]));
|
||||||
|
stack.push_back(sStkElm(p.a->childs[1],p.a->childs[1]));
|
||||||
|
stack.push_back(sStkElm(p.a->childs[0],p.a->childs[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(Intersect(p.a->volume,p.b->volume))
|
||||||
|
{
|
||||||
|
if(p.a->isinternal())
|
||||||
|
{
|
||||||
|
if(p.b->isinternal())
|
||||||
|
{
|
||||||
|
stack.push_back(sStkElm(p.a->childs[0],p.b->childs[0]));
|
||||||
|
stack.push_back(sStkElm(p.a->childs[1],p.b->childs[0]));
|
||||||
|
stack.push_back(sStkElm(p.a->childs[0],p.b->childs[1]));
|
||||||
|
stack.push_back(sStkElm(p.a->childs[1],p.b->childs[1]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stack.push_back(sStkElm(p.a->childs[0],p.b));
|
||||||
|
stack.push_back(sStkElm(p.a->childs[1],p.b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(p.b->isinternal())
|
||||||
|
{
|
||||||
|
stack.push_back(sStkElm(p.a,p.b->childs[0]));
|
||||||
|
stack.push_back(sStkElm(p.a,p.b->childs[1]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
policy.Process(p.a,p.b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while(stack.size()>0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
template <typename T>
|
||||||
|
inline void btDbvt::collideGeneric( btDbvt* tree,T& policy) const
|
||||||
|
{
|
||||||
|
collideGeneric<T>(tree->m_root,policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
template <typename T>
|
||||||
|
inline void btDbvt::collideGeneric(const Volume& volume,T& policy) const
|
||||||
{
|
{
|
||||||
if(m_root)
|
if(m_root)
|
||||||
{
|
{
|
||||||
btAlignedObjectArray<const Node*> stack;
|
btAlignedObjectArray<const Node*> stack;
|
||||||
stack.reserve(64);
|
stack.reserve(VOLUMETREE_STACKSIZE);
|
||||||
|
stack.push_back(m_root);
|
||||||
|
do {
|
||||||
|
const Node* n=stack[stack.size()-1];
|
||||||
|
stack.pop_back();
|
||||||
|
if(Intersect(n->volume,volume))
|
||||||
|
{
|
||||||
|
if(n->isinternal())
|
||||||
|
{
|
||||||
|
stack.push_back(n->childs[0]);
|
||||||
|
stack.push_back(n->childs[1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
policy.Process(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while(stack.size()>0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
template <typename T>
|
||||||
|
inline void btDbvt::collideGeneric(T& policy) const
|
||||||
|
{
|
||||||
|
if(m_root)
|
||||||
|
{
|
||||||
|
btAlignedObjectArray<const Node*> stack;
|
||||||
|
stack.reserve(VOLUMETREE_STACKSIZE);
|
||||||
stack.push_back(m_root);
|
stack.push_back(m_root);
|
||||||
do {
|
do {
|
||||||
const Node* n=stack[stack.size()-1];
|
const Node* n=stack[stack.size()-1];
|
||||||
@@ -132,140 +411,5 @@ struct btDbvt
|
|||||||
} while(stack.size()>0);
|
} while(stack.size()>0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
|
||||||
private:
|
|
||||||
btDbvt(const btDbvt&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Inline's
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
inline btDbvt::Aabb btDbvt::Aabb::FromCE(const btVector3& c,const btVector3& e)
|
|
||||||
{
|
|
||||||
Aabb box;
|
|
||||||
box.mi=c-e;box.mx=c+e;
|
|
||||||
return(box);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
inline btDbvt::Aabb btDbvt::Aabb::FromCR(const btVector3& c,btScalar r)
|
|
||||||
{
|
|
||||||
return(FromCE(c,btVector3(r,r,r)));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
inline btDbvt::Aabb btDbvt::Aabb::FromMM(const btVector3& mi,const btVector3& mx)
|
|
||||||
{
|
|
||||||
Aabb box;
|
|
||||||
box.mi=mi;box.mx=mx;
|
|
||||||
return(box);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
inline btDbvt::Aabb btDbvt::Aabb::FromPoints(const btVector3* pts,int n)
|
|
||||||
{
|
|
||||||
Aabb box;
|
|
||||||
box.mi=box.mx=pts[0];
|
|
||||||
for(int i=1;i<n;++i)
|
|
||||||
{
|
|
||||||
box.mi.setMin(pts[i]);
|
|
||||||
box.mx.setMax(pts[i]);
|
|
||||||
}
|
|
||||||
return(box);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
inline btDbvt::Aabb btDbvt::Aabb::FromPoints(const btVector3** ppts,int n)
|
|
||||||
{
|
|
||||||
Aabb box;
|
|
||||||
box.mi=box.mx=*ppts[0];
|
|
||||||
for(int i=1;i<n;++i)
|
|
||||||
{
|
|
||||||
box.mi.setMin(*ppts[i]);
|
|
||||||
box.mx.setMax(*ppts[i]);
|
|
||||||
}
|
|
||||||
return(box);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
inline void btDbvt::Aabb::Expand(const btVector3 e)
|
|
||||||
{
|
|
||||||
mi-=e;mx+=e;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
inline void btDbvt::Aabb::SignedExpand(const btVector3 e)
|
|
||||||
{
|
|
||||||
if(e.x()>0) mx.setX(mx.x()+e.x()); else mi.setX(mi.x()+e.x());
|
|
||||||
if(e.y()>0) mx.setY(mx.y()+e.y()); else mi.setY(mi.y()+e.y());
|
|
||||||
if(e.z()>0) mx.setZ(mx.z()+e.z()); else mi.setZ(mi.z()+e.z());
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
inline bool btDbvt::Aabb::Contain(const Aabb& a) const
|
|
||||||
{
|
|
||||||
return( (mi.x()<=a.mi.x())&&
|
|
||||||
(mi.y()<=a.mi.y())&&
|
|
||||||
(mi.z()<=a.mi.z())&&
|
|
||||||
(mx.x()>=a.mx.x())&&
|
|
||||||
(mx.y()>=a.mx.y())&&
|
|
||||||
(mx.z()>=a.mx.z()));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
inline bool Intersect( const btDbvt::Aabb& a,
|
|
||||||
const btDbvt::Aabb& b)
|
|
||||||
{
|
|
||||||
return( (a.mi.x()<=b.mx.x())&&
|
|
||||||
(a.mi.y()<=b.mx.y())&&
|
|
||||||
(a.mi.z()<=b.mx.z())&&
|
|
||||||
(a.mx.x()>=b.mi.x())&&
|
|
||||||
(a.mx.y()>=b.mi.y())&&
|
|
||||||
(a.mx.z()>=b.mi.z()));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
inline bool Intersect( const btDbvt::Aabb& a,
|
|
||||||
const btVector3& b)
|
|
||||||
{
|
|
||||||
return( (b.x()>=a.mi.x())&&
|
|
||||||
(b.y()>=a.mi.y())&&
|
|
||||||
(b.z()>=a.mi.z())&&
|
|
||||||
(b.x()<=a.mx.x())&&
|
|
||||||
(b.y()<=a.mx.y())&&
|
|
||||||
(b.z()<=a.mx.z()));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
inline btScalar Proximity( const btDbvt::Aabb& a,
|
|
||||||
const btDbvt::Aabb& b)
|
|
||||||
{
|
|
||||||
const btVector3 d=(a.mi+a.mx)-(b.mi+b.mx);
|
|
||||||
return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z()));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
inline void Merge( const btDbvt::Aabb& a,
|
|
||||||
const btDbvt::Aabb& b,
|
|
||||||
btDbvt::Aabb& r)
|
|
||||||
{
|
|
||||||
r=a;
|
|
||||||
r.mi.setMin(b.mi);
|
|
||||||
r.mx.setMax(b.mx);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
inline bool NotEqual( const btDbvt::Aabb& a,
|
|
||||||
const btDbvt::Aabb& b)
|
|
||||||
{
|
|
||||||
return( (a.mi.x()!=b.mi.x())||
|
|
||||||
(a.mi.y()!=b.mi.y())||
|
|
||||||
(a.mi.z()!=b.mi.z())||
|
|
||||||
(a.mx.x()!=b.mx.x())||
|
|
||||||
(a.mx.y()!=b.mx.y())||
|
|
||||||
(a.mx.z()!=b.mx.z()));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
342
src/BulletSoftBody/btDbvtBroadphase.cpp
Normal file
342
src/BulletSoftBody/btDbvtBroadphase.cpp
Normal file
@@ -0,0 +1,342 @@
|
|||||||
|
/*
|
||||||
|
Bullet Continuous Collision Detection and Physics Library
|
||||||
|
Copyright (c) 2003-2007 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.
|
||||||
|
*/
|
||||||
|
///btDbvtBroadphase implementation by Nathanael Presson
|
||||||
|
|
||||||
|
#include "btDbvtBroadphase.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Profiling
|
||||||
|
//
|
||||||
|
|
||||||
|
#if DBVT_BP_PROFILE
|
||||||
|
#include <stdio.h>
|
||||||
|
struct ProfileScope
|
||||||
|
{
|
||||||
|
ProfileScope(btClock& clock,unsigned long& value)
|
||||||
|
{
|
||||||
|
m_clock=&clock;
|
||||||
|
m_value=&value;
|
||||||
|
m_base=clock.getTimeMicroseconds();
|
||||||
|
}
|
||||||
|
~ProfileScope()
|
||||||
|
{
|
||||||
|
(*m_value)+=m_clock->getTimeMicroseconds()-m_base;
|
||||||
|
}
|
||||||
|
btClock* m_clock;
|
||||||
|
unsigned long* m_value;
|
||||||
|
unsigned long m_base;
|
||||||
|
};
|
||||||
|
#define SPC(_value_) ProfileScope spc_scope(m_clock,_value_)
|
||||||
|
#else
|
||||||
|
#define SPC(_value_)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Helpers
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
static inline int hash(unsigned int i,unsigned int j)
|
||||||
|
{
|
||||||
|
int key=((unsigned int)i)|(((unsigned int)j)<<16);
|
||||||
|
key+=~(key<<15);
|
||||||
|
key^= (key>>10);
|
||||||
|
key+= (key<<3);
|
||||||
|
key^= (key>>6);
|
||||||
|
key+=~(key<<11);
|
||||||
|
key^= (key>>16);
|
||||||
|
return(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
template <typename T>
|
||||||
|
static inline void listappend(T* item,T*& list)
|
||||||
|
{
|
||||||
|
item->links[0]=0;
|
||||||
|
item->links[1]=list;
|
||||||
|
if(list) list->links[0]=item;
|
||||||
|
list=item;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
template <typename T>
|
||||||
|
static inline void listremove(T* item,T*& list)
|
||||||
|
{
|
||||||
|
if(item->links[0]) item->links[0]->links[1]=item->links[1]; else list=item->links[1];
|
||||||
|
if(item->links[1]) item->links[1]->links[0]=item->links[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
template <typename T>
|
||||||
|
static inline int listcount(T* root)
|
||||||
|
{
|
||||||
|
int n=0;
|
||||||
|
while(root) { ++n;root=root->links[1]; }
|
||||||
|
return(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
template <typename T>
|
||||||
|
static inline void clear(T& value)
|
||||||
|
{
|
||||||
|
static const T zerodummy;
|
||||||
|
value=zerodummy;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Collider
|
||||||
|
//
|
||||||
|
struct btDbvtBroadphaseCollider : btDbvt::ICollide
|
||||||
|
{
|
||||||
|
btDbvtBroadphase* pbp;
|
||||||
|
int pid;
|
||||||
|
btDbvtBroadphaseCollider(btDbvtBroadphase* p,int id) : pbp(p),pid(id) {}
|
||||||
|
void Process(const btDbvt::Node* na,const btDbvt::Node* nb)
|
||||||
|
{
|
||||||
|
btDbvtProxy* pa=(btDbvtProxy*)na->data;
|
||||||
|
btDbvtProxy* pb=(btDbvtProxy*)nb->data;
|
||||||
|
#if DBVT_BP_DISCRETPAIRS
|
||||||
|
if(Intersect(pa->aabb,pb->aabb))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
btBroadphasePair* pp=pbp->m_paircache->addOverlappingPair(pa,pb);
|
||||||
|
if(pp) pp->m_userInfo=*(void**)&pid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// btDbvtBroadphase
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
btDbvtBroadphase::btDbvtBroadphase()
|
||||||
|
{
|
||||||
|
m_fcursor = 0;
|
||||||
|
m_dcursor = 0;
|
||||||
|
m_stageCurrent = 0;
|
||||||
|
m_fupdates = 1;
|
||||||
|
m_dupdates = 0;
|
||||||
|
m_paircache = new btHashedOverlappingPairCache();
|
||||||
|
m_gid = 0;
|
||||||
|
m_pid = 0;
|
||||||
|
for(int i=0;i<=STAGECOUNT;++i)
|
||||||
|
{
|
||||||
|
m_stageRoots[i]=0;
|
||||||
|
}
|
||||||
|
#if DBVT_BP_PROFILE
|
||||||
|
clear(m_profiling);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
btDbvtBroadphase::~btDbvtBroadphase()
|
||||||
|
{
|
||||||
|
delete m_paircache;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
btBroadphaseProxy* btDbvtBroadphase::createProxy( const btVector3& aabbMin,
|
||||||
|
const btVector3& aabbMax,
|
||||||
|
int shapeType,
|
||||||
|
void* userPtr,
|
||||||
|
short int collisionFilterGroup,
|
||||||
|
short int collisionFilterMask,
|
||||||
|
btDispatcher* dispatcher,
|
||||||
|
void* multiSapProxy)
|
||||||
|
{
|
||||||
|
btDbvtProxy* proxy=new btDbvtProxy(userPtr,collisionFilterGroup,collisionFilterMask);
|
||||||
|
proxy->aabb = btDbvtAabbMm::FromMM(aabbMin,aabbMax);
|
||||||
|
proxy->leaf = m_sets[0].insert(proxy->aabb,proxy);
|
||||||
|
proxy->stage = m_stageCurrent;
|
||||||
|
proxy->m_uniqueId = ++m_gid;
|
||||||
|
listappend(proxy,m_stageRoots[m_stageCurrent]);
|
||||||
|
return(proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void btDbvtBroadphase::destroyProxy( btBroadphaseProxy* absproxy,
|
||||||
|
btDispatcher* dispatcher)
|
||||||
|
{
|
||||||
|
btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
|
||||||
|
if(proxy->stage==STAGECOUNT)
|
||||||
|
m_sets[1].remove(proxy->leaf);
|
||||||
|
else
|
||||||
|
m_sets[0].remove(proxy->leaf);
|
||||||
|
listremove(proxy,m_stageRoots[proxy->stage]);
|
||||||
|
m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher);
|
||||||
|
delete proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy,
|
||||||
|
const btVector3& aabbMin,
|
||||||
|
const btVector3& aabbMax,
|
||||||
|
btDispatcher* dispatcher)
|
||||||
|
{
|
||||||
|
btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
|
||||||
|
btDbvtAabbMm aabb=btDbvtAabbMm::FromMM(aabbMin,aabbMax);
|
||||||
|
if(proxy->stage==STAGECOUNT)
|
||||||
|
{/* fixed -> dynamic set */
|
||||||
|
m_sets[1].remove(proxy->leaf);
|
||||||
|
proxy->leaf=m_sets[0].insert(aabb,proxy);
|
||||||
|
m_fcursor=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{/* dynamic set */
|
||||||
|
const btVector3 delta=(aabbMin+aabbMax)/2-proxy->aabb.Center();
|
||||||
|
m_sets[0].update(proxy->leaf,aabb,delta*PREDICTED_FRAMES,DBVT_BP_MARGIN);
|
||||||
|
}
|
||||||
|
listremove(proxy,m_stageRoots[proxy->stage]);
|
||||||
|
proxy->aabb = aabb;
|
||||||
|
proxy->stage = m_stageCurrent;
|
||||||
|
listappend(proxy,m_stageRoots[m_stageCurrent]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
|
||||||
|
{
|
||||||
|
collide(dispatcher);
|
||||||
|
#if DBVT_BP_PROFILE
|
||||||
|
if(0==(m_pid%DBVT_BP_PROFILING_RATE))
|
||||||
|
{
|
||||||
|
printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leafs,m_sets[0].m_leafs,m_paircache->getNumOverlappingPairs());
|
||||||
|
unsigned int total=m_profiling.m_total;
|
||||||
|
if(total<=0) total=1;
|
||||||
|
printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE);
|
||||||
|
printf("fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/DBVT_BP_PROFILING_RATE);
|
||||||
|
printf("cleanup: %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/DBVT_BP_PROFILING_RATE);
|
||||||
|
printf("total: %uus\r\n",total/DBVT_BP_PROFILING_RATE);
|
||||||
|
const unsigned long sum=m_profiling.m_ddcollide+
|
||||||
|
m_profiling.m_fdcollide+
|
||||||
|
m_profiling.m_cleanup;
|
||||||
|
printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE);
|
||||||
|
clear(m_profiling);
|
||||||
|
m_clock.reset();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void btDbvtBroadphase::collide(btDispatcher* dispatcher)
|
||||||
|
{
|
||||||
|
SPC(m_profiling.m_total);
|
||||||
|
/* refine dynamic */
|
||||||
|
if(m_stageRoots[m_stageCurrent]&&(m_dupdates>0))
|
||||||
|
{
|
||||||
|
const int count=1+(m_sets[0].m_leafs*m_dupdates)/100;
|
||||||
|
for(int i=0;i<count;++i)
|
||||||
|
{
|
||||||
|
if(!m_dcursor) m_dcursor=m_stageRoots[m_stageCurrent];
|
||||||
|
m_sets[0].update(m_dcursor->leaf);
|
||||||
|
m_dcursor=m_dcursor->links[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* dynamic -> fixed set */
|
||||||
|
m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT;
|
||||||
|
btDbvtProxy* current=m_stageRoots[m_stageCurrent];
|
||||||
|
if(current)
|
||||||
|
{
|
||||||
|
btDbvtBroadphaseCollider collider(this,m_pid);
|
||||||
|
do {
|
||||||
|
btDbvtProxy* next=current->links[1];
|
||||||
|
if(m_dcursor==current) m_dcursor=0;
|
||||||
|
listremove(current,m_stageRoots[current->stage]);
|
||||||
|
listappend(current,m_stageRoots[STAGECOUNT]);
|
||||||
|
m_sets[1].collideGeneric(current->leaf,collider);
|
||||||
|
m_sets[0].remove(current->leaf);
|
||||||
|
current->leaf = m_sets[1].insert(current->aabb,current);
|
||||||
|
current->stage = STAGECOUNT;
|
||||||
|
current = next;
|
||||||
|
} while(current);
|
||||||
|
}
|
||||||
|
/* refine fixed */
|
||||||
|
if(m_stageRoots[STAGECOUNT]&&(m_fupdates>0))
|
||||||
|
{
|
||||||
|
const int count=1+(m_sets[1].m_leafs*m_fupdates)/100;
|
||||||
|
for(int i=0;i<count;++i)
|
||||||
|
{
|
||||||
|
if(!m_fcursor) m_fcursor=m_stageRoots[STAGECOUNT];
|
||||||
|
m_sets[1].update(m_fcursor->leaf);
|
||||||
|
m_fcursor=m_fcursor->links[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* collide dynamics */
|
||||||
|
btDbvtBroadphaseCollider collider(this,m_pid);
|
||||||
|
{
|
||||||
|
SPC(m_profiling.m_fdcollide);
|
||||||
|
m_sets[0].collideGeneric(&m_sets[1],collider);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SPC(m_profiling.m_ddcollide);
|
||||||
|
m_sets[0].collideGeneric(&m_sets[0],collider);
|
||||||
|
}
|
||||||
|
/* clean up */
|
||||||
|
{
|
||||||
|
SPC(m_profiling.m_cleanup);
|
||||||
|
btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray();
|
||||||
|
for(int i=0,ni=pairs.size();i<ni;++i)
|
||||||
|
{
|
||||||
|
btBroadphasePair& p=pairs[i];
|
||||||
|
if(m_pid!=(*(int*)&p.m_userInfo))
|
||||||
|
{
|
||||||
|
btDbvtProxy* pa=(btDbvtProxy*)p.m_pProxy0;
|
||||||
|
btDbvtProxy* pb=(btDbvtProxy*)p.m_pProxy1;
|
||||||
|
if(!Intersect(pa->aabb,pb->aabb))
|
||||||
|
{
|
||||||
|
m_paircache->removeOverlappingPair(pa,pb,dispatcher);
|
||||||
|
--ni;--i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++m_pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache()
|
||||||
|
{
|
||||||
|
return(m_paircache);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() const
|
||||||
|
{
|
||||||
|
return(m_paircache);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void btDbvtBroadphase::getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const
|
||||||
|
{
|
||||||
|
btDbvtAabbMm bounds;
|
||||||
|
if(!m_sets[0].empty())
|
||||||
|
if(!m_sets[1].empty()) Merge( m_sets[0].m_root->volume,
|
||||||
|
m_sets[1].m_root->volume,bounds);
|
||||||
|
else
|
||||||
|
bounds=m_sets[0].m_root->volume;
|
||||||
|
else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume;
|
||||||
|
else
|
||||||
|
bounds=btDbvtAabbMm::FromCR(btVector3(0,0,0),0);
|
||||||
|
aabbMin=bounds.Mins();
|
||||||
|
aabbMax=bounds.Maxs();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void btDbvtBroadphase::printStats()
|
||||||
|
{}
|
||||||
|
|
||||||
|
#if DBVT_BP_PROFILE
|
||||||
|
#undef SPC
|
||||||
|
#endif
|
||||||
108
src/BulletSoftBody/btDbvtBroadphase.h
Normal file
108
src/BulletSoftBody/btDbvtBroadphase.h
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
Bullet Continuous Collision Detection and Physics Library
|
||||||
|
Copyright (c) 2003-2007 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.
|
||||||
|
*/
|
||||||
|
///btDbvtBroadphase implementation by Nathanael Presson
|
||||||
|
|
||||||
|
#ifndef BT_DBVT_BROADPHASE_H
|
||||||
|
#define BT_DBVT_BROADPHASE_H
|
||||||
|
|
||||||
|
#include "btDbvt.h"
|
||||||
|
#include "LinearMath/btPoint3.h"
|
||||||
|
#include "LinearMath/btVector3.h"
|
||||||
|
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
|
||||||
|
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
|
||||||
|
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||||
|
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h"
|
||||||
|
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Compile time config
|
||||||
|
//
|
||||||
|
|
||||||
|
#define DBVT_BP_PROFILE 1
|
||||||
|
#define DBVT_BP_DISCRETPAIRS 0
|
||||||
|
#define DBVT_BP_MARGIN (btScalar)0.05
|
||||||
|
|
||||||
|
#if DBVT_BP_PROFILE
|
||||||
|
#define DBVT_BP_PROFILING_RATE 50
|
||||||
|
#include "LinearMath/btQuickprof.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// btDbvtProxy
|
||||||
|
//
|
||||||
|
struct btDbvtProxy : btBroadphaseProxy
|
||||||
|
{
|
||||||
|
/* Fields */
|
||||||
|
btDbvtAabbMm aabb;
|
||||||
|
btDbvt::Node* leaf;
|
||||||
|
btDbvtProxy* links[2];
|
||||||
|
int stage;
|
||||||
|
/* ctor */
|
||||||
|
btDbvtProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) :
|
||||||
|
btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask)
|
||||||
|
{
|
||||||
|
links[0]=links[1]=0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// btDbvtBroadphase
|
||||||
|
//
|
||||||
|
struct btDbvtBroadphase : btBroadphaseInterface
|
||||||
|
{
|
||||||
|
/* Config */
|
||||||
|
enum {
|
||||||
|
DYNAMIC_SET = 0, /* Dynamic set index */
|
||||||
|
FIXED_SET = 1, /* Fixed set index */
|
||||||
|
STAGECOUNT = 2, /* Number of stages */
|
||||||
|
PREDICTED_FRAMES = 2, /* Frames prediction */
|
||||||
|
};
|
||||||
|
/* Fields */
|
||||||
|
btDbvt m_sets[2]; // Dbvt sets
|
||||||
|
btDbvtProxy* m_stageRoots[STAGECOUNT+1]; // Stages list
|
||||||
|
int m_stageCurrent; // Current stage
|
||||||
|
btOverlappingPairCache* m_paircache; // Pair cache
|
||||||
|
btDbvtProxy* m_fcursor; // Current fixed cursor
|
||||||
|
btDbvtProxy* m_dcursor; // Current dynamic cursor
|
||||||
|
int m_fupdates; // % of fixed updates per frame
|
||||||
|
int m_dupdates; // % of dynamic updates per frame
|
||||||
|
int m_pid; // Parse id
|
||||||
|
int m_gid; // Gen id
|
||||||
|
#if DBVT_BP_PROFILE
|
||||||
|
btClock m_clock;
|
||||||
|
struct {
|
||||||
|
unsigned long m_total;
|
||||||
|
unsigned long m_ddcollide;
|
||||||
|
unsigned long m_fdcollide;
|
||||||
|
unsigned long m_cleanup;
|
||||||
|
} m_profiling;
|
||||||
|
#endif
|
||||||
|
/* Methods */
|
||||||
|
btDbvtBroadphase();
|
||||||
|
~btDbvtBroadphase();
|
||||||
|
void collide(btDispatcher* dispatcher);
|
||||||
|
/* btBroadphaseInterface Implementation */
|
||||||
|
btBroadphaseProxy* createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
|
||||||
|
void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
|
||||||
|
void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
|
||||||
|
void calculateOverlappingPairs(btDispatcher* dispatcher);
|
||||||
|
btOverlappingPairCache* getOverlappingPairCache();
|
||||||
|
const btOverlappingPairCache* getOverlappingPairCache() const;
|
||||||
|
void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const;
|
||||||
|
void printStats();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -39,12 +39,6 @@ public:
|
|||||||
// Enumerations
|
// Enumerations
|
||||||
//
|
//
|
||||||
|
|
||||||
///eLType
|
|
||||||
struct eLType { enum _ {
|
|
||||||
Structural, ///Master constraints
|
|
||||||
Bending, ///Secondary constraints
|
|
||||||
};};
|
|
||||||
|
|
||||||
///eAeroModel
|
///eAeroModel
|
||||||
struct eAeroModel { enum _ {
|
struct eAeroModel { enum _ {
|
||||||
V_Point, ///Vertex normals are oriented toward velocity
|
V_Point, ///Vertex normals are oriented toward velocity
|
||||||
@@ -54,6 +48,40 @@ public:
|
|||||||
F_OneSided, ///Face normals are taken as it is
|
F_OneSided, ///Face normals are taken as it is
|
||||||
};};
|
};};
|
||||||
|
|
||||||
|
///eVSolver : velocities solvers
|
||||||
|
struct eVSolver { enum _ {
|
||||||
|
Linear, ///Linear solver
|
||||||
|
Volume, ///Volume solver
|
||||||
|
};};
|
||||||
|
|
||||||
|
///ePSolver : positions solvers
|
||||||
|
struct ePSolver { enum _ {
|
||||||
|
Linear, ///Linear solver
|
||||||
|
Volume, ///Volume solver
|
||||||
|
Anchors, ///Anchor solver
|
||||||
|
RContacts, ///Rigid contacts solver
|
||||||
|
SContacts, ///Soft contacts solver
|
||||||
|
};};
|
||||||
|
|
||||||
|
///eSolverPresets
|
||||||
|
struct eSolverPresets { enum _ {
|
||||||
|
Positions,
|
||||||
|
Velocities,
|
||||||
|
Default = Positions,
|
||||||
|
};};
|
||||||
|
|
||||||
|
///eFeature
|
||||||
|
struct eFeature { enum _ {
|
||||||
|
None,
|
||||||
|
Node,
|
||||||
|
Link,
|
||||||
|
Face,
|
||||||
|
Tetra,
|
||||||
|
};};
|
||||||
|
|
||||||
|
typedef btAlignedObjectArray<eVSolver::_> tVSolverArray;
|
||||||
|
typedef btAlignedObjectArray<ePSolver::_> tPSolverArray;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Flags
|
// Flags
|
||||||
//
|
//
|
||||||
@@ -69,6 +97,13 @@ public:
|
|||||||
Default = SDF_RS,
|
Default = SDF_RS,
|
||||||
};};
|
};};
|
||||||
|
|
||||||
|
///fMaterial
|
||||||
|
struct fMaterial { enum _ {
|
||||||
|
DebugDraw = 0x0001, /// Enable debug draw
|
||||||
|
/* presets */
|
||||||
|
Default = DebugDraw,
|
||||||
|
};};
|
||||||
|
|
||||||
//
|
//
|
||||||
// API Types
|
// API Types
|
||||||
//
|
//
|
||||||
@@ -76,17 +111,24 @@ public:
|
|||||||
/* sRayCast */
|
/* sRayCast */
|
||||||
struct sRayCast
|
struct sRayCast
|
||||||
{
|
{
|
||||||
int face; /// face
|
btSoftBody* body; /// soft body
|
||||||
|
eFeature::_ feature; /// feature type
|
||||||
|
int index; /// feature index
|
||||||
btScalar time; /// time of impact (rayorg+raydir*time)
|
btScalar time; /// time of impact (rayorg+raydir*time)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ImplicitFn */
|
||||||
|
struct ImplicitFn
|
||||||
|
{
|
||||||
|
virtual btScalar Eval(const btVector3& x)=0;
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Internal types
|
// Internal types
|
||||||
//
|
//
|
||||||
|
|
||||||
typedef btAlignedObjectArray<btScalar> tScalarArray;
|
typedef btAlignedObjectArray<btScalar> tScalarArray;
|
||||||
typedef btAlignedObjectArray<btVector3> tVector3Array;
|
typedef btAlignedObjectArray<btVector3> tVector3Array;
|
||||||
|
|
||||||
/* btSoftBodyWorldInfo */
|
/* btSoftBodyWorldInfo */
|
||||||
struct btSoftBodyWorldInfo
|
struct btSoftBodyWorldInfo
|
||||||
{
|
{
|
||||||
@@ -121,8 +163,22 @@ public:
|
|||||||
{
|
{
|
||||||
void* m_tag; // User data
|
void* m_tag; // User data
|
||||||
};
|
};
|
||||||
|
/* Material */
|
||||||
|
struct Material : Element
|
||||||
|
{
|
||||||
|
btScalar m_kLST; // Linear stiffness coefficient [0,1]
|
||||||
|
btScalar m_kAST; // Area stiffness coefficient [0,1]
|
||||||
|
btScalar m_kVST; // Volume stiffness coefficient [0,1]
|
||||||
|
int m_flags; // Flags
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Feature */
|
||||||
|
struct Feature : Element
|
||||||
|
{
|
||||||
|
Material* m_material; // Material
|
||||||
|
};
|
||||||
/* Node */
|
/* Node */
|
||||||
struct Node : Element
|
struct Node : Feature
|
||||||
{
|
{
|
||||||
btVector3 m_x; // Position
|
btVector3 m_x; // Position
|
||||||
btVector3 m_q; // Previous step position
|
btVector3 m_q; // Previous step position
|
||||||
@@ -135,23 +191,33 @@ public:
|
|||||||
int m_battach:1; // Attached
|
int m_battach:1; // Attached
|
||||||
};
|
};
|
||||||
/* Link */
|
/* Link */
|
||||||
struct Link : Element
|
struct Link : Feature
|
||||||
{
|
{
|
||||||
Node* m_n[2]; // Node pointers
|
Node* m_n[2]; // Node pointers
|
||||||
btScalar m_rl; // Rest length
|
btScalar m_rl; // Rest length
|
||||||
btScalar m_kST; // Stiffness coefficient
|
|
||||||
btScalar m_c0; // (ima+imb)*kLST
|
btScalar m_c0; // (ima+imb)*kLST
|
||||||
btScalar m_c1; // rl^2
|
btScalar m_c1; // rl^2
|
||||||
btSoftBody::eLType::_ m_type; // Link type
|
btScalar m_c2; // |gradient|^2/c0
|
||||||
|
btVector3 m_c3; // gradient
|
||||||
};
|
};
|
||||||
/* Face */
|
/* Face */
|
||||||
struct Face : Element
|
struct Face : Feature
|
||||||
{
|
{
|
||||||
Node* m_n[3]; // Node pointers
|
Node* m_n[3]; // Node pointers
|
||||||
btVector3 m_normal; // Normal
|
btVector3 m_normal; // Normal
|
||||||
btScalar m_ra; // Rest area
|
btScalar m_ra; // Rest area
|
||||||
btDbvt::Node* m_leaf; // Leaf data
|
btDbvt::Node* m_leaf; // Leaf data
|
||||||
};
|
};
|
||||||
|
/* Tetra */
|
||||||
|
struct Tetra : Feature
|
||||||
|
{
|
||||||
|
Node* m_n[4]; // Node pointers
|
||||||
|
btScalar m_rv; // Rest volume
|
||||||
|
btDbvt::Node* m_leaf; // Leaf data
|
||||||
|
btVector3 m_c0[4]; // gradients
|
||||||
|
btScalar m_c1; // (4*kVST)/(im0+im1+im2+im3)
|
||||||
|
btScalar m_c2; // m_c1/sum(|g0..3|^2)
|
||||||
|
};
|
||||||
/* RContact */
|
/* RContact */
|
||||||
struct RContact
|
struct RContact
|
||||||
{
|
{
|
||||||
@@ -184,6 +250,15 @@ public:
|
|||||||
btVector3 m_c1; // Relative anchor
|
btVector3 m_c1; // Relative anchor
|
||||||
btScalar m_c2; // ima*dt
|
btScalar m_c2; // ima*dt
|
||||||
};
|
};
|
||||||
|
/* Note */
|
||||||
|
struct Note : Element
|
||||||
|
{
|
||||||
|
const char* m_text; // Text
|
||||||
|
btVector3 m_offset; // Offset
|
||||||
|
int m_rank; // Rank
|
||||||
|
Node* m_nodes[4]; // Nodes
|
||||||
|
btScalar m_coords[4]; // Coordinates
|
||||||
|
};
|
||||||
/* Pose */
|
/* Pose */
|
||||||
struct Pose
|
struct Pose
|
||||||
{
|
{
|
||||||
@@ -197,16 +272,11 @@ public:
|
|||||||
btMatrix3x3 m_scl; // Scale
|
btMatrix3x3 m_scl; // Scale
|
||||||
btMatrix3x3 m_aqq; // Base scaling
|
btMatrix3x3 m_aqq; // Base scaling
|
||||||
};
|
};
|
||||||
/* DFld */
|
|
||||||
struct DFld
|
|
||||||
{
|
|
||||||
btAlignedObjectArray<btVector3> pts;
|
|
||||||
};
|
|
||||||
/* Config */
|
/* Config */
|
||||||
struct Config
|
struct Config
|
||||||
{
|
{
|
||||||
btSoftBody::eAeroModel::_ aeromodel; // Aerodynamic model (default: V_Point)
|
eAeroModel::_ aeromodel; // Aerodynamic model (default: V_Point)
|
||||||
btScalar kLST; // Linear stiffness coefficient [0,1]
|
btScalar kVCF; // Velocities correction factor (Baumgarte)
|
||||||
btScalar kDP; // Damping coefficient [0,1]
|
btScalar kDP; // Damping coefficient [0,1]
|
||||||
btScalar kDG; // Drag coefficient [0,+inf]
|
btScalar kDG; // Drag coefficient [0,+inf]
|
||||||
btScalar kLF; // Lift coefficient [0,+inf]
|
btScalar kLF; // Lift coefficient [0,+inf]
|
||||||
@@ -214,19 +284,23 @@ public:
|
|||||||
btScalar kVC; // Volume conversation coefficient [0,+inf]
|
btScalar kVC; // Volume conversation coefficient [0,+inf]
|
||||||
btScalar kDF; // Dynamic friction coefficient [0,1]
|
btScalar kDF; // Dynamic friction coefficient [0,1]
|
||||||
btScalar kMT; // Pose matching coefficient [0,1]
|
btScalar kMT; // Pose matching coefficient [0,1]
|
||||||
btScalar kSOR; // SOR(w) [1,2] default 1, never use with solver!=Accurate
|
|
||||||
btScalar kCHR; // Rigid contacts hardness [0,1]
|
btScalar kCHR; // Rigid contacts hardness [0,1]
|
||||||
|
btScalar kKHR; // Kinetic contacts hardness [0,1]
|
||||||
btScalar kSHR; // Soft contacts hardness [0,1]
|
btScalar kSHR; // Soft contacts hardness [0,1]
|
||||||
btScalar kAHR; // Anchors hardness [0,1]
|
btScalar kAHR; // Anchors hardness [0,1]
|
||||||
btScalar maxvolume; // Maximum volume ratio for pose
|
btScalar maxvolume; // Maximum volume ratio for pose
|
||||||
btScalar timescale; // Time scale
|
btScalar timescale; // Time scale
|
||||||
int iterations; // Solver iterations
|
int viterations; // Velocities solver iterations
|
||||||
|
int piterations; // Positions solver iterations
|
||||||
|
int diterations; // Drift solver iterations
|
||||||
int collisions; // Collisions flags
|
int collisions; // Collisions flags
|
||||||
|
tVSolverArray m_vsequence; // Velocity solvers sequence
|
||||||
|
tPSolverArray m_psequence; // Position solvers sequence
|
||||||
|
tPSolverArray m_dsequence; // Drift solvers sequence
|
||||||
};
|
};
|
||||||
/* SolverState */
|
/* SolverState */
|
||||||
struct SolverState
|
struct SolverState
|
||||||
{
|
{
|
||||||
btScalar iit; // 1/iterations
|
|
||||||
btScalar sdt; // dt*timescale
|
btScalar sdt; // dt*timescale
|
||||||
btScalar isdt; // 1/sdt
|
btScalar isdt; // 1/sdt
|
||||||
btScalar velmrg; // velocity margin
|
btScalar velmrg; // velocity margin
|
||||||
@@ -238,13 +312,16 @@ public:
|
|||||||
// Typedef's
|
// Typedef's
|
||||||
//
|
//
|
||||||
|
|
||||||
|
typedef btAlignedObjectArray<Note> tNoteArray;
|
||||||
typedef btAlignedObjectArray<Node> tNodeArray;
|
typedef btAlignedObjectArray<Node> tNodeArray;
|
||||||
typedef btAlignedObjectArray<btDbvt::Node*> tLeafArray;
|
typedef btAlignedObjectArray<btDbvt::Node*> tLeafArray;
|
||||||
typedef btAlignedObjectArray<Link> tLinkArray;
|
typedef btAlignedObjectArray<Link> tLinkArray;
|
||||||
typedef btAlignedObjectArray<Face> tFaceArray;
|
typedef btAlignedObjectArray<Face> tFaceArray;
|
||||||
|
typedef btAlignedObjectArray<Tetra> tTetraArray;
|
||||||
typedef btAlignedObjectArray<Anchor> tAnchorArray;
|
typedef btAlignedObjectArray<Anchor> tAnchorArray;
|
||||||
typedef btAlignedObjectArray<RContact> tRContactArray;
|
typedef btAlignedObjectArray<RContact> tRContactArray;
|
||||||
typedef btAlignedObjectArray<SContact> tSContactArray;
|
typedef btAlignedObjectArray<SContact> tSContactArray;
|
||||||
|
typedef btAlignedObjectArray<Material*> tMaterialArray;
|
||||||
typedef btAlignedObjectArray<btSoftBody*> tSoftBodyArray;
|
typedef btAlignedObjectArray<btSoftBody*> tSoftBodyArray;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -254,18 +331,22 @@ public:
|
|||||||
Config m_cfg; // Configuration
|
Config m_cfg; // Configuration
|
||||||
SolverState m_sst; // Solver state
|
SolverState m_sst; // Solver state
|
||||||
Pose m_pose; // Pose
|
Pose m_pose; // Pose
|
||||||
DFld m_dfld; // Distance field
|
|
||||||
void* m_tag; // User data
|
void* m_tag; // User data
|
||||||
btSoftBodyWorldInfo* m_worldInfo; //
|
btSoftBodyWorldInfo* m_worldInfo; //
|
||||||
|
tNoteArray m_notes; // Notes
|
||||||
|
tNodeArray m_nodes; // Nodes
|
||||||
|
tLinkArray m_links; // Links
|
||||||
|
tFaceArray m_faces; // Faces
|
||||||
|
tTetraArray m_tetras; // Tetras
|
||||||
tAnchorArray m_anchors; // Anchors
|
tAnchorArray m_anchors; // Anchors
|
||||||
tRContactArray m_rcontacts; // Rigid contacts
|
tRContactArray m_rcontacts; // Rigid contacts
|
||||||
tSContactArray m_scontacts; // Soft contacts
|
tSContactArray m_scontacts; // Soft contacts
|
||||||
|
tMaterialArray m_materials; // Materials
|
||||||
btScalar m_timeacc; // Time accumulator
|
btScalar m_timeacc; // Time accumulator
|
||||||
btVector3 m_bounds[2]; // Spatial bounds
|
btVector3 m_bounds[2]; // Spatial bounds
|
||||||
bool m_bUpdateRtCst; // Update runtime constants
|
bool m_bUpdateRtCst; // Update runtime constants
|
||||||
btDbvt m_ndbvt; // Nodes tree
|
btDbvt m_ndbvt; // Nodes tree
|
||||||
btDbvt m_fdbvt; // Faces tree
|
btDbvt m_fdbvt; // Faces tree
|
||||||
|
|
||||||
//
|
//
|
||||||
// Api
|
// Api
|
||||||
//
|
//
|
||||||
@@ -285,21 +366,53 @@ public:
|
|||||||
bool checkFace( int node0,
|
bool checkFace( int node0,
|
||||||
int node1,
|
int node1,
|
||||||
int node2) const;
|
int node2) const;
|
||||||
|
/* Append material */
|
||||||
|
Material* appendMaterial();
|
||||||
|
/* Append note */
|
||||||
|
void appendNote( const char* text,
|
||||||
|
const btVector3& o,
|
||||||
|
const btVector4& c=btVector4(1,0,0,0),
|
||||||
|
Node* n0=0,
|
||||||
|
Node* n1=0,
|
||||||
|
Node* n2=0,
|
||||||
|
Node* n3=0);
|
||||||
|
void appendNote( const char* text,
|
||||||
|
const btVector3& o,
|
||||||
|
Node* feature);
|
||||||
|
void appendNote( const char* text,
|
||||||
|
const btVector3& o,
|
||||||
|
Link* feature);
|
||||||
|
void appendNote( const char* text,
|
||||||
|
const btVector3& o,
|
||||||
|
Face* feature);
|
||||||
|
void appendNote( const char* text,
|
||||||
|
const btVector3& o,
|
||||||
|
Tetra* feature);
|
||||||
|
/* Append node */
|
||||||
|
void appendNode( const btVector3& x,btScalar m);
|
||||||
/* Append link */
|
/* Append link */
|
||||||
|
void appendLink(int model=-1,Material* mat=0);
|
||||||
void appendLink( int node0,
|
void appendLink( int node0,
|
||||||
int node1,
|
int node1,
|
||||||
btScalar kST,
|
Material* mat=0,
|
||||||
btSoftBody::eLType::_ type,
|
|
||||||
bool bcheckexist=false);
|
bool bcheckexist=false);
|
||||||
void appendLink( btSoftBody::Node* node0,
|
void appendLink( btSoftBody::Node* node0,
|
||||||
btSoftBody::Node* node1,
|
btSoftBody::Node* node1,
|
||||||
btScalar kST,
|
Material* mat=0,
|
||||||
btSoftBody::eLType::_ type,
|
|
||||||
bool bcheckexist=false);
|
bool bcheckexist=false);
|
||||||
/* Append face */
|
/* Append face */
|
||||||
|
void appendFace(int model=-1,Material* mat=0);
|
||||||
void appendFace( int node0,
|
void appendFace( int node0,
|
||||||
int node1,
|
int node1,
|
||||||
int node2);
|
int node2,
|
||||||
|
Material* mat=0);
|
||||||
|
/* Append tetrahedron */
|
||||||
|
void appendTetra(int model=-1,Material* mat=0);
|
||||||
|
void appendTetra(int node0,
|
||||||
|
int node1,
|
||||||
|
int node2,
|
||||||
|
int node3,
|
||||||
|
Material* mat=0);
|
||||||
/* Append anchor */
|
/* Append anchor */
|
||||||
void appendAnchor( int node,
|
void appendAnchor( int node,
|
||||||
btRigidBody* body);
|
btRigidBody* body);
|
||||||
@@ -325,31 +438,48 @@ public:
|
|||||||
bool fromfaces=false);
|
bool fromfaces=false);
|
||||||
/* Set total density */
|
/* Set total density */
|
||||||
void setTotalDensity(btScalar density);
|
void setTotalDensity(btScalar density);
|
||||||
|
/* Set volume mass (using tetrahedrons) */
|
||||||
|
void setVolumeMass( btScalar mass);
|
||||||
|
/* Set volume density (using tetrahedrons) */
|
||||||
|
void setVolumeDensity( btScalar density);
|
||||||
/* Transform */
|
/* Transform */
|
||||||
void transform( const btTransform& trs);
|
void transform( const btTransform& trs);
|
||||||
|
/* Translate */
|
||||||
|
void translate( const btVector3& trs);
|
||||||
|
/* Rotate */
|
||||||
|
void rotate( const btQuaternion& rot);
|
||||||
/* Scale */
|
/* Scale */
|
||||||
void scale( const btVector3& scl);
|
void scale( const btVector3& scl);
|
||||||
/* Set current state as pose */
|
/* Set current state as pose */
|
||||||
void setPose( bool bvolume,
|
void setPose( bool bvolume,
|
||||||
bool bframe);
|
bool bframe);
|
||||||
/* Set current state as distance field */
|
|
||||||
void setDistanceField(int nominalresolution);
|
|
||||||
/* Return the volume */
|
/* Return the volume */
|
||||||
btScalar getVolume() const;
|
btScalar getVolume() const;
|
||||||
/* Generate bending constraints based on distance in the adjency graph */
|
/* Generate bending constraints based on distance in the adjency graph */
|
||||||
int generateBendingConstraints( int distance,
|
int generateBendingConstraints( int distance,
|
||||||
btScalar stiffness);
|
Material* mat=0);
|
||||||
|
/* Generate tetrahedral constraints */
|
||||||
|
int generateTetrahedralConstraints();
|
||||||
/* Randomize constraints to reduce solver bias */
|
/* Randomize constraints to reduce solver bias */
|
||||||
void randomizeConstraints();
|
void randomizeConstraints();
|
||||||
|
/* Refine */
|
||||||
|
void refine(ImplicitFn* ifn,btScalar accurary,bool cut);
|
||||||
|
/* CutLink */
|
||||||
|
bool cutLink(int node0,int node1,btScalar position);
|
||||||
|
bool cutLink(const Node* node0,const Node* node1,btScalar position);
|
||||||
/* Ray casting */
|
/* Ray casting */
|
||||||
bool rayCast(const btVector3& org,
|
bool rayCast(const btVector3& org,
|
||||||
const btVector3& dir,
|
const btVector3& dir,
|
||||||
sRayCast& results,
|
sRayCast& results,
|
||||||
btScalar maxtime=SIMD_INFINITY);
|
btScalar maxtime=SIMD_INFINITY);
|
||||||
|
/* Solver presets */
|
||||||
|
void setSolver(eSolverPresets::_ preset);
|
||||||
/* predictMotion */
|
/* predictMotion */
|
||||||
void predictMotion(btScalar dt);
|
void predictMotion(btScalar dt);
|
||||||
/* solveConstraints */
|
/* solveConstraints */
|
||||||
void solveConstraints();
|
void solveConstraints();
|
||||||
|
/* staticSolve */
|
||||||
|
void staticSolve(int iterations);
|
||||||
/* solveCommonConstraints */
|
/* solveCommonConstraints */
|
||||||
static void solveCommonConstraints(btSoftBody** bodies,int count,int iterations);
|
static void solveCommonConstraints(btSoftBody** bodies,int count,int iterations);
|
||||||
/* integrateMotion */
|
/* integrateMotion */
|
||||||
@@ -358,23 +488,6 @@ public:
|
|||||||
void defaultCollisionHandler(btCollisionObject* pco);
|
void defaultCollisionHandler(btCollisionObject* pco);
|
||||||
void defaultCollisionHandler(btSoftBody* psb);
|
void defaultCollisionHandler(btSoftBody* psb);
|
||||||
|
|
||||||
//
|
|
||||||
// Accessor's and cast.
|
|
||||||
//
|
|
||||||
|
|
||||||
tNodeArray& getNodes();
|
|
||||||
const tNodeArray& getNodes() const;
|
|
||||||
tLinkArray& getLinks();
|
|
||||||
const tLinkArray& getLinks() const;
|
|
||||||
tFaceArray& getFaces();
|
|
||||||
const tFaceArray& getFaces() const;
|
|
||||||
|
|
||||||
virtual void getAabb(btVector3& aabbMin,btVector3& aabbMax) const
|
|
||||||
{
|
|
||||||
aabbMin = m_bounds[0];
|
|
||||||
aabbMax = m_bounds[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Cast
|
// Cast
|
||||||
//
|
//
|
||||||
@@ -392,6 +505,13 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void getAabb(btVector3& aabbMin,btVector3& aabbMax) const
|
||||||
|
{
|
||||||
|
aabbMin = m_bounds[0];
|
||||||
|
aabbMax = m_bounds[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -71,15 +71,27 @@ if(node)
|
|||||||
if(depth>=mindepth)
|
if(depth>=mindepth)
|
||||||
{
|
{
|
||||||
const btScalar scl=(btScalar)(node->isinternal()?1:1);
|
const btScalar scl=(btScalar)(node->isinternal()?1:1);
|
||||||
const btVector3 mi=node->box.Center()-node->box.Extent()*scl;
|
const btVector3 mi=node->volume.Center()-node->volume.Extent()*scl;
|
||||||
const btVector3 mx=node->box.Center()+node->box.Extent()*scl;
|
const btVector3 mx=node->volume.Center()+node->volume.Extent()*scl;
|
||||||
drawBox(idraw,mi,mx,node->isleaf()?lcolor:ncolor);
|
drawBox(idraw,mi,mx,node->isleaf()?lcolor:ncolor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
#if 0
|
//
|
||||||
|
static inline btScalar tetravolume(const btVector3& x0,
|
||||||
|
const btVector3& x1,
|
||||||
|
const btVector3& x2,
|
||||||
|
const btVector3& x3)
|
||||||
|
{
|
||||||
|
const btVector3 a=x1-x0;
|
||||||
|
const btVector3 b=x2-x0;
|
||||||
|
const btVector3 c=x3-x0;
|
||||||
|
return(dot(a,cross(b,c)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
static btVector3 stresscolor(btScalar stress)
|
static btVector3 stresscolor(btScalar stress)
|
||||||
{
|
{
|
||||||
static const btVector3 spectrum[]= { btVector3(1,0,1),
|
static const btVector3 spectrum[]= { btVector3(1,0,1),
|
||||||
@@ -96,7 +108,6 @@ static btVector3 stresscolor(btScalar stress)
|
|||||||
const btScalar frc=stress-sel;
|
const btScalar frc=stress-sel;
|
||||||
return(spectrum[sel]+(spectrum[sel+1]-spectrum[sel])*frc);
|
return(spectrum[sel]+(spectrum[sel+1]-spectrum[sel])*frc);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
void btSoftBodyHelpers::Draw( btSoftBody* psb,
|
void btSoftBodyHelpers::Draw( btSoftBody* psb,
|
||||||
@@ -105,16 +116,16 @@ void btSoftBodyHelpers::Draw( btSoftBody* psb,
|
|||||||
{
|
{
|
||||||
const btScalar scl=(btScalar)0.1;
|
const btScalar scl=(btScalar)0.1;
|
||||||
const btScalar nscl=scl*5;
|
const btScalar nscl=scl*5;
|
||||||
const btVector3 scolor=btVector3(0,0,0);
|
const btVector3 lcolor=btVector3(0,0,0);
|
||||||
const btVector3 bcolor=btVector3(1,1,0);
|
|
||||||
const btVector3 ncolor=btVector3(1,1,1);
|
const btVector3 ncolor=btVector3(1,1,1);
|
||||||
const btVector3 ccolor=btVector3(1,0,0);
|
const btVector3 ccolor=btVector3(1,0,0);
|
||||||
/* Nodes */
|
/* Nodes */
|
||||||
if(0!=(drawflags&fDrawFlags::Nodes))
|
if(0!=(drawflags&fDrawFlags::Nodes))
|
||||||
{
|
{
|
||||||
for(int i=0;i<psb->getNodes().size();++i)
|
for(int i=0;i<psb->m_nodes.size();++i)
|
||||||
{
|
{
|
||||||
const btSoftBody::Node& n=psb->getNodes()[i];
|
const btSoftBody::Node& n=psb->m_nodes[i];
|
||||||
|
if(0==(n.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue;
|
||||||
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(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,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));
|
idraw->drawLine(n.m_x-btVector3(0,0,scl),n.m_x+btVector3(0,0,scl),btVector3(0,0,1));
|
||||||
@@ -123,24 +134,20 @@ void btSoftBodyHelpers::Draw( btSoftBody* psb,
|
|||||||
/* Links */
|
/* Links */
|
||||||
if(0!=(drawflags&fDrawFlags::Links))
|
if(0!=(drawflags&fDrawFlags::Links))
|
||||||
{
|
{
|
||||||
for(int i=0;i<psb->getLinks().size();++i)
|
for(int i=0;i<psb->m_links.size();++i)
|
||||||
{
|
{
|
||||||
const btSoftBody::Link& l=psb->getLinks()[i];
|
const btSoftBody::Link& l=psb->m_links[i];
|
||||||
switch(l.m_type)
|
if(0==(l.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue;
|
||||||
{
|
idraw->drawLine(l.m_n[0]->m_x,l.m_n[1]->m_x,lcolor);
|
||||||
case btSoftBody::eLType::Structural:
|
|
||||||
if(0!=(drawflags&fDrawFlags::SLinks)) idraw->drawLine(l.m_n[0]->m_x,l.m_n[1]->m_x,scolor);break;
|
|
||||||
case btSoftBody::eLType::Bending:
|
|
||||||
if(0!=(drawflags&fDrawFlags::BLinks)) idraw->drawLine(l.m_n[0]->m_x,l.m_n[1]->m_x,bcolor);break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Normals */
|
/* Normals */
|
||||||
if(0!=(drawflags&fDrawFlags::Normals))
|
if(0!=(drawflags&fDrawFlags::Normals))
|
||||||
{
|
{
|
||||||
for(int i=0;i<psb->getNodes().size();++i)
|
for(int i=0;i<psb->m_nodes.size();++i)
|
||||||
{
|
{
|
||||||
const btSoftBody::Node& n=psb->getNodes()[i];
|
const btSoftBody::Node& n=psb->m_nodes[i];
|
||||||
|
if(0==(n.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue;
|
||||||
const btVector3 d=n.m_n*nscl;
|
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);
|
||||||
idraw->drawLine(n.m_x,n.m_x-d,ncolor*0.5);
|
idraw->drawLine(n.m_x,n.m_x-d,ncolor*0.5);
|
||||||
@@ -175,9 +182,10 @@ void btSoftBodyHelpers::Draw( btSoftBody* psb,
|
|||||||
drawVertex(idraw,q,0.25,btVector3(0,1,0));
|
drawVertex(idraw,q,0.25,btVector3(0,1,0));
|
||||||
idraw->drawLine(a.m_node->m_x,q,btVector3(1,1,1));
|
idraw->drawLine(a.m_node->m_x,q,btVector3(1,1,1));
|
||||||
}
|
}
|
||||||
for(int i=0;i<psb->getNodes().size();++i)
|
for(int i=0;i<psb->m_nodes.size();++i)
|
||||||
{
|
{
|
||||||
const btSoftBody::Node& n=psb->getNodes()[i];
|
const btSoftBody::Node& n=psb->m_nodes[i];
|
||||||
|
if(0==(n.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue;
|
||||||
if(n.m_im<=0)
|
if(n.m_im<=0)
|
||||||
{
|
{
|
||||||
drawVertex(idraw,n.m_x,0.25,btVector3(1,0,0));
|
drawVertex(idraw,n.m_x,0.25,btVector3(1,0,0));
|
||||||
@@ -187,19 +195,59 @@ void btSoftBodyHelpers::Draw( btSoftBody* psb,
|
|||||||
/* Faces */
|
/* Faces */
|
||||||
if(0!=(drawflags&fDrawFlags::Faces))
|
if(0!=(drawflags&fDrawFlags::Faces))
|
||||||
{
|
{
|
||||||
const btScalar scl=(btScalar)0.7;
|
const btScalar scl=(btScalar)0.8;
|
||||||
const btScalar alp=(btScalar)1;
|
const btScalar alp=(btScalar)1;
|
||||||
const btVector3 col(0,(btScalar)0.7,0);
|
const btVector3 col(0,(btScalar)0.7,0);
|
||||||
for(int i=0;i<psb->getFaces().size();++i)
|
for(int i=0;i<psb->m_faces.size();++i)
|
||||||
{
|
{
|
||||||
const btSoftBody::Face& f=psb->getFaces()[i];
|
const btSoftBody::Face& f=psb->m_faces[i];
|
||||||
|
if(0==(f.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue;
|
||||||
const btVector3 x[]={f.m_n[0]->m_x,f.m_n[1]->m_x,f.m_n[2]->m_x};
|
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;
|
const btVector3 c=(x[0]+x[1]+x[2])/3;
|
||||||
|
/*idraw->drawLine((x[0]-c)*scl+c,(x[1]-c)*scl+c,col);
|
||||||
|
idraw->drawLine((x[1]-c)*scl+c,(x[2]-c)*scl+c,col);
|
||||||
|
idraw->drawLine((x[2]-c)*scl+c,(x[0]-c)*scl+c,col);*/
|
||||||
idraw->drawTriangle((x[0]-c)*scl+c,
|
idraw->drawTriangle((x[0]-c)*scl+c,
|
||||||
(x[1]-c)*scl+c,
|
(x[1]-c)*scl+c,
|
||||||
(x[2]-c)*scl+c,
|
(x[2]-c)*scl+c,
|
||||||
f.m_n[0]->m_n,f.m_n[1]->m_n,f.m_n[2]->m_n,
|
|
||||||
col,alp);
|
col,alp);
|
||||||
|
/*idraw->drawTriangle((x[0]-c)*scl+c,
|
||||||
|
(x[1]-c)*scl+c,
|
||||||
|
(x[2]-c)*scl+c,
|
||||||
|
f.m_n[0]->m_n,f.m_n[1]->m_n,f.m_n[2]->m_n,
|
||||||
|
col,alp);*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Tetras */
|
||||||
|
if(0!=(drawflags&fDrawFlags::Tetras))
|
||||||
|
{
|
||||||
|
const btScalar scl=(btScalar)0.8;
|
||||||
|
const btScalar alp=(btScalar)1;
|
||||||
|
const btVector3 col((btScalar)0.7,(btScalar)0.7,(btScalar)0.7);
|
||||||
|
for(int i=0;i<psb->m_tetras.size();++i)
|
||||||
|
{
|
||||||
|
const btSoftBody::Tetra& t=psb->m_tetras[i];
|
||||||
|
if(0==(t.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue;
|
||||||
|
const btVector3 x[]={t.m_n[0]->m_x,t.m_n[1]->m_x,t.m_n[2]->m_x,t.m_n[3]->m_x};
|
||||||
|
const btVector3 c=(x[0]+x[1]+x[2]+x[3])/4;
|
||||||
|
idraw->drawTriangle((x[0]-c)*scl+c,(x[1]-c)*scl+c,(x[2]-c)*scl+c,col,alp);
|
||||||
|
idraw->drawTriangle((x[0]-c)*scl+c,(x[1]-c)*scl+c,(x[3]-c)*scl+c,col,alp);
|
||||||
|
idraw->drawTriangle((x[1]-c)*scl+c,(x[2]-c)*scl+c,(x[3]-c)*scl+c,col,alp);
|
||||||
|
idraw->drawTriangle((x[2]-c)*scl+c,(x[0]-c)*scl+c,(x[3]-c)*scl+c,col,alp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Notes */
|
||||||
|
if(0!=(drawflags&fDrawFlags::Notes))
|
||||||
|
{
|
||||||
|
for(int i=0;i<psb->m_notes.size();++i)
|
||||||
|
{
|
||||||
|
const btSoftBody::Note& n=psb->m_notes[i];
|
||||||
|
btVector3 p=n.m_offset;
|
||||||
|
for(int j=0;j<n.m_rank;++j)
|
||||||
|
{
|
||||||
|
p+=n.m_nodes[j]->m_x*n.m_coords[j];
|
||||||
|
}
|
||||||
|
idraw->draw3dText(p,n.m_text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -211,9 +259,9 @@ void btSoftBodyHelpers::DrawInfos( btSoftBody* psb,
|
|||||||
bool areas,
|
bool areas,
|
||||||
bool /*stress*/)
|
bool /*stress*/)
|
||||||
{
|
{
|
||||||
for(int i=0;i<psb->getNodes().size();++i)
|
for(int i=0;i<psb->m_nodes.size();++i)
|
||||||
{
|
{
|
||||||
const btSoftBody::Node& n=psb->getNodes()[i];
|
const btSoftBody::Node& n=psb->m_nodes[i];
|
||||||
char text[2048]={0};
|
char text[2048]={0};
|
||||||
char buff[1024];
|
char buff[1024];
|
||||||
if(masses)
|
if(masses)
|
||||||
@@ -269,11 +317,6 @@ void btSoftBodyHelpers::DrawFrame( btSoftBody* psb,
|
|||||||
const btVector3 x=com+trs*psb->m_pose.m_pos[i];
|
const btVector3 x=com+trs*psb->m_pose.m_pos[i];
|
||||||
drawVertex(idraw,x,nscl,btVector3(1,0,1));
|
drawVertex(idraw,x,nscl,btVector3(1,0,1));
|
||||||
}
|
}
|
||||||
for(int i=0;i<psb->m_dfld.pts.size();++i)
|
|
||||||
{
|
|
||||||
const btVector3 x=com+trs*psb->m_dfld.pts[i];
|
|
||||||
drawVertex(idraw,x,nscl*(btScalar)0.5,btVector3(0,0,1));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,7 +344,7 @@ btSoftBody* btSoftBodyHelpers::CreateRope( btSoftBody::btSoftBodyWorldInfo& wor
|
|||||||
/* Create links */
|
/* Create links */
|
||||||
for(int i=1;i<r;++i)
|
for(int i=1;i<r;++i)
|
||||||
{
|
{
|
||||||
psb->appendLink(i-1,i,1,btSoftBody::eLType::Structural);
|
psb->appendLink(i-1,i);
|
||||||
}
|
}
|
||||||
/* Finished */
|
/* Finished */
|
||||||
return(psb);
|
return(psb);
|
||||||
@@ -352,10 +395,8 @@ btSoftBody* btSoftBodyHelpers::CreatePatch(btSoftBody::btSoftBodyWorldInfo& wor
|
|||||||
const int idx=IDX(ix,iy);
|
const int idx=IDX(ix,iy);
|
||||||
const bool mdx=(ix+1)<rx;
|
const bool mdx=(ix+1)<rx;
|
||||||
const bool mdy=(iy+1)<ry;
|
const bool mdy=(iy+1)<ry;
|
||||||
if(mdx) psb->appendLink(idx,IDX(ix+1,iy),
|
if(mdx) psb->appendLink(idx,IDX(ix+1,iy));
|
||||||
1,btSoftBody::eLType::Structural);
|
if(mdy) psb->appendLink(idx,IDX(ix,iy+1));
|
||||||
if(mdy) psb->appendLink(idx,IDX(ix,iy+1),
|
|
||||||
1,btSoftBody::eLType::Structural);
|
|
||||||
if(mdx&&mdy)
|
if(mdx&&mdy)
|
||||||
{
|
{
|
||||||
if((ix+iy)&1)
|
if((ix+iy)&1)
|
||||||
@@ -364,8 +405,7 @@ btSoftBody* btSoftBodyHelpers::CreatePatch(btSoftBody::btSoftBodyWorldInfo& wor
|
|||||||
psb->appendFace(IDX(ix,iy),IDX(ix+1,iy+1),IDX(ix,iy+1));
|
psb->appendFace(IDX(ix,iy),IDX(ix+1,iy+1),IDX(ix,iy+1));
|
||||||
if(gendiags)
|
if(gendiags)
|
||||||
{
|
{
|
||||||
psb->appendLink(IDX(ix,iy),IDX(ix+1,iy+1),
|
psb->appendLink(IDX(ix,iy),IDX(ix+1,iy+1));
|
||||||
1,btSoftBody::eLType::Structural);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -374,8 +414,7 @@ btSoftBody* btSoftBodyHelpers::CreatePatch(btSoftBody::btSoftBodyWorldInfo& wor
|
|||||||
psb->appendFace(IDX(ix,iy+1),IDX(ix+1,iy),IDX(ix+1,iy+1));
|
psb->appendFace(IDX(ix,iy+1),IDX(ix+1,iy),IDX(ix+1,iy+1));
|
||||||
if(gendiags)
|
if(gendiags)
|
||||||
{
|
{
|
||||||
psb->appendLink(IDX(ix+1,iy),IDX(ix,iy+1),
|
psb->appendLink(IDX(ix+1,iy),IDX(ix,iy+1));
|
||||||
1,btSoftBody::eLType::Structural);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -448,7 +487,7 @@ btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBody::btSoftBodyWorldInf
|
|||||||
{
|
{
|
||||||
chks[IDX(idx[j],idx[k])]=true;
|
chks[IDX(idx[j],idx[k])]=true;
|
||||||
chks[IDX(idx[k],idx[k])]=true;
|
chks[IDX(idx[k],idx[k])]=true;
|
||||||
psb->appendLink(idx[j],idx[k],1,btSoftBody::eLType::Structural);
|
psb->appendLink(idx[j],idx[k]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#undef IDX
|
#undef IDX
|
||||||
@@ -474,12 +513,9 @@ btSoftBody* btSoftBodyHelpers::CreateFromConvexHull(btSoftBody::btSoftBodyWorld
|
|||||||
const int idx[]={ hres.m_Indices[i*3+0],
|
const int idx[]={ hres.m_Indices[i*3+0],
|
||||||
hres.m_Indices[i*3+1],
|
hres.m_Indices[i*3+1],
|
||||||
hres.m_Indices[i*3+2]};
|
hres.m_Indices[i*3+2]};
|
||||||
if(idx[0]<idx[1]) psb->appendLink( idx[0],idx[1],
|
if(idx[0]<idx[1]) psb->appendLink( idx[0],idx[1]);
|
||||||
1,btSoftBody::eLType::Structural);
|
if(idx[1]<idx[2]) psb->appendLink( idx[1],idx[2]);
|
||||||
if(idx[1]<idx[2]) psb->appendLink( idx[1],idx[2],
|
if(idx[2]<idx[0]) psb->appendLink( idx[2],idx[0]);
|
||||||
1,btSoftBody::eLType::Structural);
|
|
||||||
if(idx[2]<idx[0]) psb->appendLink( idx[2],idx[0],
|
|
||||||
1,btSoftBody::eLType::Structural);
|
|
||||||
psb->appendFace(idx[0],idx[1],idx[2]);
|
psb->appendFace(idx[0],idx[1],idx[2]);
|
||||||
}
|
}
|
||||||
hlib.ReleaseResult(hres);
|
hlib.ReleaseResult(hres);
|
||||||
@@ -487,4 +523,154 @@ btSoftBody* btSoftBodyHelpers::CreateFromConvexHull(btSoftBody::btSoftBodyWorld
|
|||||||
return(psb);
|
return(psb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BT_SOFTBODY_USE_STL
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
void btSoftBodyHelpers::ExportAsSMeshFile(btSoftBody* psb,
|
||||||
|
const char* filename)
|
||||||
|
{
|
||||||
|
std::ofstream output(filename);
|
||||||
|
output << psb->m_nodes.size() << " " << 3 << " " << 0 << " " << 0 << "\n";
|
||||||
|
for(int i=0;i<psb->m_nodes.size();++i)
|
||||||
|
{
|
||||||
|
const btSoftBody::Node& n=psb->m_nodes[i];
|
||||||
|
output << i << " "
|
||||||
|
<< n.m_x.x() << " "
|
||||||
|
<< n.m_x.y() << " "
|
||||||
|
<< n.m_x.z() << "\n";
|
||||||
|
}
|
||||||
|
output << psb->m_faces.size() << " " << 1 << "\n";
|
||||||
|
for(int i=0;i<psb->m_faces.size();++i)
|
||||||
|
{
|
||||||
|
const btSoftBody::Node* b=&psb->m_nodes[0];
|
||||||
|
const btSoftBody::Face& f=psb->m_faces[i];
|
||||||
|
output << 3 << " "
|
||||||
|
<< int(f.m_n[0]-b) << " "
|
||||||
|
<< int(f.m_n[1]-b) << " "
|
||||||
|
<< int(f.m_n[2]-b) << " "
|
||||||
|
<< 1 << "\n";
|
||||||
|
}
|
||||||
|
output << 0 << "\n";
|
||||||
|
output << 0 << "\n";
|
||||||
|
output.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create from TetGen .ele, .face, .node files */
|
||||||
|
btSoftBody* btSoftBodyHelpers::CreateFromTetGenFile(btSoftBody::btSoftBodyWorldInfo& worldInfo,
|
||||||
|
const char* ele,
|
||||||
|
const char* face,
|
||||||
|
const char* node,
|
||||||
|
bool bfacelinks,
|
||||||
|
bool btetralinks,
|
||||||
|
bool bfacesfromtetras)
|
||||||
|
{
|
||||||
|
std::ifstream efile(ele?ele:"");
|
||||||
|
std::ifstream ffile(face?face:"");
|
||||||
|
std::ifstream nfile(node);
|
||||||
|
std::string edata;
|
||||||
|
std::string fdata;
|
||||||
|
std::string ndata;
|
||||||
|
if(efile.good()) while(!efile.eof()) edata+=efile.get();
|
||||||
|
if(ffile.good()) while(!ffile.eof()) fdata+=ffile.get();
|
||||||
|
if(nfile.good()) while(!nfile.eof()) ndata+=nfile.get();
|
||||||
|
efile.close();
|
||||||
|
ffile.close();
|
||||||
|
nfile.close();
|
||||||
|
return(CreateFromTetGenData(worldInfo,edata.c_str(),fdata.c_str(),ndata.c_str(),
|
||||||
|
bfacelinks,btetralinks,bfacesfromtetras));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create from TetGen .ele, .face, .node data */
|
||||||
|
btSoftBody* btSoftBodyHelpers::CreateFromTetGenData(btSoftBody::btSoftBodyWorldInfo& worldInfo,
|
||||||
|
const char* ele,
|
||||||
|
const char* face,
|
||||||
|
const char* node,
|
||||||
|
bool bfacelinks,
|
||||||
|
bool btetralinks,
|
||||||
|
bool bfacesfromtetras)
|
||||||
|
{
|
||||||
|
std::istringstream se(ele?ele:"");
|
||||||
|
std::istringstream sf(face?face:"");
|
||||||
|
std::istringstream sn(node?node:"");
|
||||||
|
btAlignedObjectArray<btVector3> pos;
|
||||||
|
int nnode=0;
|
||||||
|
int ndims=0;
|
||||||
|
int nattrb=0;
|
||||||
|
int hasbounds=0;
|
||||||
|
sn>>nnode;sn>>ndims;sn>>nattrb;sn>>hasbounds;
|
||||||
|
pos.resize(nnode);
|
||||||
|
for(int i=0;i<pos.size();++i)
|
||||||
|
{
|
||||||
|
int index=0;
|
||||||
|
int bound=0;
|
||||||
|
btScalar x,y,z,a;
|
||||||
|
sn>>index;
|
||||||
|
sn>>x;sn>>y;sn>>z;
|
||||||
|
for(int j=0;j<nattrb;++j) sn>>a;
|
||||||
|
if(hasbounds) sn>>bound;
|
||||||
|
pos[index].setX(x);
|
||||||
|
pos[index].setY(y);
|
||||||
|
pos[index].setZ(z);
|
||||||
|
}
|
||||||
|
btSoftBody* psb=new btSoftBody(&worldInfo,nnode,&pos[0],0);
|
||||||
|
if(face&&face[0])
|
||||||
|
{
|
||||||
|
int nface=0;
|
||||||
|
sf>>nface;sf>>hasbounds;
|
||||||
|
for(int i=0;i<nface;++i)
|
||||||
|
{
|
||||||
|
int index=0;
|
||||||
|
int bound=0;
|
||||||
|
int ni[3];
|
||||||
|
sf>>index;
|
||||||
|
sf>>ni[0];sf>>ni[1];sf>>ni[2];
|
||||||
|
sf>>bound;
|
||||||
|
psb->appendFace(ni[0],ni[1],ni[2]);
|
||||||
|
if(btetralinks)
|
||||||
|
{
|
||||||
|
psb->appendLink(ni[0],ni[1],0,true);
|
||||||
|
psb->appendLink(ni[1],ni[2],0,true);
|
||||||
|
psb->appendLink(ni[2],ni[0],0,true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(ele&&ele[0])
|
||||||
|
{
|
||||||
|
int ntetra=0;
|
||||||
|
int ncorner=0;
|
||||||
|
int neattrb=0;
|
||||||
|
se>>ntetra;se>>ncorner;se>>neattrb;
|
||||||
|
for(int i=0;i<ntetra;++i)
|
||||||
|
{
|
||||||
|
int index=0;
|
||||||
|
int ni[4],a;
|
||||||
|
se>>index;
|
||||||
|
se>>ni[0];se>>ni[1];se>>ni[2];se>>ni[3];
|
||||||
|
for(int j=0;j<neattrb;++j) se>>a;
|
||||||
|
psb->appendTetra(ni[0],ni[1],ni[2],ni[3]);
|
||||||
|
if(btetralinks)
|
||||||
|
{
|
||||||
|
psb->appendLink(ni[0],ni[1],0,true);
|
||||||
|
psb->appendLink(ni[1],ni[2],0,true);
|
||||||
|
psb->appendLink(ni[2],ni[0],0,true);
|
||||||
|
psb->appendLink(ni[0],ni[3],0,true);
|
||||||
|
psb->appendLink(ni[1],ni[3],0,true);
|
||||||
|
psb->appendLink(ni[2],ni[3],0,true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("Nodes: %u\r\n",psb->m_nodes.size());
|
||||||
|
printf("Links: %u\r\n",psb->m_links.size());
|
||||||
|
printf("Faces: %u\r\n",psb->m_faces.size());
|
||||||
|
printf("Tetras: %u\r\n",psb->m_tetras.size());
|
||||||
|
return(psb);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ subject to the following restrictions:
|
|||||||
|
|
||||||
#include "btSoftBody.h"
|
#include "btSoftBody.h"
|
||||||
|
|
||||||
|
//Can't enable this, Bullet doesn't use STL
|
||||||
|
//#define BT_SOFTBODY_USE_STL 1
|
||||||
|
|
||||||
//
|
//
|
||||||
// Helpers
|
// Helpers
|
||||||
//
|
//
|
||||||
@@ -25,16 +28,15 @@ subject to the following restrictions:
|
|||||||
/* fDrawFlags */
|
/* fDrawFlags */
|
||||||
struct fDrawFlags { enum _ {
|
struct fDrawFlags { enum _ {
|
||||||
Nodes = 0x0001,
|
Nodes = 0x0001,
|
||||||
SLinks = 0x0002,
|
Links = 0x0002,
|
||||||
BLinks = 0x0004,
|
Faces = 0x0004,
|
||||||
Faces = 0x0008,
|
Tetras = 0x0008,
|
||||||
Tetras = 0x0010,
|
Normals = 0x0010,
|
||||||
Normals = 0x0020,
|
Contacts = 0x0020,
|
||||||
Contacts = 0x0040,
|
Anchors = 0x0040,
|
||||||
Anchors = 0x0080,
|
Notes = 0x0080,
|
||||||
/* presets */
|
/* presets */
|
||||||
Links = SLinks+BLinks,
|
Std = Links+Faces+Tetras+Anchors+Notes,
|
||||||
Std = SLinks+Faces+Anchors,
|
|
||||||
StdTetra = Std-Faces+Tetras,
|
StdTetra = Std-Faces+Tetras,
|
||||||
};};
|
};};
|
||||||
|
|
||||||
@@ -64,12 +66,14 @@ struct btSoftBodyHelpers
|
|||||||
static void DrawFrame( btSoftBody* psb,
|
static void DrawFrame( btSoftBody* psb,
|
||||||
btIDebugDraw* idraw);
|
btIDebugDraw* idraw);
|
||||||
/* Create a rope */
|
/* Create a rope */
|
||||||
static btSoftBody* CreateRope( btSoftBody::btSoftBodyWorldInfo& worldInfo,const btVector3& from,
|
static btSoftBody* CreateRope( btSoftBody::btSoftBodyWorldInfo& worldInfo,
|
||||||
|
const btVector3& from,
|
||||||
const btVector3& to,
|
const btVector3& to,
|
||||||
int res,
|
int res,
|
||||||
int fixeds);
|
int fixeds);
|
||||||
/* Create a patch */
|
/* Create a patch */
|
||||||
static btSoftBody* CreatePatch( btSoftBody::btSoftBodyWorldInfo& worldInfo,const btVector3& corner00,
|
static btSoftBody* CreatePatch(btSoftBody::btSoftBodyWorldInfo& worldInfo,
|
||||||
|
const btVector3& corner00,
|
||||||
const btVector3& corner10,
|
const btVector3& corner10,
|
||||||
const btVector3& corner01,
|
const btVector3& corner01,
|
||||||
const btVector3& corner11,
|
const btVector3& corner11,
|
||||||
@@ -78,16 +82,40 @@ struct btSoftBodyHelpers
|
|||||||
int fixeds,
|
int fixeds,
|
||||||
bool gendiags);
|
bool gendiags);
|
||||||
/* Create an ellipsoid */
|
/* Create an ellipsoid */
|
||||||
static btSoftBody* CreateEllipsoid(btSoftBody::btSoftBodyWorldInfo& worldInfo,const btVector3& center,
|
static btSoftBody* CreateEllipsoid(btSoftBody::btSoftBodyWorldInfo& worldInfo,
|
||||||
|
const btVector3& center,
|
||||||
const btVector3& radius,
|
const btVector3& radius,
|
||||||
int res);
|
int res);
|
||||||
/* Create from convex-hull */
|
|
||||||
static btSoftBody* CreateFromConvexHull( btSoftBody::btSoftBodyWorldInfo& worldInfo, const btVector3* vertices,
|
|
||||||
int nvertices);
|
|
||||||
/* Create from trimesh */
|
/* Create from trimesh */
|
||||||
static btSoftBody* CreateFromTriMesh( btSoftBody::btSoftBodyWorldInfo& worldInfo, const btScalar* vertices,
|
static btSoftBody* CreateFromTriMesh( btSoftBody::btSoftBodyWorldInfo& worldInfo,
|
||||||
|
const btScalar* vertices,
|
||||||
const int* triangles,
|
const int* triangles,
|
||||||
int ntriangles);
|
int ntriangles);
|
||||||
|
/* Create from convex-hull */
|
||||||
|
static btSoftBody* CreateFromConvexHull( btSoftBody::btSoftBodyWorldInfo& worldInfo,
|
||||||
|
const btVector3* vertices,
|
||||||
|
int nvertices);
|
||||||
|
#if BT_SOFTBODY_USE_STL
|
||||||
|
/* Export TetGen compatible .smesh file */
|
||||||
|
static void ExportAsSMeshFile( btSoftBody* psb,
|
||||||
|
const char* filename);
|
||||||
|
/* Create from TetGen .ele, .face, .node files */
|
||||||
|
static btSoftBody* CreateFromTetGenFile( btSoftBody::btSoftBodyWorldInfo& worldInfo,
|
||||||
|
const char* ele,
|
||||||
|
const char* face,
|
||||||
|
const char* node,
|
||||||
|
bool bfacelinks,
|
||||||
|
bool btetralinks,
|
||||||
|
bool bfacesfromtetras);
|
||||||
|
/* Create from TetGen .ele, .face, .node data */
|
||||||
|
static btSoftBody* CreateFromTetGenData( btSoftBody::btSoftBodyWorldInfo& worldInfo,
|
||||||
|
const char* ele,
|
||||||
|
const char* face,
|
||||||
|
const char* node,
|
||||||
|
bool bfacelinks,
|
||||||
|
bool btetralinks,
|
||||||
|
bool bfacesfromtetras);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //SOFT_BODY_HELPERS_H
|
#endif //SOFT_BODY_HELPERS_H
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ void btSoftRigidDynamicsWorld::debugDrawWorld()
|
|||||||
{
|
{
|
||||||
btSoftBody* psb=(btSoftBody*)this->m_softBodies[i];
|
btSoftBody* psb=(btSoftBody*)this->m_softBodies[i];
|
||||||
btSoftBodyHelpers::DrawFrame(psb,m_debugDrawer);
|
btSoftBodyHelpers::DrawFrame(psb,m_debugDrawer);
|
||||||
btSoftBodyHelpers::Draw(psb,m_debugDrawer,fDrawFlags::Std);
|
btSoftBodyHelpers::Draw(psb,m_debugDrawer,fDrawFlags::Nodes+fDrawFlags::Std);
|
||||||
if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
|
if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
|
||||||
{
|
{
|
||||||
btSoftBodyHelpers::DrawNodeTree(psb,m_debugDrawer);
|
btSoftBodyHelpers::DrawNodeTree(psb,m_debugDrawer);
|
||||||
|
|||||||
@@ -109,6 +109,28 @@ struct btSparseSdf
|
|||||||
/* else setup a priority list... */
|
/* else setup a priority list... */
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
int RemoveReferences(btCollisionShape* pcs)
|
||||||
|
{
|
||||||
|
int refcount=0;
|
||||||
|
for(int i=0;i<cells.size();++i)
|
||||||
|
{
|
||||||
|
Cell*& root=cells[i];
|
||||||
|
Cell* pp=0;
|
||||||
|
Cell* pc=root;
|
||||||
|
while(pc)
|
||||||
|
{
|
||||||
|
Cell* pn=pc->next;
|
||||||
|
if(pc->pclient==pcs)
|
||||||
|
{
|
||||||
|
if(pp) pp->next=pn; else root=pn;
|
||||||
|
delete pc;pc=pp;++refcount;
|
||||||
|
}
|
||||||
|
pp=pc;pc=pn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(refcount);
|
||||||
|
}
|
||||||
|
//
|
||||||
btScalar Evaluate( const btVector3& x,
|
btScalar Evaluate( const btVector3& x,
|
||||||
btCollisionShape* shape,
|
btCollisionShape* shape,
|
||||||
btVector3& normal,
|
btVector3& normal,
|
||||||
|
|||||||
Reference in New Issue
Block a user