From 7ac497d6f20df6dc4f6471580f420f103a32e7f7 Mon Sep 17 00:00:00 2001 From: erwin coumans Date: Sun, 18 Oct 2015 14:01:25 -0700 Subject: [PATCH] WIP example for real-time collision detection features of Bullet --- examples/Collision/CollisionSdkC_Api.cpp | 43 +++++-- examples/Collision/CollisionSdkC_Api.h | 38 +++--- .../Collision/CollisionTutorialBullet2.cpp | 103 +++++++++------- .../Internal/Bullet2CollisionSdk.cpp | 55 +++++++-- .../Collision/Internal/Bullet2CollisionSdk.h | 10 +- .../Internal/CollisionSdkInterface.h | 10 +- .../Internal/RealTimeBullet3CollisionSdk.cpp | 112 ++++++++++++++++++ .../Internal/RealTimeBullet3CollisionSdk.h | 42 +++++++ .../CommonInterfaces/CommonRenderInterface.h | 1 + .../OpenGLWindow/GLInstancingRenderer.cpp | 5 + examples/OpenGLWindow/GLInstancingRenderer.h | 1 + .../OpenGLWindow/SimpleOpenGL2Renderer.cpp | 5 + examples/OpenGLWindow/SimpleOpenGL2Renderer.h | 2 + examples/Tutorial/Tutorial.cpp | 7 ++ .../shared/b3Collidable.h | 13 +- 15 files changed, 355 insertions(+), 92 deletions(-) create mode 100644 examples/Collision/Internal/RealTimeBullet3CollisionSdk.cpp create mode 100644 examples/Collision/Internal/RealTimeBullet3CollisionSdk.h diff --git a/examples/Collision/CollisionSdkC_Api.cpp b/examples/Collision/CollisionSdkC_Api.cpp index 0fd2fded1..5ef7eec9b 100644 --- a/examples/Collision/CollisionSdkC_Api.cpp +++ b/examples/Collision/CollisionSdkC_Api.cpp @@ -1,24 +1,41 @@ #include "CollisionSdkC_Api.h" #include "Internal/CollisionSdkInterface.h" #include "Internal/Bullet2CollisionSdk.h" +#include "Internal/RealTimeBullet3CollisionSdk.h" /* Collision World */ -plCollisionWorldHandle plCreateCollisionWorld(plCollisionSdkHandle collisionSdkHandle) +plCollisionWorldHandle plCreateCollisionWorld(plCollisionSdkHandle collisionSdkHandle, int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity) { CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; - return sdk->createCollisionWorld(); + return sdk->createCollisionWorld( maxNumObjsCapacity, maxNumShapesCapacity, maxNumPairsCapacity); } void plDeleteCollisionWorld(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle) { CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; - sdk->deleteCollisionWorld(worldHandle); + if (sdk && worldHandle) + { + sdk->deleteCollisionWorld(worldHandle); + } } plCollisionSdkHandle plCreateBullet2CollisionSdk() { +#ifndef DISABLE_BULLET2_COLLISION_SDK return Bullet2CollisionSdk::createBullet2SdkHandle(); +#else + return 0; +#endif //DISABLE_BULLET2_COLLISION_SDK +} + +plCollisionSdkHandle plCreateRealTimeBullet3CollisionSdk() +{ +#ifndef DISABLE_REAL_TIME_BULLET3_COLLISION_SDK + return RealTimeBullet3CollisionSdk::createRealTimeBullet3CollisionSdkHandle(); +#else + return 0; +#endif } void plDeleteCollisionSdk(plCollisionSdkHandle collisionSdkHandle) @@ -27,32 +44,38 @@ void plDeleteCollisionSdk(plCollisionSdkHandle collisionSdkHandle) delete sdk; } -plCollisionShapeHandle plCreateSphereShape(plCollisionSdkHandle collisionSdkHandle, plReal radius) +plCollisionShapeHandle plCreateSphereShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plReal radius) { CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; - return sdk->createSphereShape(radius); + return sdk->createSphereShape(worldHandle,radius); } -void plDeleteShape(plCollisionSdkHandle collisionSdkHandle, plCollisionShapeHandle shapeHandle) +void plDeleteShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle shapeHandle) { CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; - sdk->deleteShape(shapeHandle); + sdk->deleteShape(worldHandle,shapeHandle); } -plCollisionObjectHandle plCreateCollisionObject( plCollisionSdkHandle collisionSdkHandle, void* user_data, plCollisionShapeHandle cshape ,plVector3 childPos,plQuaternion childOrn) +plCollisionObjectHandle plCreateCollisionObject( plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, void* userData, int userIndex, plCollisionShapeHandle cshape ,plVector3 childPos,plQuaternion childOrn) { CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; - return sdk->createCollisionObject(user_data, cshape, childPos, childOrn); + return sdk->createCollisionObject(userData, userIndex, cshape, childPos, childOrn); } -void plDeleteCollisionObject(plCollisionSdkHandle collisionSdkHandle, plCollisionObjectHandle body) +void plDeleteCollisionObject(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle body) { CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; sdk->deleteCollisionObject(body); } +void plSetCollisionObjectTransform( plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle objHandle, plVector3 position,plQuaternion orientation) +{ + CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; + sdk->setCollisionObjectTransform(objHandle,position,orientation); +} + void plAddCollisionObject(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object) { CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; diff --git a/examples/Collision/CollisionSdkC_Api.h b/examples/Collision/CollisionSdkC_Api.h index 25916c019..32cde118c 100644 --- a/examples/Collision/CollisionSdkC_Api.h +++ b/examples/Collision/CollisionSdkC_Api.h @@ -34,14 +34,18 @@ extern "C" { /* Collision SDK */ extern plCollisionSdkHandle plCreateBullet2CollisionSdk(); -// extern plCollisionSdkHandle plCreateRealTimeBullet3CollisionSdk(); + + extern plCollisionSdkHandle plCreateRealTimeBullet3CollisionSdk(); // extern plCollisionSdkHandle plCreateCustomCollisionSdk(); extern void plDeleteCollisionSdk(plCollisionSdkHandle collisionSdkHandle); - + + //extern int plGetSdkWorldCreationIntParameter(); + //extern int plSetSdkWorldCreationIntParameter(int newValue); + /* Collision World */ - extern plCollisionWorldHandle plCreateCollisionWorld(plCollisionSdkHandle collisionSdkHandle); + extern plCollisionWorldHandle plCreateCollisionWorld(plCollisionSdkHandle collisionSdkHandle, int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity); extern void plDeleteCollisionWorld(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world); @@ -51,22 +55,23 @@ extern "C" { /* Collision Object */ - extern plCollisionObjectHandle plCreateCollisionObject( plCollisionSdkHandle sdkHandle, void* user_data, plCollisionShapeHandle cshape , plVector3 startPosition,plQuaternion startOrientation); - extern void plDeleteCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionObjectHandle body); - + extern plCollisionObjectHandle plCreateCollisionObject( plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape , plVector3 startPosition,plQuaternion startOrientation); + extern void plDeleteCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle body); + extern void plSetCollisionObjectTransform( plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle objHandle, plVector3 startPosition,plQuaternion startOrientation); /* Collision Shape definition */ - extern plCollisionShapeHandle plCreateSphereShape(plCollisionSdkHandle sdk, plReal radius); - extern plCollisionShapeHandle plNewCapsuleShape(plCollisionSdkHandle sdk, plReal radius, plReal height); - extern plCollisionShapeHandle plNewPlaneShape(plCollisionSdkHandle sdk, plReal planeNormalX, - plReal planeNormalY, - plReal planeNormalZ, - plReal planeConstant); - extern plCollisionShapeHandle plNewCompoundShape(plCollisionSdkHandle sdk); - extern void plAddChildShape(plCollisionSdkHandle sdk, plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn); + extern plCollisionShapeHandle plCreateSphereShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle, plReal radius); + extern plCollisionShapeHandle plNewCapsuleShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle, plReal radius, plReal height); + extern plCollisionShapeHandle plNewPlaneShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle, + plReal planeNormalX, + plReal planeNormalY, + plReal planeNormalZ, + plReal planeConstant); + extern plCollisionShapeHandle plNewCompoundShape(plCollisionSdkHandle sdk,plCollisionWorldHandle worldHandle); + extern void plAddChildShape(plCollisionSdkHandle sdk, plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn); - extern void plDeleteShape(plCollisionSdkHandle collisionSdkHandle, plCollisionShapeHandle shape); + extern void plDeleteShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape); @@ -81,7 +86,8 @@ extern "C" { }; /* Collision Filtering */ - typedef void(*plNearCallback)(plCollisionSdkHandle sdk, void* userData, plCollisionObjectHandle objA, plCollisionObjectHandle objB); + typedef void(*plNearCallback)(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userData, + plCollisionObjectHandle objA, plCollisionObjectHandle objB); /* Collision Queries */ diff --git a/examples/Collision/CollisionTutorialBullet2.cpp b/examples/Collision/CollisionTutorialBullet2.cpp index 69fc62846..90c4895b3 100644 --- a/examples/Collision/CollisionTutorialBullet2.cpp +++ b/examples/Collision/CollisionTutorialBullet2.cpp @@ -17,11 +17,26 @@ #include "CollisionSdkC_Api.h" -static int myCounter=0; +///Not Invented Here link reminder http://www.joelonsoftware.com/articles/fog0000000007.html -void myNearCallback(plCollisionSdkHandle sdk, void* userData, plCollisionObjectHandle objA, plCollisionObjectHandle objB) +///todo: use the 'userData' to prevent this use of global variables +static int gTotalPoints = 0; +lwContactPoint pointsOut[10]; +int pointCapacity=2; + + +void myNearCallback(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userData, plCollisionObjectHandle objA, plCollisionObjectHandle objB) { - myCounter++; + int remainingCapacity = pointCapacity-gTotalPoints; + btAssert(remainingCapacity>=0); + + if (remainingCapacity>0) + { + lwContactPoint* pointPtr = &pointsOut[gTotalPoints]; + int numNewPoints = plCollide(sdkHandle, worldHandle, objA,objB,pointPtr,remainingCapacity); + btAssert(numNewPoints <= remainingCapacity); + gTotalPoints+=numNewPoints; + } } class CollisionTutorialBullet2 : public CommonExampleInterface @@ -44,6 +59,7 @@ public: m_guiHelper(guiHelper), m_tutorialIndex(tutorialIndex), m_collisionSdkHandle(0), + m_collisionWorldHandle(0), m_stage(0), m_counter(0), m_timeSeriesCanvas0(0) @@ -58,33 +74,43 @@ public: case TUT_SPHERE_SPHERE: { numBodies=10; - m_collisionSdkHandle = plCreateBullet2CollisionSdk(); + //m_collisionSdkHandle = plCreateBullet2CollisionSdk(); + m_collisionSdkHandle = plCreateRealTimeBullet3CollisionSdk(); if (m_collisionSdkHandle) { - m_collisionWorldHandle = plCreateCollisionWorld(m_collisionSdkHandle); + int maxNumObjsCapacity=32; + int maxNumShapesCapacity=1024; + int maxNumPairsCapacity=16384; + + m_collisionWorldHandle = plCreateCollisionWorld(m_collisionSdkHandle,maxNumObjsCapacity,maxNumShapesCapacity,maxNumPairsCapacity); //create objects, do query etc float radius = 1.f; - plCollisionShapeHandle colShape = plCreateSphereShape(m_collisionSdkHandle, radius); - void* userData = 0; + plCollisionShapeHandle colShape = plCreateSphereShape(m_collisionSdkHandle, m_collisionWorldHandle,radius); + void* userPointer = 0; btAlignedObjectArray colliders; - + int sphereGfxShapeId = m_app->registerGraphicsUnitSphereShape(SPHERE_LOD_HIGH);//, textureIndex); + for (int i=0;i<3;i++) { - btVector3 pos(0,i*1,0); + btVector3 pos(0,btScalar(i*1.5),0); btQuaternion orn(0,0,0,1); - plCollisionObjectHandle colObj = plCreateCollisionObject(m_collisionSdkHandle,userData,colShape,pos,orn); + + b3Vector4 color = b3MakeVector4(0,1,0,0.8); + b3Vector3 scaling = b3MakeVector3(radius,radius,radius); + + int gfxIndex = m_app->m_renderer->registerGraphicsInstance(sphereGfxShapeId,pos, orn,color,scaling); + + plCollisionObjectHandle colObj = plCreateCollisionObject(m_collisionSdkHandle,m_collisionWorldHandle,userPointer, gfxIndex,colShape,pos,orn); colliders.push_back(colObj); plAddCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle,colObj); } - lwContactPoint pointsOut[10]; - int pointCapacity=10; - + int numContacts = plCollide(m_collisionSdkHandle,m_collisionWorldHandle,colliders[0],colliders[1],pointsOut,pointCapacity); printf("numContacts = %d\n", numContacts); void* myUserPtr = 0; - myCounter = 0; + gTotalPoints = 0; plWorldCollide(m_collisionSdkHandle,m_collisionWorldHandle,myNearCallback, myUserPtr); - printf("myCounter=%d\n",myCounter); + printf("total points=%d\n",gTotalPoints); //plRemoveCollisionObject(m_collisionSdkHandle,m_collisionWorldHandle,colObj); //plDeleteCollisionObject(m_collisionSdkHandle,colObj); @@ -155,20 +181,6 @@ public: } } - // int boxId = m_app->registerCubeShape(1,1,1,textureIndex); - int boxId = m_app->registerGraphicsUnitSphereShape(SPHERE_LOD_HIGH);//, textureIndex); - b3Vector4 color = b3MakeVector4(0,1,0,0.8); - b3Vector3 scaling = b3MakeVector3(1,1,1); - float pos[3] = {1,0,0}; - float orn[4] = {0,0,0,1}; - int gfxIndex = m_app->m_renderer->registerGraphicsInstance(boxId,pos, orn,color,scaling); - - - // m_bodies[i]->m_graphicsIndex = m_app->m_renderer->registerGraphicsInstance(boxId,m_bodies[i]->m_worldPose.m_position, m_bodies[i]->m_worldPose.m_orientation,color,scaling); - - - //m_app->m_renderer->writeSingleInstanceTransformToCPU(m_bodies[i]->m_worldPose.m_position, m_bodies[i]->m_worldPose.m_orientation, m_bodies[i]->m_graphicsIndex); - } m_app->m_renderer->writeTransforms(); @@ -232,23 +244,30 @@ public: } virtual void renderScene() { - m_app->m_renderer->renderScene(); - m_app->drawText3D("X",1,0,0,1); - m_app->drawText3D("Y",0,1,0,1); - m_app->drawText3D("Z",0,0,1,1); - - /*for (int i=0;im_renderer) { - const LWContactPoint& contact = m_contactPoints[i]; - b3Vector3 color=b3MakeVector3(1,1,0); - float lineWidth=3; - if (contact.m_distance<0) + m_app->m_renderer->renderScene(); + + m_app->m_renderer->clearZBuffer(); + + m_app->drawText3D("X",1,0,0,1); + m_app->drawText3D("Y",0,1,0,1); + m_app->drawText3D("Z",0,0,1,1); + + + for (int i=0;im_renderer->drawLine(contact.m_ptOnAWorld,contact.m_ptOnBWorld,color,lineWidth); } - m_app->m_renderer->drawLine(contact.m_ptOnAWorld,contact.m_ptOnBWorld,color,lineWidth); } - */ + } diff --git a/examples/Collision/Internal/Bullet2CollisionSdk.cpp b/examples/Collision/Internal/Bullet2CollisionSdk.cpp index f93f08593..825d93885 100644 --- a/examples/Collision/Internal/Bullet2CollisionSdk.cpp +++ b/examples/Collision/Internal/Bullet2CollisionSdk.cpp @@ -29,9 +29,10 @@ Bullet2CollisionSdk::~Bullet2CollisionSdk() m_internalData = 0; } -plCollisionWorldHandle Bullet2CollisionSdk::createCollisionWorld() +plCollisionWorldHandle Bullet2CollisionSdk::createCollisionWorld(int /*maxNumObjsCapacity*/, int /*maxNumShapesCapacity*/, int /*maxNumPairsCapacity*/) { m_internalData->m_collisionConfig = new btDefaultCollisionConfiguration; + m_internalData->m_dispatcher = new btCollisionDispatcher(m_internalData->m_collisionConfig); m_internalData->m_aabbBroadphase = new btDbvtBroadphase(); m_internalData->m_collisionWorld = new btCollisionWorld(m_internalData->m_dispatcher, @@ -58,13 +59,13 @@ void Bullet2CollisionSdk::deleteCollisionWorld(plCollisionWorldHandle worldHandl } } -plCollisionShapeHandle Bullet2CollisionSdk::createSphereShape(plReal radius) +plCollisionShapeHandle Bullet2CollisionSdk::createSphereShape(plCollisionWorldHandle /*worldHandle*/, plReal radius) { btSphereShape* sphereShape = new btSphereShape(radius); return (plCollisionShapeHandle) sphereShape; } -void Bullet2CollisionSdk::deleteShape(plCollisionShapeHandle shapeHandle) +void Bullet2CollisionSdk::deleteShape(plCollisionWorldHandle /*worldHandle*/, plCollisionShapeHandle shapeHandle) { btCollisionShape* shape = (btCollisionShape*) shapeHandle; delete shape; @@ -91,7 +92,7 @@ void Bullet2CollisionSdk::removeCollisionObject(plCollisionWorldHandle worldHand } } -plCollisionObjectHandle Bullet2CollisionSdk::createCollisionObject( void* user_data, plCollisionShapeHandle shapeHandle , +plCollisionObjectHandle Bullet2CollisionSdk::createCollisionObject( void* userPointer, int userIndex, plCollisionShapeHandle shapeHandle , plVector3 startPosition,plQuaternion startOrientation ) { @@ -100,6 +101,8 @@ plCollisionObjectHandle Bullet2CollisionSdk::createCollisionObject( void* user_ if (colShape) { btCollisionObject* colObj= new btCollisionObject; + colObj->setUserIndex(userIndex); + colObj->setUserPointer(userPointer); colObj->setCollisionShape(colShape); btTransform tr; tr.setOrigin(btVector3(startPosition[0],startPosition[1],startPosition[2])); @@ -115,6 +118,16 @@ void Bullet2CollisionSdk::deleteCollisionObject(plCollisionObjectHandle bodyHand btCollisionObject* colObj = (btCollisionObject*) bodyHandle; delete colObj; } +void Bullet2CollisionSdk::setCollisionObjectTransform(plCollisionObjectHandle bodyHandle, + plVector3 position,plQuaternion orientation ) +{ + btCollisionObject* colObj = (btCollisionObject*) bodyHandle; + btTransform tr; + tr.setOrigin(btVector3(position[0],position[1],position[2])); + tr.setRotation(btQuaternion(orientation[0],orientation[1],orientation[2],orientation[3])); + colObj->setWorldTransform(tr); +} + struct Bullet2ContactResultCallback : public btCollisionWorld::ContactResultCallback { @@ -122,7 +135,10 @@ struct Bullet2ContactResultCallback : public btCollisionWorld::ContactResultCa lwContactPoint* m_pointsOut; int m_pointCapacity; - Bullet2ContactResultCallback() :m_numContacts(0) + Bullet2ContactResultCallback(lwContactPoint* pointsOut, int pointCapacity) : + m_numContacts(0), + m_pointsOut(pointsOut), + m_pointCapacity(pointCapacity) { } virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1) @@ -134,6 +150,12 @@ struct Bullet2ContactResultCallback : public btCollisionWorld::ContactResultCa ptOut.m_normalOnB[0] = cp.m_normalWorldOnB.getX(); ptOut.m_normalOnB[1] = cp.m_normalWorldOnB.getY(); ptOut.m_normalOnB[2] = cp.m_normalWorldOnB.getZ(); + ptOut.m_ptOnAWorld[0] = cp.m_positionWorldOnA[0]; + ptOut.m_ptOnAWorld[1] = cp.m_positionWorldOnA[1]; + ptOut.m_ptOnAWorld[2] = cp.m_positionWorldOnA[2]; + ptOut.m_ptOnBWorld[0] = cp.m_positionWorldOnB[0]; + ptOut.m_ptOnBWorld[1] = cp.m_positionWorldOnB[1]; + ptOut.m_ptOnBWorld[2] = cp.m_positionWorldOnB[2]; m_numContacts++; } @@ -150,7 +172,7 @@ int Bullet2CollisionSdk::collide(plCollisionWorldHandle worldHandle,plCollisionO btAssert(world && colObjA && colObjB); if (world == m_internalData->m_collisionWorld && colObjA && colObjB) { - Bullet2ContactResultCallback cb; + Bullet2ContactResultCallback cb(pointsOut,pointCapacity); world->contactPairTest(colObjA,colObjB,cb); return cb.m_numContacts; } @@ -158,13 +180,22 @@ int Bullet2CollisionSdk::collide(plCollisionWorldHandle worldHandle,plCollisionO } static plNearCallback gTmpFilter; -static int gContactCount = 0; +static int gNearCallbackCount = 0; +static plCollisionSdkHandle gCollisionSdk = 0; +static plCollisionWorldHandle gCollisionWorldHandle = 0; + +static void* gUserData = 0; void Bullet2NearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo) { - if (gTmpFilter) + btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject; + btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject; + plCollisionObjectHandle obA =(plCollisionObjectHandle) colObj0; + plCollisionObjectHandle obB =(plCollisionObjectHandle) colObj1; + if(gTmpFilter) { - gContactCount++; + gTmpFilter(gCollisionSdk,gCollisionWorldHandle, gUserData,obA,obB); + gNearCallbackCount++; } } @@ -174,8 +205,10 @@ void Bullet2CollisionSdk::collideWorld( plCollisionWorldHandle worldHandle, btCollisionWorld* world = (btCollisionWorld*) worldHandle; //chain the near-callback gTmpFilter = filter; - gContactCount = 0; - + gNearCallbackCount = 0; + gUserData = userData; + gCollisionSdk = (plCollisionSdkHandle)this; + gCollisionWorldHandle = worldHandle; m_internalData->m_dispatcher->setNearCallback(Bullet2NearCallback); world->performDiscreteCollisionDetection(); gTmpFilter = 0; diff --git a/examples/Collision/Internal/Bullet2CollisionSdk.h b/examples/Collision/Internal/Bullet2CollisionSdk.h index a2e9df7d2..b7a93c661 100644 --- a/examples/Collision/Internal/Bullet2CollisionSdk.h +++ b/examples/Collision/Internal/Bullet2CollisionSdk.h @@ -13,20 +13,22 @@ public: virtual ~Bullet2CollisionSdk(); - virtual plCollisionWorldHandle createCollisionWorld(); + virtual plCollisionWorldHandle createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity); virtual void deleteCollisionWorld(plCollisionWorldHandle worldHandle); - virtual plCollisionShapeHandle createSphereShape(plReal radius); + virtual plCollisionShapeHandle createSphereShape(plCollisionWorldHandle worldHandle, plReal radius); - virtual void deleteShape(plCollisionShapeHandle shape); + virtual void deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape); virtual void addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object); virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object); - virtual plCollisionObjectHandle createCollisionObject( void* user_data, plCollisionShapeHandle cshape , + virtual plCollisionObjectHandle createCollisionObject( void* userPointer, int userIndex, plCollisionShapeHandle cshape , plVector3 startPosition,plQuaternion startOrientation ); virtual void deleteCollisionObject(plCollisionObjectHandle body); + virtual void setCollisionObjectTransform(plCollisionObjectHandle body, + plVector3 position,plQuaternion orientation ); virtual int collide(plCollisionWorldHandle world,plCollisionObjectHandle colA, plCollisionObjectHandle colB, lwContactPoint* pointsOut, int pointCapacity); diff --git a/examples/Collision/Internal/CollisionSdkInterface.h b/examples/Collision/Internal/CollisionSdkInterface.h index a995203ae..d7065e2c0 100644 --- a/examples/Collision/Internal/CollisionSdkInterface.h +++ b/examples/Collision/Internal/CollisionSdkInterface.h @@ -11,20 +11,22 @@ public: { } - virtual plCollisionWorldHandle createCollisionWorld() = 0; + virtual plCollisionWorldHandle createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity) = 0; virtual void deleteCollisionWorld(plCollisionWorldHandle worldHandle) = 0; - virtual plCollisionShapeHandle createSphereShape(plReal radius) = 0; + virtual plCollisionShapeHandle createSphereShape(plCollisionWorldHandle worldHandle, plReal radius) = 0; - virtual void deleteShape(plCollisionShapeHandle shape) = 0; + virtual void deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape) = 0; virtual void addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object)=0; virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object)=0; - virtual plCollisionObjectHandle createCollisionObject( void* user_data, plCollisionShapeHandle cshape , + virtual plCollisionObjectHandle createCollisionObject( void* userPointer, int userIndex, plCollisionShapeHandle cshape , plVector3 startPosition,plQuaternion startOrientation )=0; virtual void deleteCollisionObject(plCollisionObjectHandle body)=0; + virtual void setCollisionObjectTransform(plCollisionObjectHandle body, + plVector3 position,plQuaternion orientation )=0; virtual int collide(plCollisionWorldHandle world,plCollisionObjectHandle colA, plCollisionObjectHandle colB, lwContactPoint* pointsOut, int pointCapacity)=0; diff --git a/examples/Collision/Internal/RealTimeBullet3CollisionSdk.cpp b/examples/Collision/Internal/RealTimeBullet3CollisionSdk.cpp new file mode 100644 index 000000000..27b52fe19 --- /dev/null +++ b/examples/Collision/Internal/RealTimeBullet3CollisionSdk.cpp @@ -0,0 +1,112 @@ +#include "RealTimeBullet3CollisionSdk.h" +#include "Bullet3Common/b3AlignedObjectArray.h" +#include "Bullet3Collision/NarrowPhaseCollision/shared/b3Collidable.h" + +struct RTB3CollisionWorld +{ + b3AlignedObjectArray m_collidables; + b3AlignedObjectArray m_childShapes; + b3AlignedObjectArray m_compoundOverlappingPairs; + int m_nextFreeShapeIndex; + int m_nextFreeCollidableIndex; + + RTB3CollisionWorld() + :m_nextFreeCollidableIndex(0), + m_nextFreeShapeIndex(0) + { + } +}; + +struct RealTimeBullet3CollisionSdkInternalData +{ + b3AlignedObjectArray m_collisionWorlds; +}; + +RealTimeBullet3CollisionSdk::RealTimeBullet3CollisionSdk() +{ + int szCol = sizeof(b3Collidable); + int szShap = sizeof(b3GpuChildShape); + int szComPair = sizeof(b3CompoundOverlappingPair); + m_internalData = new RealTimeBullet3CollisionSdkInternalData; +} + +RealTimeBullet3CollisionSdk::~RealTimeBullet3CollisionSdk() +{ + delete m_internalData; + m_internalData=0; +} + +plCollisionWorldHandle RealTimeBullet3CollisionSdk::createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity) +{ + RTB3CollisionWorld* world = new RTB3CollisionWorld(); + world->m_collidables.resize(maxNumObjsCapacity); + world->m_childShapes.resize(maxNumShapesCapacity); + world->m_compoundOverlappingPairs.resize(maxNumPairsCapacity); + + m_internalData->m_collisionWorlds.push_back(world); + return (plCollisionWorldHandle) world; +} + +void RealTimeBullet3CollisionSdk::deleteCollisionWorld(plCollisionWorldHandle worldHandle) +{ + RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle; + int loc = m_internalData->m_collisionWorlds.findLinearSearch(world); + b3Assert(loc >=0 && locm_collisionWorlds.size()); + if (loc >=0 && locm_collisionWorlds.size()) + { + m_internalData->m_collisionWorlds.remove(world); + delete world; + } +} + +plCollisionShapeHandle RealTimeBullet3CollisionSdk::createSphereShape(plCollisionWorldHandle worldHandle, plReal radius) +{ + int index = 10; + return (plCollisionShapeHandle) index; +} + +void RealTimeBullet3CollisionSdk::deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape) +{ + //deleting shapes would involve a garbage collection phase, and mess up all user indices + //this would be solved by one more in-direction, at some performance penalty for certain operations + //for now, we don't delete and eventually run out-of-shapes +} + +void RealTimeBullet3CollisionSdk::addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object) +{ +} + +void RealTimeBullet3CollisionSdk::removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object) +{ +} + +plCollisionObjectHandle RealTimeBullet3CollisionSdk::createCollisionObject( void* userPointer, int userIndex, plCollisionShapeHandle cshape , + plVector3 startPosition,plQuaternion startOrientation ) +{ + return 0; +} + +void RealTimeBullet3CollisionSdk::deleteCollisionObject(plCollisionObjectHandle body) +{ +} + +void RealTimeBullet3CollisionSdk::setCollisionObjectTransform(plCollisionObjectHandle body, + plVector3 position,plQuaternion orientation ) +{ +} + +int RealTimeBullet3CollisionSdk::collide(plCollisionWorldHandle world,plCollisionObjectHandle colA, plCollisionObjectHandle colB, + lwContactPoint* pointsOut, int pointCapacity) +{ + return 0; +} + +void RealTimeBullet3CollisionSdk::collideWorld( plCollisionWorldHandle world, + plNearCallback filter, void* userData) +{ +} + +plCollisionSdkHandle RealTimeBullet3CollisionSdk::createRealTimeBullet3CollisionSdkHandle() +{ + return (plCollisionSdkHandle) new RealTimeBullet3CollisionSdk(); +} \ No newline at end of file diff --git a/examples/Collision/Internal/RealTimeBullet3CollisionSdk.h b/examples/Collision/Internal/RealTimeBullet3CollisionSdk.h new file mode 100644 index 000000000..b153f50c3 --- /dev/null +++ b/examples/Collision/Internal/RealTimeBullet3CollisionSdk.h @@ -0,0 +1,42 @@ +#ifndef REAL_TIME_COLLISION_SDK_H +#define REAL_TIME_COLLISION_SDK_H + +#include "CollisionSdkInterface.h" + +class RealTimeBullet3CollisionSdk : public CollisionSdkInterface +{ + struct RealTimeBullet3CollisionSdkInternalData* m_internalData; + +public: + + RealTimeBullet3CollisionSdk(); + + virtual ~RealTimeBullet3CollisionSdk(); + + virtual plCollisionWorldHandle createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity); + + virtual void deleteCollisionWorld(plCollisionWorldHandle worldHandle); + + virtual plCollisionShapeHandle createSphereShape(plCollisionWorldHandle worldHandle, plReal radius); + virtual void deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape); + + virtual void addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object); + virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object); + + virtual plCollisionObjectHandle createCollisionObject( void* userPointer, int userIndex, plCollisionShapeHandle cshape , + plVector3 startPosition,plQuaternion startOrientation ); + virtual void deleteCollisionObject(plCollisionObjectHandle body); + virtual void setCollisionObjectTransform(plCollisionObjectHandle body, + plVector3 position,plQuaternion orientation ); + + virtual int collide(plCollisionWorldHandle world,plCollisionObjectHandle colA, plCollisionObjectHandle colB, + lwContactPoint* pointsOut, int pointCapacity); + + virtual void collideWorld( plCollisionWorldHandle world, + plNearCallback filter, void* userData); + + static plCollisionSdkHandle createRealTimeBullet3CollisionSdkHandle(); +}; + + +#endif //REAL_TIME_COLLISION_SDK_H diff --git a/examples/CommonInterfaces/CommonRenderInterface.h b/examples/CommonInterfaces/CommonRenderInterface.h index 6e167c17a..a3d1d0f8b 100644 --- a/examples/CommonInterfaces/CommonRenderInterface.h +++ b/examples/CommonInterfaces/CommonRenderInterface.h @@ -51,6 +51,7 @@ struct CommonRenderInterface virtual void writeTransforms()=0; virtual void enableBlend(bool blend)=0; + virtual void clearZBuffer()=0; //This is internal access to OpenGL3+ features, mainly used for OpenCL-OpenGL interop //Only the GLInstancingRenderer supports it, just return 0 otherwise. diff --git a/examples/OpenGLWindow/GLInstancingRenderer.cpp b/examples/OpenGLWindow/GLInstancingRenderer.cpp index 5798c75ba..695f39e98 100644 --- a/examples/OpenGLWindow/GLInstancingRenderer.cpp +++ b/examples/OpenGLWindow/GLInstancingRenderer.cpp @@ -1669,6 +1669,11 @@ void GLInstancingRenderer::enableShadowMap() } +void GLInstancingRenderer::clearZBuffer() +{ + glClear(GL_DEPTH_BUFFER_BIT); +} + int GLInstancingRenderer::getMaxShapeCapacity() const { return m_data->m_maxShapeCapacityInBytes; diff --git a/examples/OpenGLWindow/GLInstancingRenderer.h b/examples/OpenGLWindow/GLInstancingRenderer.h index 2fd726409..abdadb9e9 100644 --- a/examples/OpenGLWindow/GLInstancingRenderer.h +++ b/examples/OpenGLWindow/GLInstancingRenderer.h @@ -127,6 +127,7 @@ public: { m_enableBlend = blend; } + virtual void clearZBuffer(); }; diff --git a/examples/OpenGLWindow/SimpleOpenGL2Renderer.cpp b/examples/OpenGLWindow/SimpleOpenGL2Renderer.cpp index a1108f8e4..74c701aad 100644 --- a/examples/OpenGLWindow/SimpleOpenGL2Renderer.cpp +++ b/examples/OpenGLWindow/SimpleOpenGL2Renderer.cpp @@ -160,3 +160,8 @@ void SimpleOpenGL2Renderer::updateShape(int shapeIndex, const float* vertices) void SimpleOpenGL2Renderer::enableBlend(bool blend) { } + +void SimpleOpenGL2Renderer::clearZBuffer() +{ + glClear(GL_DEPTH_BUFFER_BIT); +} \ No newline at end of file diff --git a/examples/OpenGLWindow/SimpleOpenGL2Renderer.h b/examples/OpenGLWindow/SimpleOpenGL2Renderer.h index 45c7809da..b1e64483c 100644 --- a/examples/OpenGLWindow/SimpleOpenGL2Renderer.h +++ b/examples/OpenGLWindow/SimpleOpenGL2Renderer.h @@ -76,6 +76,8 @@ struct SimpleOpenGL2Renderer : public CommonRenderInterface virtual void enableBlend(bool blend); + virtual void clearZBuffer(); + virtual struct GLInstanceRendererInternalData* getInternalData() { return 0; diff --git a/examples/Tutorial/Tutorial.cpp b/examples/Tutorial/Tutorial.cpp index c7564deae..8a2e0ca81 100644 --- a/examples/Tutorial/Tutorial.cpp +++ b/examples/Tutorial/Tutorial.cpp @@ -30,6 +30,8 @@ enum LWEnumCollisionTypes struct LWPlane { + BT_DECLARE_ALIGNED_ALLOCATOR(); + b3Vector3 m_normal; btScalar m_planeConstant; }; @@ -47,6 +49,7 @@ struct LWSphere struct LWBox { + BT_DECLARE_ALIGNED_ALLOCATOR(); b3Vector3 m_halfExtents; }; @@ -64,6 +67,8 @@ struct LWCollisionShape struct LWPose { + BT_DECLARE_ALIGNED_ALLOCATOR(); + b3Vector3 m_position; b3Quaternion m_orientation; LWPose() @@ -119,6 +124,8 @@ enum LWRIGIDBODY_FLAGS }; struct LWRigidBody { + BT_DECLARE_ALIGNED_ALLOCATOR(); + LWPose m_worldPose; b3Vector3 m_linearVelocity; b3Vector3 m_angularVelocity; diff --git a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3Collidable.h b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3Collidable.h index 50f835287..0ef4d97a7 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3Collidable.h +++ b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3Collidable.h @@ -15,6 +15,9 @@ enum b3ShapeTypes SHAPE_CONCAVE_TRIMESH=5, SHAPE_COMPOUND_OF_CONVEX_HULLS=6, SHAPE_SPHERE=7, + SHAPE_CAPSULE=8, + SHAPE_COMPOUND_OF_SPHERES=9, + SHAPE_COMPOUND_OF_CAPSULES=10, MAX_NUM_SHAPE_TYPES, }; @@ -37,16 +40,15 @@ struct b3Collidable int m_shapeIndex; }; - typedef struct b3GpuChildShape b3GpuChildShape_t; struct b3GpuChildShape { b3Float4 m_childPosition; b3Quat m_childOrientation; - int m_shapeIndex; - int m_unused0; - int m_unused1; - int m_unused2; + int m_shapeIndex;//used for SHAPE_COMPOUND_OF_CONVEX_HULLS + float m_radius;//used for SHAPE_COMPOUND_OF_SPHERES or SHAPE_COMPOUND_OF_CAPSULES + float m_height;//used for SHAPE_COMPOUND_OF_CAPSULES + int m_unused2; }; struct b3CompoundOverlappingPair @@ -57,4 +59,5 @@ struct b3CompoundOverlappingPair int m_childShapeIndexA; int m_childShapeIndexB; }; + #endif //B3_COLLIDABLE_H