Some changes in rendering, to get shadows for trimeshes

Add dynamic aabb tree (btDbvt) optimization for btCompoundShape/btCompoundCollisionAlgorithm
Add btTransformAabb util, todo: deploy it throughout the codebase
This commit is contained in:
erwin.coumans
2008-09-10 05:20:04 +00:00
parent aad1d574ef
commit 93d1d24234
10 changed files with 773 additions and 572 deletions

View File

@@ -45,7 +45,7 @@ subject to the following restrictions:
#include "GlutStuff.h" #include "GlutStuff.h"
btVector3 centroid; btVector3 centroid=btVector3(0,0,0);
btVector3 convexDecompositionObjectOffset(10,0,0); btVector3 convexDecompositionObjectOffset(10,0,0);
#define CUBE_HALF_EXTENTS 4 #define CUBE_HALF_EXTENTS 4
@@ -100,6 +100,7 @@ void ConvexDecompositionDemo::initPhysics(const char* filename)
#endif//USE_PARALLEL_DISPATCHER #endif//USE_PARALLEL_DISPATCHER
convexDecompositionObjectOffset.setValue(10,0,0);
btVector3 worldAabbMin(-10000,-10000,-10000); btVector3 worldAabbMin(-10000,-10000,-10000);
btVector3 worldAabbMax(10000,10000,10000); btVector3 worldAabbMax(10000,10000,10000);
@@ -124,10 +125,13 @@ void ConvexDecompositionDemo::initPhysics(const char* filename)
class MyConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface class MyConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface
{ {
ConvexDecompositionDemo* m_convexDemo; ConvexDecompositionDemo* m_convexDemo;
public: public:
btAlignedObjectArray<btConvexHullShape*> m_convexShapes;
btAlignedObjectArray<btVector3> m_convexCentroids;
MyConvexDecomposition (FILE* outputFile,ConvexDecompositionDemo* demo) MyConvexDecomposition (FILE* outputFile,ConvexDecompositionDemo* demo)
:m_convexDemo(demo), :m_convexDemo(demo),
mBaseCount(0), mBaseCount(0),
@@ -162,6 +166,7 @@ void ConvexDecompositionDemo::initPhysics(const char* filename)
//calc centroid, to shift vertices around center of mass //calc centroid, to shift vertices around center of mass
centroid.setValue(0,0,0); centroid.setValue(0,0,0);
btAlignedObjectArray<btVector3> vertices; btAlignedObjectArray<btVector3> vertices;
if ( 1 ) if ( 1 )
{ {
@@ -245,29 +250,17 @@ void ConvexDecompositionDemo::initPhysics(const char* filename)
btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,shiftedVertices); btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,shiftedVertices);
btCollisionShape* convexShape = new btConvexHullShape(&(shiftedVertices[0].getX()),shiftedVertices.size()); btConvexHullShape* convexShape = new btConvexHullShape(&(shiftedVertices[0].getX()),shiftedVertices.size());
#else //SHRINK_OBJECT_INWARDS #else //SHRINK_OBJECT_INWARDS
#ifdef USE_PARALLEL_DISPATCHER btConvexHullShape* convexShape = new btConvexHullShape(&(vertices[0].getX()),vertices.size());
//SPU/multi threaded version only supports convex hull with contiguous vertices at the moment
btCollisionShape* convexShape = new btConvexHullShape(&(vertices[0].getX()),vertices.size());
#else
btCollisionShape* convexShape = new btConvexTriangleMeshShape(trimesh);
#endif //USE_PARALLEL_DISPATCHER
#endif #endif
convexShape->setMargin(0.01); convexShape->setMargin(0.01);
m_convexShapes.push_back(convexShape);
m_convexCentroids.push_back(centroid);
m_convexDemo->m_collisionShapes.push_back(convexShape); m_convexDemo->m_collisionShapes.push_back(convexShape);
btTransform trans;
trans.setIdentity();
trans.setOrigin(centroid-convexDecompositionObjectOffset);
//btRigidBody* body = m_convexDemo->localCreateRigidBody( mass, trans,convexShape);
m_convexDemo->localCreateRigidBody( mass, trans,convexShape);
mBaseCount+=result.mHullVcount; // advance the 'base index' counter. mBaseCount+=result.mHullVcount; // advance the 'base index' counter.
@@ -394,6 +387,34 @@ void ConvexDecompositionDemo::initPhysics(const char* filename)
ConvexBuilder cb(desc.mCallback); ConvexBuilder cb(desc.mCallback);
cb.process(desc); cb.process(desc);
//now create some bodies
{
btCompoundShape* compound = new btCompoundShape();
m_collisionShapes.push_back (compound);
btTransform trans;
trans.setIdentity();
for (int i=0;i<convexDecomposition.m_convexShapes.size();i++)
{
btVector3 centroid = convexDecomposition.m_convexCentroids[i];
trans.setOrigin(centroid);
btConvexHullShape* convexShape = convexDecomposition.m_convexShapes[i];
compound->addChildShape(trans,convexShape);
}
btScalar mass=10.f;
trans.setOrigin(-convexDecompositionObjectOffset);
localCreateRigidBody( mass, trans,compound);
convexDecompositionObjectOffset.setZ(6);
trans.setOrigin(-convexDecompositionObjectOffset);
localCreateRigidBody( mass, trans,compound);
convexDecompositionObjectOffset.setZ(-6);
trans.setOrigin(-convexDecompositionObjectOffset);
localCreateRigidBody( mass, trans,compound);
}
if (outputFile) if (outputFile)
fclose(outputFile); fclose(outputFile);

View File

@@ -51,29 +51,29 @@ extern int gTotalBytesAlignedAllocs;
DemoApplication::DemoApplication() DemoApplication::DemoApplication()
//see btIDebugDraw.h for modes //see btIDebugDraw.h for modes
: :
m_dynamicsWorld(0), m_dynamicsWorld(0),
m_pickConstraint(0), m_pickConstraint(0),
m_shootBoxShape(0), m_shootBoxShape(0),
m_cameraDistance(15.0), m_cameraDistance(15.0),
m_debugMode(0), m_debugMode(0),
m_ele(20.f), m_ele(20.f),
m_azi(0.f), m_azi(0.f),
m_cameraPosition(0.f,0.f,0.f), m_cameraPosition(0.f,0.f,0.f),
m_cameraTargetPosition(0.f,0.f,0.f), m_cameraTargetPosition(0.f,0.f,0.f),
m_scaleBottom(0.5f), m_scaleBottom(0.5f),
m_scaleFactor(2.f), m_scaleFactor(2.f),
m_cameraUp(0,1,0), m_cameraUp(0,1,0),
m_forwardAxis(2), m_forwardAxis(2),
m_glutScreenWidth(0), m_glutScreenWidth(0),
m_glutScreenHeight(0), m_glutScreenHeight(0),
m_ShootBoxInitialSpeed(40.f), m_ShootBoxInitialSpeed(40.f),
m_stepping(true), m_stepping(true),
m_singleStep(false), m_singleStep(false),
m_idle(false), m_idle(false),
m_enableshadows(false), m_enableshadows(false),
m_sundirection(btVector3(1,-2,1)*1000) m_sundirection(btVector3(1,-2,1)*1000)
{ {
#ifndef BT_NO_PROFILE #ifndef BT_NO_PROFILE
m_profileIterator = CProfileManager::Get_Iterator(); m_profileIterator = CProfileManager::Get_Iterator();
@@ -379,7 +379,7 @@ void DemoApplication::keyboardCallback(unsigned char key, int x, int y)
break; break;
} }
case 's' : clientMoveAndDisplay(); break; case 's' : clientMoveAndDisplay(); break;
// case ' ' : newRandom(); break; // case ' ' : newRandom(); break;
case ' ': case ' ':
clientResetScene(); clientResetScene();
break; break;
@@ -410,7 +410,7 @@ void DemoApplication::keyboardCallback(unsigned char key, int x, int y)
} }
default: default:
// std::cout << "unused key : " << key << std::endl; // std::cout << "unused key : " << key << std::endl;
break; break;
} }
@@ -483,7 +483,7 @@ void DemoApplication::specialKeyboard(int key, int x, int y)
case GLUT_KEY_PAGE_DOWN : zoomOut(); break; case GLUT_KEY_PAGE_DOWN : zoomOut(); break;
case GLUT_KEY_HOME : toggleIdle(); break; case GLUT_KEY_HOME : toggleIdle(); break;
default: default:
// std::cout << "unused (special) key : " << key << std::endl; // std::cout << "unused (special) key : " << key << std::endl;
break; break;
} }
@@ -916,11 +916,11 @@ void DemoApplication::showProfileInfo(float& xOffset,float& yStart, float yIncr)
// //
void DemoApplication::renderscene(int pass) void DemoApplication::renderscene(int pass)
{ {
btScalar m[16]; btScalar m[16];
btMatrix3x3 rot;rot.setIdentity(); btMatrix3x3 rot;rot.setIdentity();
const int numObjects=m_dynamicsWorld->getNumCollisionObjects(); const int numObjects=m_dynamicsWorld->getNumCollisionObjects();
btVector3 wireColor(1,0,0); btVector3 wireColor(1,0,0);
for(int i=0;i<numObjects;i++) for(int i=0;i<numObjects;i++)
{ {
btCollisionObject* colObj=m_dynamicsWorld->getCollisionObjectArray()[i]; btCollisionObject* colObj=m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body=btRigidBody::upcast(colObj); btRigidBody* body=btRigidBody::upcast(colObj);
@@ -964,6 +964,13 @@ for(int i=0;i<numObjects;i++)
btVector3 aabbMin,aabbMax; btVector3 aabbMin,aabbMax;
m_dynamicsWorld->getBroadphase()->getBroadphaseAabb(aabbMin,aabbMax); m_dynamicsWorld->getBroadphase()->getBroadphaseAabb(aabbMin,aabbMax);
aabbMin-=btVector3(1e30,1e30,1e30);
aabbMax+=btVector3(1e30,1e30,1e30);
// printf("aabbMin=(%f,%f,%f)\n",aabbMin.getX(),aabbMin.getY(),aabbMin.getZ());
// printf("aabbMax=(%f,%f,%f)\n",aabbMax.getX(),aabbMax.getY(),aabbMax.getZ());
// m_dynamicsWorld->getDebugDrawer()->drawAabb(aabbMin,aabbMax,btVector3(1,1,1));
switch(pass) switch(pass)
{ {
case 0: m_shapeDrawer.drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode(),aabbMin,aabbMax);break; case 0: m_shapeDrawer.drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode(),aabbMin,aabbMax);break;
@@ -1026,6 +1033,7 @@ void DemoApplication::renderme()
} }
else else
{ {
glDisable(GL_CULL_FACE);
renderscene(0); renderscene(0);
} }
@@ -1043,7 +1051,7 @@ void DemoApplication::renderme()
showProfileInfo(xOffset,yStart,yIncr); showProfileInfo(xOffset,yStart,yIncr);
#ifdef USE_QUICKPROF #ifdef USE_QUICKPROF
if ( getDebugMode() & btIDebugDraw::DBG_ProfileTimings) if ( getDebugMode() & btIDebugDraw::DBG_ProfileTimings)
@@ -1062,7 +1070,7 @@ void DemoApplication::renderme()
} }
} }
#endif //USE_QUICKPROF #endif //USE_QUICKPROF
glRasterPos3f(xOffset,yStart,0); glRasterPos3f(xOffset,yStart,0);
@@ -1167,7 +1175,7 @@ void DemoApplication::renderme()
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
yStart += yIncr; yStart += yIncr;
//enable BT_DEBUG_MEMORY_ALLOCATIONS define in Bullet/src/LinearMath/btAlignedAllocator.h for memory leak detection //enable BT_DEBUG_MEMORY_ALLOCATIONS define in Bullet/src/LinearMath/btAlignedAllocator.h for memory leak detection
#ifdef BT_DEBUG_MEMORY_ALLOCATIONS #ifdef BT_DEBUG_MEMORY_ALLOCATIONS
glRasterPos3f(xOffset,yStart,0); glRasterPos3f(xOffset,yStart,0);
sprintf(buf,"gTotalBytesAlignedAllocs = %d",gTotalBytesAlignedAllocs); sprintf(buf,"gTotalBytesAlignedAllocs = %d",gTotalBytesAlignedAllocs);

View File

@@ -166,7 +166,7 @@ void OGL_displaylist_register_shape(btCollisionShape * shape)
glNewList(dlist.m_dlist,GL_COMPILE); glNewList(dlist.m_dlist,GL_COMPILE);
glEnable(GL_CULL_FACE); // glEnable(GL_CULL_FACE);
glCullFace(GL_BACK); glCullFace(GL_BACK);
@@ -177,7 +177,7 @@ void OGL_displaylist_register_shape(btCollisionShape * shape)
concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax); concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);
} }
glDisable(GL_CULL_FACE); // glDisable(GL_CULL_FACE);
glEndList(); glEndList();
} }
@@ -237,12 +237,16 @@ public:
} else } else
{ {
glBegin(GL_TRIANGLES); glBegin(GL_TRIANGLES);
glColor3f(1, 1, 1); //glColor3f(1, 1, 1);
glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ()); glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
//glColor3f(0, 1, 0);
glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ()); glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
//glColor3f(0, 0, 1);
glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ()); glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
glEnd(); glEnd();
} }
} }

View File

@@ -16,12 +16,17 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h" #include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h" #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btCompoundShape.h" #include "BulletCollision/CollisionShapes/btCompoundShape.h"
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
#include "LinearMath/btIDebugDraw.h"
#include "LinearMath/btAabbUtil2.h"
btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped) btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
:btCollisionAlgorithm(ci), :btCollisionAlgorithm(ci),
m_isSwapped(isSwapped) m_isSwapped(isSwapped),
m_sharedManifold(ci.m_manifold)
{ {
m_ownsManifold = false;
btCollisionObject* colObj = m_isSwapped? body1 : body0; btCollisionObject* colObj = m_isSwapped? body1 : body0;
btCollisionObject* otherObj = m_isSwapped? body0 : body1; btCollisionObject* otherObj = m_isSwapped? body0 : body1;
assert (colObj->getCollisionShape()->isCompound()); assert (colObj->getCollisionShape()->isCompound());
@@ -32,13 +37,19 @@ m_isSwapped(isSwapped)
m_childCollisionAlgorithms.resize(numChildren); m_childCollisionAlgorithms.resize(numChildren);
for (i=0;i<numChildren;i++) for (i=0;i<numChildren;i++)
{
if (compoundShape->getDynamicAabbTree())
{
m_childCollisionAlgorithms[i] = 0;
} else
{ {
btCollisionShape* tmpShape = colObj->getCollisionShape(); btCollisionShape* tmpShape = colObj->getCollisionShape();
btCollisionShape* childShape = compoundShape->getChildShape(i); btCollisionShape* childShape = compoundShape->getChildShape(i);
colObj->internalSetTemporaryCollisionShape( childShape ); colObj->internalSetTemporaryCollisionShape( childShape );
m_childCollisionAlgorithms[i] = ci.m_dispatcher1->findAlgorithm(colObj,otherObj); m_childCollisionAlgorithms[i] = ci.m_dispatcher1->findAlgorithm(colObj,otherObj,m_sharedManifold);
colObj->internalSetTemporaryCollisionShape( tmpShape ); colObj->internalSetTemporaryCollisionShape( tmpShape );
} }
}
} }
@@ -47,12 +58,110 @@ btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm()
int numChildren = m_childCollisionAlgorithms.size(); int numChildren = m_childCollisionAlgorithms.size();
int i; int i;
for (i=0;i<numChildren;i++) for (i=0;i<numChildren;i++)
{
if (m_childCollisionAlgorithms[i])
{ {
m_childCollisionAlgorithms[i]->~btCollisionAlgorithm(); m_childCollisionAlgorithms[i]->~btCollisionAlgorithm();
m_dispatcher->freeCollisionAlgorithm(m_childCollisionAlgorithms[i]); m_dispatcher->freeCollisionAlgorithm(m_childCollisionAlgorithms[i]);
} }
}
} }
struct btCompoundLeafCallback : btDbvt::ICollide
{
public:
btCollisionObject* m_compoundColObj;
btCollisionObject* m_otherObj;
btDispatcher* m_dispatcher;
const btDispatcherInfo& m_dispatchInfo;
btManifoldResult* m_resultOut;
btCollisionAlgorithm** m_childCollisionAlgorithms;
btPersistentManifold* m_sharedManifold;
btCompoundLeafCallback (btCollisionObject* compoundObj,btCollisionObject* otherObj,btDispatcher* dispatcher,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut,btCollisionAlgorithm** childCollisionAlgorithms,btPersistentManifold* sharedManifold)
:m_compoundColObj(compoundObj),m_otherObj(otherObj),m_dispatcher(dispatcher),m_dispatchInfo(dispatchInfo),m_resultOut(resultOut),
m_childCollisionAlgorithms(childCollisionAlgorithms),
m_sharedManifold(sharedManifold)
{
}
void ProcessChildShape(btCollisionShape* childShape,int index)
{
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(m_compoundColObj->getCollisionShape());
//backup
btTransform orgTrans = m_compoundColObj->getWorldTransform();
btTransform orgInterpolationTrans = m_compoundColObj->getInterpolationWorldTransform();
const btTransform& childTrans = compoundShape->getChildTransform(index);
btTransform newChildWorldTrans = orgTrans*childTrans ;
//perform an AABB check first
btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0);
m_otherObj->getCollisionShape()->getAabb(m_otherObj->getWorldTransform(),aabbMin1,aabbMax1);
if (TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
{
m_compoundColObj->setWorldTransform( newChildWorldTrans);
m_compoundColObj->setInterpolationWorldTransform(newChildWorldTrans);
//the contactpoint is still projected back using the original inverted worldtrans
btCollisionShape* tmpShape = m_compoundColObj->getCollisionShape();
m_compoundColObj->internalSetTemporaryCollisionShape( childShape );
if (!m_childCollisionAlgorithms[index])
m_childCollisionAlgorithms[index] = m_dispatcher->findAlgorithm(m_compoundColObj,m_otherObj,m_sharedManifold);
m_childCollisionAlgorithms[index]->processCollision(m_compoundColObj,m_otherObj,m_dispatchInfo,m_resultOut);
if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
{
btVector3 worldAabbMin,worldAabbMax;
m_dispatchInfo.m_debugDraw->drawAabb(aabbMin0,aabbMax0,btVector3(1,1,1));
m_dispatchInfo.m_debugDraw->drawAabb(aabbMin1,aabbMax1,btVector3(1,1,1));
}
//revert back transform
m_compoundColObj->internalSetTemporaryCollisionShape( tmpShape);
m_compoundColObj->setWorldTransform( orgTrans );
m_compoundColObj->setInterpolationWorldTransform(orgInterpolationTrans);
}
}
void Process(const btDbvtNode* leaf)
{
int index = int(leaf->data);
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(m_compoundColObj->getCollisionShape());
btCollisionShape* childShape = compoundShape->getChildShape(index);
if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
{
btVector3 worldAabbMin,worldAabbMax;
btTransform orgTrans = m_compoundColObj->getWorldTransform();
btTransformAabb(leaf->volume.Mins(),leaf->volume.Maxs(),0.,orgTrans,worldAabbMin,worldAabbMax);
m_dispatchInfo.m_debugDraw->drawAabb(worldAabbMin,worldAabbMax,btVector3(1,0,0));
}
ProcessChildShape(childShape,index);
}
};
void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
btCollisionObject* colObj = m_isSwapped? body1 : body0; btCollisionObject* colObj = m_isSwapped? body1 : body0;
@@ -61,37 +170,69 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
assert (colObj->getCollisionShape()->isCompound()); assert (colObj->getCollisionShape()->isCompound());
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape()); btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
//We will use the OptimizedBVH, AABB tree to cull potential child-overlaps btDbvt* tree = compoundShape->getDynamicAabbTree();
//If both proxies are Compound, we will deal with that directly, by performing sequential/parallel tree traversals //use a dynamic aabb tree to cull potential child-overlaps
//given Proxy0 and Proxy1, if both have a tree, Tree0 and Tree1, this means: btCompoundLeafCallback callback(colObj,otherObj,m_dispatcher,dispatchInfo,resultOut,&m_childCollisionAlgorithms[0],m_sharedManifold);
//determine overlapping nodes of Proxy1 using Proxy0 AABB against Tree1
//then use each overlapping node AABB against Tree0
//and vise versa.
if (tree)
{
btVector3 localAabbMin,localAabbMax;
btTransform otherInCompoundSpace;
otherInCompoundSpace = colObj->getWorldTransform().inverse() * otherObj->getWorldTransform();
otherObj->getCollisionShape()->getAabb(otherInCompoundSpace,localAabbMin,localAabbMax);
const btDbvtVolume bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
//process all children, that overlap with the given AABB bounds
tree->collideTV(tree->m_root,bounds,callback);
} else
{
//iterate over all children, perform an AABB check inside ProcessChildShape
int numChildren = m_childCollisionAlgorithms.size(); int numChildren = m_childCollisionAlgorithms.size();
int i; int i;
for (i=0;i<numChildren;i++) for (i=0;i<numChildren;i++)
{ {
//temporarily exchange parent btCollisionShape with childShape, and recurse callback.ProcessChildShape(compoundShape->getChildShape(i),i);
btCollisionShape* childShape = compoundShape->getChildShape(i); }
}
//backup {
//iterate over all children, perform an AABB check inside ProcessChildShape
int numChildren = m_childCollisionAlgorithms.size();
int i;
btManifoldArray manifoldArray;
for (i=0;i<numChildren;i++)
{
if (m_childCollisionAlgorithms[i])
{
btCollisionShape* childShape = compoundShape->getChildShape(i);
//if not longer overlapping, remove the algorithm
btTransform orgTrans = colObj->getWorldTransform(); btTransform orgTrans = colObj->getWorldTransform();
btTransform orgInterpolationTrans = colObj->getInterpolationWorldTransform(); btTransform orgInterpolationTrans = colObj->getInterpolationWorldTransform();
const btTransform& childTrans = compoundShape->getChildTransform(i); const btTransform& childTrans = compoundShape->getChildTransform(i);
btTransform newChildWorldTrans = orgTrans*childTrans ; btTransform newChildWorldTrans = orgTrans*childTrans ;
colObj->setWorldTransform( newChildWorldTrans);
colObj->setInterpolationWorldTransform(newChildWorldTrans);
//the contactpoint is still projected back using the original inverted worldtrans //perform an AABB check first
btCollisionShape* tmpShape = colObj->getCollisionShape(); btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
colObj->internalSetTemporaryCollisionShape( childShape ); childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0);
m_childCollisionAlgorithms[i]->processCollision(colObj,otherObj,dispatchInfo,resultOut); otherObj->getCollisionShape()->getAabb(otherObj->getWorldTransform(),aabbMin1,aabbMax1);
//revert back
colObj->internalSetTemporaryCollisionShape( tmpShape); if (!TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
colObj->setWorldTransform( orgTrans ); {
colObj->setInterpolationWorldTransform(orgInterpolationTrans); m_childCollisionAlgorithms[i]->~btCollisionAlgorithm();
m_dispatcher->freeCollisionAlgorithm(m_childCollisionAlgorithms[i]);
m_childCollisionAlgorithms[i] = 0;
}
}
}
} }
} }

View File

@@ -28,12 +28,14 @@ class btDispatcher;
class btDispatcher; class btDispatcher;
/// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes /// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes
/// Place holder, not fully implemented yet
class btCompoundCollisionAlgorithm : public btCollisionAlgorithm class btCompoundCollisionAlgorithm : public btCollisionAlgorithm
{ {
btAlignedObjectArray<btCollisionAlgorithm*> m_childCollisionAlgorithms; btAlignedObjectArray<btCollisionAlgorithm*> m_childCollisionAlgorithms;
bool m_isSwapped; bool m_isSwapped;
class btPersistentManifold* m_sharedManifold;
bool m_ownsManifold;
public: public:
btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped); btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);

View File

@@ -21,20 +21,7 @@ subject to the following restrictions:
void btBoxShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const void btBoxShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
{ {
btVector3 halfExtents = getHalfExtentsWithoutMargin(); btTransformAabb(getHalfExtentsWithoutMargin(),getMargin(),t,aabbMin,aabbMax);
halfExtents += btVector3(getMargin(),getMargin(),getMargin());
btMatrix3x3 abs_b = t.getBasis().absolute();
btPoint3 center = t.getOrigin();
btVector3 extent = btVector3(abs_b[0].dot(halfExtents),
abs_b[1].dot(halfExtents),
abs_b[2].dot(halfExtents));
aabbMin = center - extent;
aabbMax = center + extent;
} }

View File

@@ -14,23 +14,29 @@ subject to the following restrictions:
*/ */
#include "btCompoundShape.h" #include "btCompoundShape.h"
#include "btCollisionShape.h" #include "btCollisionShape.h"
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
btCompoundShape::btCompoundShape() btCompoundShape::btCompoundShape()
:m_localAabbMin(btScalar(1e30),btScalar(1e30),btScalar(1e30)), :m_localAabbMin(btScalar(1e30),btScalar(1e30),btScalar(1e30)),
m_localAabbMax(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)), m_localAabbMax(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)),
m_aabbTree(0),
m_collisionMargin(btScalar(0.)), m_collisionMargin(btScalar(0.)),
m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)) m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
m_dynamicAabbTree(0)
{ {
void* mem = btAlignedAlloc(sizeof(btDbvt),16);
m_dynamicAabbTree = new(mem) btDbvt();
btAssert(mem==m_dynamicAabbTree);
} }
btCompoundShape::~btCompoundShape() btCompoundShape::~btCompoundShape()
{ {
if (m_dynamicAabbTree)
{
m_dynamicAabbTree->~btDbvt();
btAlignedFree(m_dynamicAabbTree);
}
} }
void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisionShape* shape) void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisionShape* shape)
@@ -60,28 +66,45 @@ void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisio
} }
} }
if (m_dynamicAabbTree)
{
const btDbvtVolume bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
int index = m_children.size()-1;
child.m_node = m_dynamicAabbTree->insert(bounds,(void*)index);
}
}
void btCompoundShape::removeChildShapeByIndex(int childShapeIndex)
{
btAssert(childShapeIndex >=0 && childShapeIndex < m_children.size());
if (m_dynamicAabbTree)
{
m_dynamicAabbTree->remove(m_children[childShapeIndex].m_node);
}
m_children.swap(childShapeIndex,m_children.size()-1);
m_children.pop_back();
} }
void btCompoundShape::removeChildShape(btCollisionShape* shape) void btCompoundShape::removeChildShape(btCollisionShape* shape)
{ {
bool done_removing;
// Find the children containing the shape specified, and remove those children. // Find the children containing the shape specified, and remove those children.
do //note: there might be multiple children using the same shape!
{ for(int i = m_children.size()-1; i >= 0 ; i--)
done_removing = true;
for(int i = 0; i < m_children.size(); i++)
{ {
if(m_children[i].m_childShape == shape) if(m_children[i].m_childShape == shape)
{ {
m_children.remove(m_children[i]); m_children.swap(i,m_children.size()-1);
done_removing = false; // Do another iteration pass after removing from the vector m_children.pop_back();
break; //remove it from the m_dynamicAabbTree too
//m_dynamicAabbTree->remove(m_aabbProxies[i]);
//m_aabbProxies.swap(i,m_children.size()-1);
//m_aabbProxies.pop_back();
} }
} }
}
while (!done_removing);
recalculateLocalAabb(); recalculateLocalAabb();
} }
@@ -108,7 +131,7 @@ void btCompoundShape::recalculateLocalAabb()
} }
} }
///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
{ {
btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin); btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);

View File

@@ -24,8 +24,8 @@ subject to the following restrictions:
#include "btCollisionMargin.h" #include "btCollisionMargin.h"
#include "LinearMath/btAlignedObjectArray.h" #include "LinearMath/btAlignedObjectArray.h"
class btOptimizedBvh; //class btOptimizedBvh;
struct btDbvt;
ATTRIBUTE_ALIGNED16(struct) btCompoundShapeChild ATTRIBUTE_ALIGNED16(struct) btCompoundShapeChild
{ {
@@ -35,6 +35,7 @@ ATTRIBUTE_ALIGNED16(struct) btCompoundShapeChild
btCollisionShape* m_childShape; btCollisionShape* m_childShape;
int m_childShapeType; int m_childShapeType;
btScalar m_childMargin; btScalar m_childMargin;
struct btDbvtNode* m_node;
}; };
SIMD_FORCE_INLINE bool operator==(const btCompoundShapeChild& c1, const btCompoundShapeChild& c2) SIMD_FORCE_INLINE bool operator==(const btCompoundShapeChild& c1, const btCompoundShapeChild& c2)
@@ -55,7 +56,8 @@ ATTRIBUTE_ALIGNED16(class) btCompoundShape : public btCollisionShape
btVector3 m_localAabbMin; btVector3 m_localAabbMin;
btVector3 m_localAabbMax; btVector3 m_localAabbMax;
btOptimizedBvh* m_aabbTree; //btOptimizedBvh* m_aabbTree;
btDbvt* m_dynamicAabbTree;
public: public:
BT_DECLARE_ALIGNED_ALLOCATOR(); BT_DECLARE_ALIGNED_ALLOCATOR();
@@ -66,10 +68,10 @@ public:
void addChildShape(const btTransform& localTransform,btCollisionShape* shape); void addChildShape(const btTransform& localTransform,btCollisionShape* shape);
/** Remove all children shapes that contain the specified shape. */ /// Remove all children shapes that contain the specified shape
virtual void removeChildShape(btCollisionShape* shape); virtual void removeChildShape(btCollisionShape* shape);
void removeChildShapeByIndex(int childShapeindex);
int getNumChildShapes() const int getNumChildShapes() const
@@ -137,9 +139,9 @@ public:
//this is optional, but should make collision queries faster, by culling non-overlapping nodes //this is optional, but should make collision queries faster, by culling non-overlapping nodes
void createAabbTreeFromChildren(); void createAabbTreeFromChildren();
const btOptimizedBvh* getAabbTree() const btDbvt* getDynamicAabbTree()
{ {
return m_aabbTree; return m_dynamicAabbTree;
} }
///computes the exact moment of inertia and the transform from the coordinate system defined by the principal axes of the moment of inertia ///computes the exact moment of inertia and the transform from the coordinate system defined by the principal axes of the moment of inertia

View File

@@ -18,6 +18,7 @@ subject to the following restrictions:
#include "LinearMath/btPoint3.h" #include "LinearMath/btPoint3.h"
#include "LinearMath/btMatrix3x3.h" #include "LinearMath/btMatrix3x3.h"
#include "LinearMath/btAabbUtil2.h"
#include "btConvexInternalShape.h" #include "btConvexInternalShape.h"
@@ -46,28 +47,7 @@ public:
//lazy evaluation of local aabb //lazy evaluation of local aabb
btAssert(m_isLocalAabbValid); btAssert(m_isLocalAabbValid);
btTransformAabb(m_localAabbMin,m_localAabbMax,margin,trans,aabbMin,aabbMax);
btAssert(m_localAabbMin.getX() <= m_localAabbMax.getX());
btAssert(m_localAabbMin.getY() <= m_localAabbMax.getY());
btAssert(m_localAabbMin.getZ() <= m_localAabbMax.getZ());
btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
localHalfExtents+= btVector3(margin,margin,margin);
btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
btMatrix3x3 abs_b = trans.getBasis().absolute();
btPoint3 center = trans(localCenter);
btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
abs_b[1].dot(localHalfExtents),
abs_b[2].dot(localHalfExtents));
aabbMin = center-extent;
aabbMax = center+extent;
} }

View File

@@ -17,6 +17,7 @@ subject to the following restrictions:
#ifndef AABB_UTIL2 #ifndef AABB_UTIL2
#define AABB_UTIL2 #define AABB_UTIL2
#include "btTransform.h"
#include "btVector3.h" #include "btVector3.h"
#include "btMinMax.h" #include "btMinMax.h"
@@ -163,6 +164,38 @@ SIMD_FORCE_INLINE bool btRayAabb(const btVector3& rayFrom,
} }
SIMD_FORCE_INLINE void btTransformAabb(const btVector3& halfExtents, btScalar margin,const btTransform& t,btVector3& aabbMinOut,btVector3& aabbMaxOut)
{
btVector3 halfExtentsWithMargin = halfExtents+btVector3(margin,margin,margin);
btMatrix3x3 abs_b = t.getBasis().absolute();
btVector3 center = t.getOrigin();
btVector3 extent = btVector3(abs_b[0].dot(halfExtentsWithMargin),
abs_b[1].dot(halfExtentsWithMargin),
abs_b[2].dot(halfExtentsWithMargin));
aabbMinOut = center - extent;
aabbMaxOut = center + extent;
};
SIMD_FORCE_INLINE void btTransformAabb(const btVector3& localAabbMin,const btVector3& localAabbMax, btScalar margin,const btTransform& trans,btVector3& aabbMinOut,btVector3& aabbMaxOut)
{
btAssert(localAabbMin.getX() <= localAabbMax.getX());
btAssert(localAabbMin.getY() <= localAabbMax.getY());
btAssert(localAabbMin.getZ() <= localAabbMax.getZ());
btVector3 localHalfExtents = btScalar(0.5)*(localAabbMax-localAabbMin);
localHalfExtents+=btVector3(margin,margin,margin);
btVector3 localCenter = btScalar(0.5)*(localAabbMax+localAabbMin);
btMatrix3x3 abs_b = trans.getBasis().absolute();
btVector3 center = trans(localCenter);
btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
abs_b[1].dot(localHalfExtents),
abs_b[2].dot(localHalfExtents));
aabbMinOut = center-extent;
aabbMaxOut = center+extent;
}
#endif #endif