updated demos -> ALT + mouse uses Maya-style controls, replaced BMF_Fonts by GLDebugFont
fix debug drawing of btMultiSphereShape added box2d demo added experimental gpu 2d demo
This commit is contained in:
759
Demos/Gpu2dDemo/BasicDemo.cpp
Normal file
759
Demos/Gpu2dDemo/BasicDemo.cpp
Normal file
@@ -0,0 +1,759 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletMultiThreaded/btGpuDefines.h"
|
||||
#include "BulletMultiThreaded/btGpuUtilsSharedDefs.h"
|
||||
#include "BulletMultiThreaded/btGpuUtilsSharedCode.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h"
|
||||
|
||||
#include "btGpuDemoPairCache.h"
|
||||
|
||||
#include "btGpuDemoDynamicsWorld.h"
|
||||
#include "GLDebugFont.h"
|
||||
|
||||
#define USE_CUDA_DEMO_PAIR_CASHE 0
|
||||
|
||||
#define SPEC_TEST 0
|
||||
#define OECAKE_LOADER 1
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define LARGE_DEMO 0
|
||||
// #define LARGE_DEMO 1
|
||||
#else
|
||||
#define LARGE_DEMO 1
|
||||
#endif
|
||||
|
||||
#if LARGE_DEMO
|
||||
///create 512 (8x8x8) dynamic object
|
||||
// #define ARRAY_SIZE_X 116
|
||||
// #define ARRAY_SIZE_Y 116
|
||||
|
||||
// #define ARRAY_SIZE_X 228
|
||||
// #define ARRAY_SIZE_Y 228
|
||||
// #define ARRAY_SIZE_X 256
|
||||
// #define ARRAY_SIZE_Y 156
|
||||
#define ARRAY_SIZE_X 50
|
||||
#define ARRAY_SIZE_Y 100
|
||||
#define ARRAY_SIZE_Z 1
|
||||
#else
|
||||
///create 125 (5x5x5) dynamic object
|
||||
#define ARRAY_SIZE_X 5
|
||||
#define ARRAY_SIZE_Y 5
|
||||
// #define ARRAY_SIZE_Z 5
|
||||
#define ARRAY_SIZE_Z 1
|
||||
#endif
|
||||
|
||||
|
||||
//maximum number of objects (and allow user to shoot additional boxes)
|
||||
#define NUM_SMALL_PROXIES (ARRAY_SIZE_X*ARRAY_SIZE_Y*ARRAY_SIZE_Z)
|
||||
#define MAX_PROXIES (NUM_SMALL_PROXIES + 1024)
|
||||
#define MAX_LARGE_PROXIES 0
|
||||
#define MAX_SMALL_PROXIES (MAX_PROXIES - MAX_LARGE_PROXIES)
|
||||
|
||||
///scaling of the objects (0.1 = 20 centimeter boxes )
|
||||
//#define SCALING 0.1
|
||||
#define SCALING 1
|
||||
#define START_POS_X 0
|
||||
#define START_POS_Y 0
|
||||
#define START_POS_Z 0
|
||||
|
||||
#include "BasicDemo.h"
|
||||
#include "GlutStuff.h"
|
||||
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h"
|
||||
|
||||
#ifdef BT_USE_CUDA
|
||||
#include "../Extras/CUDA/btCudaBroadphase.h"
|
||||
#else
|
||||
#include "BulletMultiThreaded/btGpu3DGridBroadphase.h"
|
||||
#endif
|
||||
|
||||
btScalar gTimeStep = btScalar(1./60.);
|
||||
|
||||
bool gbDrawBatches = false;
|
||||
int gSelectedBatch = CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES;
|
||||
#ifdef BT_USE_CUDA
|
||||
bool gUseCPUSolver = false;
|
||||
#else
|
||||
bool gUseCPUSolver = true;
|
||||
#endif //BT_USE_CUDA
|
||||
|
||||
|
||||
#include "oecakeLoader.h"
|
||||
|
||||
|
||||
class BasicDemoOecakeLoader : public BasicOECakeReader
|
||||
{
|
||||
|
||||
BasicDemo* m_demo;
|
||||
|
||||
public:
|
||||
|
||||
BasicDemoOecakeLoader(BasicDemo* demo)
|
||||
:m_demo(demo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual void createBodyForCompoundShape(btCompoundShape* compoundTmpShape,bool addConstraint, const btTransform& worldTransform, btScalar mass)
|
||||
{
|
||||
|
||||
btDefaultMotionState* myMotionState= 0;
|
||||
|
||||
btVector3 inertiaHalfExtents;
|
||||
btVector3 aabbMin,aabbMax;
|
||||
compoundTmpShape->getAabb(btTransform::getIdentity(),aabbMin,aabbMax);
|
||||
inertiaHalfExtents = (aabbMax-aabbMin)*0.5;
|
||||
int numSpheres = compoundTmpShape->getNumChildShapes();
|
||||
btAssert(numSpheres>0);
|
||||
if (numSpheres>8)
|
||||
{
|
||||
printf("error: exceeded 8 spheres\n");
|
||||
return;
|
||||
}
|
||||
|
||||
btVector3* positions = new btVector3[numSpheres];
|
||||
btScalar* radii = new btScalar[numSpheres];
|
||||
|
||||
for (int i=0;i<numSpheres;i++)
|
||||
{
|
||||
btAssert(compoundTmpShape->getChildShape(i)->getShapeType()== SPHERE_SHAPE_PROXYTYPE);
|
||||
btSphereShape* sphereShape = (btSphereShape*)compoundTmpShape->getChildShape(i);
|
||||
radii[i]=sphereShape->getRadius();
|
||||
positions[i] = compoundTmpShape->getChildTransform(i).getOrigin();
|
||||
}
|
||||
|
||||
btMultiSphereShape* multiSphere = new btMultiSphereShape(inertiaHalfExtents,positions,radii,numSpheres);
|
||||
|
||||
btVector3 localInertia(0,0,0);
|
||||
if (mass)
|
||||
{
|
||||
myMotionState = new btDefaultMotionState(worldTransform);
|
||||
multiSphere->calculateLocalInertia(mass,localInertia);
|
||||
}
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btRigidBody* body = new btRigidBody(mass,myMotionState,multiSphere,localInertia);
|
||||
body->setLinearFactor(btVector3(1,1,0));
|
||||
body->setAngularFactor(btVector3(0,0,1));
|
||||
|
||||
body->setWorldTransform(worldTransform);
|
||||
|
||||
|
||||
m_demo->getDynamicsWorld()->addRigidBody(body);
|
||||
|
||||
if (addConstraint)
|
||||
{
|
||||
btVector3 pivotInA(0,0,0);
|
||||
btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*body,pivotInA);
|
||||
m_demo->getDynamicsWorld()->addConstraint(p2p);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
void BasicDemo::clientMoveAndDisplay()
|
||||
{
|
||||
updateCamera();
|
||||
glDisable(GL_LIGHTING);
|
||||
glColor3f(1.f, 1.f, 1.f);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glDisable(GL_TEXTURE_2D); // we always draw wireframe in this demo
|
||||
|
||||
//simple dynamics world doesn't handle fixed-time-stepping
|
||||
float ms = getDeltaTimeMicroseconds();
|
||||
|
||||
///step the simulation
|
||||
if (m_dynamicsWorld)
|
||||
{
|
||||
#if USE_CUDA_DEMO_PAIR_CASHE
|
||||
btCudaDemoPairCache* pc = (btCudaDemoPairCache*)m_dynamicsWorld->getPairCache();
|
||||
pc->m_numSmallProxies = m_dynamicsWorld->getNumCollisionObjects(); // - 1; // exclude floor
|
||||
#endif
|
||||
m_dynamicsWorld->stepSimulation(gTimeStep,0);//ms / 1000000.f);
|
||||
//optional but useful: debug drawing
|
||||
m_dynamicsWorld->debugDrawWorld();
|
||||
}
|
||||
renderme();
|
||||
|
||||
ms = getDeltaTimeMicroseconds();
|
||||
|
||||
glFlush();
|
||||
|
||||
glutSwapBuffers();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BasicDemo::displayCallback(void) {
|
||||
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
renderme();
|
||||
|
||||
//optional but useful: debug drawing to detect problems
|
||||
if (m_dynamicsWorld)
|
||||
m_dynamicsWorld->debugDrawWorld();
|
||||
|
||||
glFlush();
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
|
||||
#define POS_OFFS_X (ARRAY_SIZE_X * SCALING + 20)
|
||||
#define POS_OFFS_Y (ARRAY_SIZE_Y * SCALING + 10)
|
||||
#define POS_OFFS_Z (ARRAY_SIZE_Z * SCALING)
|
||||
|
||||
#if OECAKE_LOADER
|
||||
btVector3 gWorldMin(-200, 0, 0);
|
||||
btVector3 gWorldMax( 200, 200, 0);
|
||||
#else
|
||||
btVector3 gWorldMin(-POS_OFFS_X, -POS_OFFS_Y, -POS_OFFS_Z);
|
||||
btVector3 gWorldMax( POS_OFFS_X, POS_OFFS_Y, POS_OFFS_Z);
|
||||
#endif
|
||||
|
||||
//btCudaDemoPairCache* gPairCache;
|
||||
btOverlappingPairCache* gPairCache;
|
||||
|
||||
|
||||
void BasicDemo::initPhysics()
|
||||
{
|
||||
setTexturing(false);
|
||||
setShadows(false);
|
||||
|
||||
#if OECAKE_LOADER
|
||||
setCameraDistance(80.);
|
||||
m_cameraTargetPosition.setValue(50, 10, 0);
|
||||
#else
|
||||
#if LARGE_DEMO
|
||||
setCameraDistance(btScalar(SCALING*100.));
|
||||
#else
|
||||
setCameraDistance(btScalar(SCALING*20.));
|
||||
#endif
|
||||
m_cameraTargetPosition.setValue(START_POS_X, -START_POS_Y-20, START_POS_Z);
|
||||
#endif
|
||||
m_azi = btScalar(0.f);
|
||||
m_ele = btScalar(0.f);
|
||||
|
||||
///collision configuration contains default setup for memory, collision setup
|
||||
|
||||
btDefaultCollisionConstructionInfo dci;
|
||||
dci.m_defaultMaxPersistentManifoldPoolSize=50000;
|
||||
dci.m_defaultMaxCollisionAlgorithmPoolSize=50000;
|
||||
|
||||
m_collisionConfiguration = new btDefaultCollisionConfiguration(dci);
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE,new btEmptyAlgorithm::CreateFunc);
|
||||
|
||||
m_dispatcher->setNearCallback(cudaDemoNearCallback);
|
||||
|
||||
|
||||
#if USE_CUDA_DEMO_PAIR_CASHE
|
||||
gPairCache = new (btAlignedAlloc(sizeof(btCudaDemoPairCache),16)) btCudaDemoPairCache(MAX_PROXIES, 24, MAX_SMALL_PROXIES);
|
||||
#else
|
||||
gPairCache = new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16))btHashedOverlappingPairCache();
|
||||
#endif
|
||||
|
||||
|
||||
btVector3 numOfCells = (gWorldMax - gWorldMin) / (2. * SCALING);
|
||||
int numOfCellsX = (int)numOfCells[0];
|
||||
int numOfCellsY = (int)numOfCells[1];
|
||||
int numOfCellsZ = (int)numOfCells[2];
|
||||
|
||||
// m_broadphase = new btAxisSweep3(gWorldMin, gWorldMax, MAX_PROXIES,gPairCache);
|
||||
m_broadphase = new btDbvtBroadphase(gPairCache);
|
||||
// m_broadphase = new btGpu3DGridBroadphase(gPairCache, gWorldMin, gWorldMax,numOfCellsX, numOfCellsY, numOfCellsZ,MAX_SMALL_PROXIES,10,24,24);
|
||||
// m_broadphase = new btCudaBroadphase(gPairCache, gWorldMin, gWorldMax,numOfCellsX, numOfCellsY, numOfCellsZ,MAX_SMALL_PROXIES,10,24,24);
|
||||
|
||||
|
||||
///the default constraint solver
|
||||
m_solver = new btSequentialImpulseConstraintSolver();
|
||||
|
||||
btGpuDemoDynamicsWorld* pDdw = new btGpuDemoDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration, MAX_PROXIES);
|
||||
m_dynamicsWorld = pDdw;
|
||||
pDdw->getSimulationIslandManager()->setSplitIslands(true);
|
||||
pDdw->setObjRad(SCALING);
|
||||
pDdw->setWorldMin(gWorldMin);
|
||||
pDdw->setWorldMax(gWorldMax);
|
||||
// gUseCPUSolver = true;
|
||||
pDdw->setUseCPUSolver(gUseCPUSolver);
|
||||
|
||||
// m_dynamicsWorld->setGravity(btVector3(0,0,0));
|
||||
m_dynamicsWorld->setGravity(btVector3(0,-10.,0));
|
||||
m_dynamicsWorld->getSolverInfo().m_numIterations = 4;
|
||||
|
||||
{
|
||||
//create a few dynamic rigidbodies
|
||||
// Re-using the same collision is better for memory usage and performance
|
||||
|
||||
|
||||
//btCollisionShape* colShape = new btBoxShape(btVector3(SCALING*1,SCALING*1,0.1));//SCALING*1));
|
||||
// btCollisionShape* colShape = new btBox2dShape(btVector3(SCALING*.7,SCALING*.7,0.1));//SCALING*1));
|
||||
|
||||
#define SPRADIUS btScalar(SCALING*0.1f)
|
||||
#define SPRPOS btScalar(SCALING*0.05f)
|
||||
static btVector3 sSphPos[8];
|
||||
|
||||
for (int k=0;k<8;k++)
|
||||
{
|
||||
sSphPos[k].setValue((k-4)*0.25*SCALING,0,0);
|
||||
}
|
||||
|
||||
btVector3 inertiaHalfExtents(SPRADIUS, SPRADIUS, SPRADIUS);
|
||||
static btScalar sSphRad[8] =
|
||||
{
|
||||
// SPRADIUS, SPRADIUS, SPRADIUS, SPRADIUS,SPRADIUS, SPRADIUS, SPRADIUS, 0.3
|
||||
SPRADIUS, SPRADIUS, SPRADIUS, SPRADIUS,SPRADIUS, SPRADIUS, SPRADIUS, SPRADIUS
|
||||
};
|
||||
// sSphPos[0].setX(sSphPos[0].getX()-0.15);
|
||||
#undef SPR
|
||||
btMultiSphereShape* colShape[2];
|
||||
colShape[0] = new btMultiSphereShape(inertiaHalfExtents, sSphPos, sSphRad, 8);
|
||||
colShape[1] = new btMultiSphereShape(inertiaHalfExtents, sSphPos, sSphRad, 2);
|
||||
|
||||
//btCollisionShape* colShape = new btSphereShape(btScalar(1.));
|
||||
m_collisionShapes.push_back(colShape[0]);
|
||||
m_collisionShapes.push_back(colShape[1]);
|
||||
|
||||
/// Create Dynamic Objects
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
|
||||
btScalar mass(1.f);
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
btVector3 localInertia(0,0,0);
|
||||
|
||||
#if OECAKE_LOADER
|
||||
BasicDemoOecakeLoader loader(this);
|
||||
if (!loader.processFile("test1.oec"))
|
||||
{
|
||||
loader.processFile("../../test1.oec");
|
||||
}
|
||||
|
||||
#else
|
||||
#if (!SPEC_TEST)
|
||||
float start_x = START_POS_X - ARRAY_SIZE_X * SCALING;
|
||||
float start_y = START_POS_Y - ARRAY_SIZE_Y * SCALING;
|
||||
float start_z = START_POS_Z - ARRAY_SIZE_Z * SCALING;
|
||||
|
||||
int collisionShapeIndex = 0;
|
||||
for (int k=0;k<ARRAY_SIZE_Y;k++)
|
||||
{
|
||||
for (int i=0;i<ARRAY_SIZE_X;i++)
|
||||
{
|
||||
for(int j = 0;j<ARRAY_SIZE_Z;j++)
|
||||
{
|
||||
float offs = (2. * (float)rand() / (float)RAND_MAX - 1.f) * 0.05f;
|
||||
startTransform.setOrigin(SCALING*btVector3(
|
||||
2.0*SCALING*i + start_x + offs,
|
||||
2.0*SCALING*k + start_y + offs,
|
||||
2.0*SCALING*j + start_z));
|
||||
|
||||
if (isDynamic)
|
||||
colShape[collisionShapeIndex]->calculateLocalInertia(mass,localInertia);
|
||||
|
||||
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
//btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape[collisionShapeIndex],localInertia);
|
||||
collisionShapeIndex = 1 - collisionShapeIndex;
|
||||
rbInfo.m_startWorldTransform=startTransform;
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else//SPEC_TEST
|
||||
// narrowphase test - 2 bodies at the same position
|
||||
float start_x = START_POS_X;
|
||||
// float start_y = START_POS_Y;
|
||||
float start_y = gWorldMin[1] + SCALING * 0.7f + 5.f;
|
||||
float start_z = START_POS_Z;
|
||||
startTransform.setOrigin(SCALING*btVector3(start_x,start_y,start_z));
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape[0],localInertia);
|
||||
rbInfo.m_startWorldTransform=startTransform;
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
|
||||
btPoint2PointConstraint * p2pConstr = new btPoint2PointConstraint(*body, btVector3(1., 0., 0.));
|
||||
m_dynamicsWorld->addConstraint(p2pConstr);
|
||||
|
||||
startTransform.setOrigin(SCALING*btVector3(start_x-2.f, start_y,start_z));
|
||||
rbInfo.m_startWorldTransform=startTransform;
|
||||
btRigidBody* body1 = new btRigidBody(rbInfo);
|
||||
m_dynamicsWorld->addRigidBody(body1);
|
||||
|
||||
p2pConstr = new btPoint2PointConstraint(*body, *body1, btVector3(-1., 0., 0.), btVector3(1., 0., 0.));
|
||||
m_dynamicsWorld->addConstraint(p2pConstr);
|
||||
|
||||
|
||||
#endif//SPEC_TEST
|
||||
#endif //OE_CAKE_LOADER
|
||||
}
|
||||
// now set Ids used by collision detector and constraint solver
|
||||
int numObjects = m_dynamicsWorld->getNumCollisionObjects();
|
||||
btCollisionObjectArray& collisionObjects = m_dynamicsWorld->getCollisionObjectArray();
|
||||
for(int i = 0; i < numObjects; i++)
|
||||
{
|
||||
btCollisionObject* colObj = collisionObjects[i];
|
||||
colObj->setCompanionId(i+1); // 0 reserved for the "world" object
|
||||
btCollisionShape* pShape = colObj->getCollisionShape();
|
||||
int shapeType = pShape->getShapeType();
|
||||
if(shapeType == MULTI_SPHERE_SHAPE_PROXYTYPE)
|
||||
{
|
||||
btMultiSphereShape* pMs = (btMultiSphereShape*)pShape;
|
||||
int numSpheres = pMs->getSphereCount();
|
||||
pDdw->addMultiShereObject(numSpheres, i + 1);
|
||||
for(int j = 0; j < numSpheres; j++)
|
||||
{
|
||||
btVector3 sphPos = pMs->getSpherePosition(j);
|
||||
float sphRad = pMs->getSphereRadius(j);
|
||||
pDdw->addSphere(sphPos, sphRad);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
btAssert(0);
|
||||
}
|
||||
}
|
||||
#if OECAKE_LOADER
|
||||
clientResetScene();
|
||||
#endif
|
||||
}
|
||||
|
||||
void BasicDemo::clientResetScene()
|
||||
{
|
||||
DemoApplication::clientResetScene();
|
||||
#if OECAKE_LOADER
|
||||
return;
|
||||
#endif
|
||||
#if SPEC_TEST
|
||||
{
|
||||
float start_x = START_POS_X;
|
||||
// float start_y = START_POS_Y;
|
||||
float start_y = gWorldMin[1] + SCALING * 0.7f + 5.f;
|
||||
float start_z = START_POS_Z;
|
||||
int numObjects = m_dynamicsWorld->getNumCollisionObjects();
|
||||
btCollisionObjectArray& collisionObjects = m_dynamicsWorld->getCollisionObjectArray();
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
for(int n = 0; n < numObjects; n++)
|
||||
{
|
||||
btCollisionObject* colObj = collisionObjects[n];
|
||||
btRigidBody* rb = btRigidBody::upcast(colObj);
|
||||
if(!n)
|
||||
{
|
||||
startTransform.setOrigin(SCALING*btVector3(start_x,start_y,start_z));
|
||||
}
|
||||
else
|
||||
{
|
||||
// startTransform.setOrigin(SCALING*btVector3(start_x+0.1f,start_y+SCALING * 0.7f * 2.f, start_z));
|
||||
startTransform.setOrigin(SCALING*btVector3(start_x-2.f,start_y, start_z));
|
||||
}
|
||||
rb->setCenterOfMassTransform(startTransform);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// we don't use motionState, so reset transforms here
|
||||
int numObjects = m_dynamicsWorld->getNumCollisionObjects();
|
||||
btCollisionObjectArray& collisionObjects = m_dynamicsWorld->getCollisionObjectArray();
|
||||
|
||||
float start_x = START_POS_X - ARRAY_SIZE_X * SCALING;
|
||||
float start_y = START_POS_Y - ARRAY_SIZE_Y * SCALING;
|
||||
float start_z = START_POS_Z - ARRAY_SIZE_Z * SCALING;
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
|
||||
for(int n = 0; n < numObjects; n++)
|
||||
{
|
||||
btCollisionObject* colObj = collisionObjects[n];
|
||||
colObj->setCompanionId(n);
|
||||
btRigidBody* rb = btRigidBody::upcast(colObj);
|
||||
int offs = ARRAY_SIZE_X * ARRAY_SIZE_Z;
|
||||
int indx = n;
|
||||
int ky = indx / offs;
|
||||
indx -= ky * offs;
|
||||
int kx = indx / ARRAY_SIZE_Z;
|
||||
indx -= kx * ARRAY_SIZE_Z;
|
||||
int kz = indx;
|
||||
startTransform.setOrigin(SCALING*btVector3(
|
||||
2.0*SCALING*kx + start_x,
|
||||
2.0*SCALING*ky + start_y,
|
||||
2.0*SCALING*kz + start_z));
|
||||
rb->setCenterOfMassTransform(startTransform);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BasicDemo::exitPhysics()
|
||||
{
|
||||
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
int i;
|
||||
for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject( obj );
|
||||
delete obj;
|
||||
}
|
||||
|
||||
//delete collision shapes
|
||||
for (int j=0;j<m_collisionShapes.size();j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
|
||||
delete m_solver;
|
||||
|
||||
delete m_broadphase;
|
||||
|
||||
delete m_dispatcher;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BasicDemo::keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
(void)x;
|
||||
(void)y;
|
||||
switch (key)
|
||||
{
|
||||
case 'q' :
|
||||
exitPhysics();
|
||||
exit(0);
|
||||
break;
|
||||
case 'c' :
|
||||
{
|
||||
gbDrawBatches = !gbDrawBatches;
|
||||
break;
|
||||
}
|
||||
case 'b' :
|
||||
{
|
||||
gSelectedBatch++;
|
||||
gSelectedBatch %= (CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES + 1);
|
||||
break;
|
||||
}
|
||||
case 'u' :
|
||||
{
|
||||
btGpuDemoDynamicsWorld* pDdw = (btGpuDemoDynamicsWorld*)m_dynamicsWorld;
|
||||
gUseCPUSolver = !gUseCPUSolver;
|
||||
pDdw->setUseCPUSolver(gUseCPUSolver);
|
||||
break;
|
||||
}
|
||||
default :
|
||||
{
|
||||
DemoApplication::keyboardCallback(key, x, y);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(key == ' ')
|
||||
{
|
||||
#if USE_CUDA_DEMO_PAIR_CASHE
|
||||
((btCudaDemoPairCache*)gPairCache)->reset();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define BATCH_NUM_COLORS 12
|
||||
|
||||
const float cBatchColorTab[BATCH_NUM_COLORS * 3] =
|
||||
{
|
||||
1.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f,
|
||||
0.f, 0.f, 1.f,
|
||||
1.f, 1.f, 0.f,
|
||||
0.f, 1.f, 1.f,
|
||||
1.f, 0.f, 1.f,
|
||||
1.f, .5f, 0.f,
|
||||
.5f, 1.f, 0.f,
|
||||
0.f, 1.f, .5f,
|
||||
0.f, .5f, 1.f,
|
||||
.5f, 0.f, 1.f,
|
||||
1.f, 0.f, .5f
|
||||
};
|
||||
|
||||
|
||||
void BasicDemo::DrawConstraintInfo()
|
||||
{
|
||||
int fontW = 10; // hack, could be changed
|
||||
int fontH = 14; // hack, could be changed
|
||||
char buf[32];
|
||||
float xOffs;
|
||||
float yOffs = fontH * 2;
|
||||
glDisable(GL_LIGHTING);
|
||||
glColor3f(1, 1, 1);
|
||||
sprintf(buf,"solver on %s", gUseCPUSolver ? "CPU" : "CUDA");
|
||||
xOffs = m_glutScreenWidth - (strlen(buf) + 1) * fontW;
|
||||
GLDebugDrawString(xOffs, yOffs,buf);
|
||||
yOffs += fontH;
|
||||
btGpuDemoDynamicsWorld* cddw = (btGpuDemoDynamicsWorld*)m_dynamicsWorld;
|
||||
for(int i = 0; i < CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES; i++)
|
||||
{
|
||||
const float* pCol = cBatchColorTab + i * 3;
|
||||
glColor3f(pCol[0], pCol[1], pCol[2]);
|
||||
sprintf(buf,"%2d : %5d", i, cddw->m_numInBatches[i]);
|
||||
xOffs = m_glutScreenWidth - (strlen(buf) + 1) * fontW;
|
||||
GLDebugDrawString(xOffs, yOffs,buf);
|
||||
yOffs += fontH;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BasicDemo::renderme()
|
||||
{
|
||||
renderscene(0);
|
||||
if(gbDrawBatches)
|
||||
{
|
||||
((btGpuDemoDynamicsWorld*)m_dynamicsWorld)->debugDrawConstraints(gSelectedBatch, cBatchColorTab);
|
||||
}
|
||||
|
||||
// if (0)
|
||||
if ((m_debugMode & btIDebugDraw::DBG_NoHelpText)==0)
|
||||
{
|
||||
setOrthographicProjection();
|
||||
int xOffset = 10.f;
|
||||
int yStart = 20.f;
|
||||
int yIncr = 20.f;
|
||||
showProfileInfo(xOffset, yStart, yIncr);
|
||||
DrawConstraintInfo();
|
||||
outputDebugInfo(xOffset, yStart, yIncr);
|
||||
resetPerspectiveProjection();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern int gNumClampedCcdMotions;
|
||||
#define SHOW_NUM_DEEP_PENETRATIONS 1
|
||||
#ifdef SHOW_NUM_DEEP_PENETRATIONS
|
||||
extern int gNumDeepPenetrationChecks;
|
||||
extern int gNumSplitImpulseRecoveries;
|
||||
extern int gNumGjkChecks;
|
||||
extern int gNumAlignedAllocs;
|
||||
extern int gNumAlignedFree;
|
||||
extern int gTotalBytesAlignedAllocs;
|
||||
#endif //
|
||||
|
||||
|
||||
void BasicDemo::outputDebugInfo(int & xOffset,int & yStart, int yIncr)
|
||||
{
|
||||
char buf[124];
|
||||
glDisable(GL_LIGHTING);
|
||||
glColor3f(0, 0, 0);
|
||||
|
||||
sprintf(buf,"mouse move+buttons to interact");
|
||||
GLDebugDrawString(xOffset,yStart,buf);
|
||||
yStart += yIncr;
|
||||
|
||||
|
||||
sprintf(buf,"space to reset");
|
||||
GLDebugDrawString(xOffset,yStart,buf);
|
||||
yStart += yIncr;
|
||||
|
||||
|
||||
sprintf(buf,"cursor keys and z,x to navigate");
|
||||
GLDebugDrawString(xOffset,yStart,buf);
|
||||
yStart += yIncr;
|
||||
|
||||
|
||||
sprintf(buf,"i to toggle simulation, s single step");
|
||||
GLDebugDrawString(xOffset,yStart,buf);
|
||||
yStart += yIncr;
|
||||
|
||||
|
||||
sprintf(buf,"q to quit");
|
||||
GLDebugDrawString(xOffset,yStart,buf);
|
||||
yStart += yIncr;
|
||||
|
||||
|
||||
sprintf(buf,"h to toggle help text");
|
||||
GLDebugDrawString(xOffset,yStart,buf);
|
||||
yStart += yIncr;
|
||||
|
||||
|
||||
sprintf(buf,"p to toggle profiling (+results to file)");
|
||||
GLDebugDrawString(xOffset,yStart,buf);
|
||||
yStart += yIncr;
|
||||
|
||||
|
||||
sprintf(buf,"c to toggle constraint drawing");
|
||||
GLDebugDrawString(xOffset,yStart,buf);
|
||||
yStart += yIncr;
|
||||
|
||||
|
||||
sprintf(buf,"b to draw single constraint batch");
|
||||
GLDebugDrawString(xOffset,yStart,buf);
|
||||
yStart += yIncr;
|
||||
|
||||
|
||||
sprintf(buf,"u to toggle between CPU and CUDA solvers");
|
||||
GLDebugDrawString(xOffset,yStart,buf);
|
||||
yStart += yIncr;
|
||||
|
||||
|
||||
sprintf(buf,"d to toggle between different batch builders");
|
||||
GLDebugDrawString(xOffset,yStart,buf);
|
||||
yStart += yIncr;
|
||||
|
||||
if (getDynamicsWorld())
|
||||
{
|
||||
|
||||
sprintf(buf,"# objects = %d",getDynamicsWorld()->getNumCollisionObjects());
|
||||
GLDebugDrawString(xOffset,yStart,buf);
|
||||
yStart += yIncr;
|
||||
|
||||
sprintf(buf,"# pairs = %d",getDynamicsWorld()->getBroadphase()->getOverlappingPairCache()->getNumOverlappingPairs());
|
||||
GLDebugDrawString(xOffset,yStart,buf);
|
||||
yStart += yIncr;
|
||||
}
|
||||
} // BasicDemo::outputDebugInfo()
|
||||
96
Demos/Gpu2dDemo/BasicDemo.h
Normal file
96
Demos/Gpu2dDemo/BasicDemo.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#ifndef BASIC_DEMO_H
|
||||
#define BASIC_DEMO_H
|
||||
|
||||
#include "DemoApplication.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
|
||||
|
||||
|
||||
#ifdef BT_USE_CUDA
|
||||
#include "btCudaDemoPairCache.h"
|
||||
#include <vector_types.h>
|
||||
#endif //BT_USE_CUDA
|
||||
|
||||
class btBroadphaseInterface;
|
||||
class btCollisionShape;
|
||||
class btOverlappingPairCache;
|
||||
class btCollisionDispatcher;
|
||||
class btConstraintSolver;
|
||||
struct btCollisionAlgorithmCreateFunc;
|
||||
class btDefaultCollisionConfiguration;
|
||||
#include "GlutDemoApplication.h"
|
||||
|
||||
///BasicDemo is good starting point for learning the code base and porting.
|
||||
class BasicDemo : public GlutDemoApplication
|
||||
{
|
||||
|
||||
//keep the collision shapes, for deletion/cleanup
|
||||
btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
|
||||
|
||||
btBroadphaseInterface* m_broadphase;
|
||||
|
||||
btCollisionDispatcher* m_dispatcher;
|
||||
|
||||
btConstraintSolver* m_solver;
|
||||
|
||||
btDefaultCollisionConfiguration* m_collisionConfiguration;
|
||||
|
||||
int m_mouseButtons;
|
||||
int m_mouseOldX;
|
||||
int m_mouseOldY;
|
||||
|
||||
public:
|
||||
|
||||
BasicDemo()
|
||||
{
|
||||
}
|
||||
virtual ~BasicDemo()
|
||||
{
|
||||
exitPhysics();
|
||||
}
|
||||
void initPhysics();
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
virtual void clientMoveAndDisplay();
|
||||
|
||||
virtual void displayCallback();
|
||||
|
||||
virtual void keyboardCallback(unsigned char key, int x, int y);
|
||||
|
||||
virtual void clientResetScene();
|
||||
|
||||
static DemoApplication* Create()
|
||||
{
|
||||
BasicDemo* demo = new BasicDemo;
|
||||
demo->myinit();
|
||||
demo->initPhysics();
|
||||
demo->m_mouseButtons = 0;
|
||||
demo->m_mouseOldX = 0;
|
||||
demo->m_mouseOldY = 0;
|
||||
return demo;
|
||||
}
|
||||
|
||||
void DrawConstraintInfo();
|
||||
void outputDebugInfo(int & xOffset,int & yStart, int yIncr);
|
||||
virtual void renderme();
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //BASIC_DEMO_H
|
||||
|
||||
26
Demos/Gpu2dDemo/CMakeLists.txt
Normal file
26
Demos/Gpu2dDemo/CMakeLists.txt
Normal file
@@ -0,0 +1,26 @@
|
||||
# This is basically the overall name of the project in Visual Studio this is the name of the Solution File
|
||||
|
||||
|
||||
# For every executable you have with a main method you should have an add_executable line below.
|
||||
# For every add executable line you should list every .cpp and .h file you have associated with that executable.
|
||||
|
||||
|
||||
# This is the variable for Windows. I use this to define the root of my directory structure.
|
||||
SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut)
|
||||
|
||||
# You shouldn't have to modify anything below this line
|
||||
########################################################
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL }
|
||||
)
|
||||
|
||||
LINK_LIBRARIES(
|
||||
OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(AppBasicDemo
|
||||
main.cpp
|
||||
BasicDemo.cpp
|
||||
)
|
||||
|
||||
3
Demos/Gpu2dDemo/Jamfile
Normal file
3
Demos/Gpu2dDemo/Jamfile
Normal file
@@ -0,0 +1,3 @@
|
||||
SubDir TOP Demos BasicDemo ;
|
||||
|
||||
BulletDemo BasicDemo : [ Wildcard *.h *.cpp ] ;
|
||||
5
Demos/Gpu2dDemo/Makefile.am
Normal file
5
Demos/Gpu2dDemo/Makefile.am
Normal file
@@ -0,0 +1,5 @@
|
||||
noinst_PROGRAMS=BasicDemo
|
||||
|
||||
BasicDemo_SOURCES=BasicDemo.cpp BasicDemo.h main.cpp
|
||||
BasicDemo_CXXFLAGS=-I@top_builddir@/src -I@top_builddir@/Demos/OpenGL $(CXXFLAGS)
|
||||
BasicDemo_LDADD=-L../OpenGL -lbulletopenglsupport -L../../src -lbulletdynamics -lbulletcollision -lbulletmath @opengl_LIBS@
|
||||
33
Demos/Gpu2dDemo/btGpuDemo2dCpuFunc.cpp
Normal file
33
Demos/Gpu2dDemo/btGpuDemo2dCpuFunc.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
|
||||
Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
#include "LinearMath/btScalar.h"
|
||||
|
||||
#include "btGpuDemo2dSharedTypes.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#include "BulletMultiThreaded/btGpuDefines.h"
|
||||
#include "BulletMultiThreaded/btGpuUtilsSharedDefs.h"
|
||||
#include "btGpuDemo2dSharedCode.h"
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------
|
||||
46
Demos/Gpu2dDemo/btGpuDemo2dCudaFunc.cu
Normal file
46
Demos/Gpu2dDemo/btGpuDemo2dCudaFunc.cu
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Impulse based Rigid body simulation using CUDA
|
||||
Copyright (c) 2007 Takahiro Harada http://www.iii.u-tokyo.ac.jp/~takahiroharada/projects/impulseCUDA.html
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <string.h>
|
||||
|
||||
#include "../../Extras/CUDA/cutil_math.h"
|
||||
#include "math_constants.h"
|
||||
|
||||
#include <vector_types.h>
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#include "../../Extras/CUDA/btCudaDefines.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#include "../../src/BulletMultiThreaded/btGpuUtilsSharedDefs.h"
|
||||
#include "btGpuDemo2dSharedTypes.h"
|
||||
#include "btGpuDemo2dSharedDefs.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
texture<float4, 1, cudaReadModeElementType> posTex;
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#include "btGpuDemo2dSharedCode.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
472
Demos/Gpu2dDemo/btGpuDemo2dSharedCode.h
Normal file
472
Demos/Gpu2dDemo/btGpuDemo2dSharedCode.h
Normal file
@@ -0,0 +1,472 @@
|
||||
/*
|
||||
Impulse based Rigid body simulation using CUDA
|
||||
Copyright (c) 2007 Takahiro Harada http://www.iii.u-tokyo.ac.jp/~takahiroharada/projects/impulseCUDA.html
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#define USE_FRICTION 1
|
||||
#define FRICTION_BOX_GROUND_FACT 0.05f
|
||||
#define FRICTION_BOX_BOX_FACT 0.05f
|
||||
#define USE_CENTERS 1
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//---------- C o n s t r a i n t s o l v e r d e m o ----------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#define MAX_VTX_PER_OBJ 8
|
||||
|
||||
/*
|
||||
BT_GPU___device__ void kill_me()
|
||||
{
|
||||
char* badPtr = (char*)0xFFFFFFFF;
|
||||
*badPtr = 10;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
BT_GPU___global__ void clearAccumulationOfLambdaDtD(float* lambdaDtBox, int numConstraints, int numContPoints)
|
||||
{
|
||||
int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
|
||||
if(index < numConstraints)
|
||||
{
|
||||
for(int i=0; i < numContPoints; i++)
|
||||
lambdaDtBox[numContPoints * index + i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define SPHERE_FACT 1.0f
|
||||
|
||||
BT_GPU___device__ void testSphSph(float3 aPos, float3 bPos, float radA, float radB, float4* pOut)
|
||||
{
|
||||
float3 del = bPos - aPos;
|
||||
float dist = BT_GPU_dot(del, del);
|
||||
dist = sqrtf(dist);
|
||||
float maxD = radA + radB;
|
||||
if(dist > maxD)
|
||||
{
|
||||
return;
|
||||
}
|
||||
float penetration = (radA + radB - dist) * SPHERE_FACT;
|
||||
// float penetration = (dist - radA - radB) * SPHERE_FACT;
|
||||
float3 normal;
|
||||
if(dist > 0.f)
|
||||
{
|
||||
float fact = -1.0f/dist;
|
||||
// float fact = 1.0f/dist;
|
||||
normal = del * fact;
|
||||
}
|
||||
else
|
||||
{
|
||||
normal = BT_GPU_make_float3(1.f, 0.f, 0.f);
|
||||
}
|
||||
// float3 contact = (bPos + aPos + normal * (radB - radA)) * 0.5f;
|
||||
float3 contact = aPos - normal * radA;
|
||||
// now add point
|
||||
int numPoints = 0;
|
||||
for(int i = 0; i < MAX_VTX_PER_OBJ; i++)
|
||||
{
|
||||
if(pOut[i*2].w >= 0.f)
|
||||
{
|
||||
numPoints++;
|
||||
}
|
||||
}
|
||||
if(numPoints < MAX_VTX_PER_OBJ)
|
||||
{
|
||||
pOut[numPoints * 2] = BT_GPU_make_float42(contact, penetration);
|
||||
pOut[numPoints * 2 + 1] = BT_GPU_make_float42(normal, 0.f);
|
||||
}
|
||||
} // testSphSph()
|
||||
|
||||
|
||||
|
||||
BT_GPU___global__ void setConstraintDataD(int2 *constraints,
|
||||
int numConstraints,
|
||||
float4 *pos,
|
||||
float *rotation,
|
||||
char* shapes,
|
||||
int2* shapeIds,
|
||||
btCudaPartProps pProp,
|
||||
float4 *contact)
|
||||
{
|
||||
int idx = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
|
||||
int aId,bId;
|
||||
float3 aPos,bPos;
|
||||
// float positionConstraint;
|
||||
// float3 normal;
|
||||
float aRot,bRot;
|
||||
float sideLength2 = pProp.m_diameter*0.5f/sqrt(2.0f);
|
||||
|
||||
if(idx < numConstraints)
|
||||
{
|
||||
aId=constraints[idx].x;
|
||||
bId=constraints[idx].y;
|
||||
|
||||
aPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,aId));
|
||||
bPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,bId));
|
||||
aRot= rotation[aId];
|
||||
bRot= rotation[bId];
|
||||
float cosA = cosf(aRot);
|
||||
float sinA = sinf(aRot);
|
||||
float cosB = cosf(bRot);
|
||||
float sinB = sinf(bRot);
|
||||
float4* shapeA = (float4*)(shapes + shapeIds[aId].x);
|
||||
int numSphA = shapeIds[aId].y;
|
||||
float4* shapeB = (float4*)(shapes + shapeIds[bId].x);
|
||||
int numSphB = shapeIds[bId].y;
|
||||
int i, j;
|
||||
float3 ai = BT_GPU_make_float3(cosA, sinA, 0.f);
|
||||
float3 aj = BT_GPU_make_float3(-sinA, cosA, 0.f);
|
||||
float3 bi = BT_GPU_make_float3(cosB, sinB, 0.f);
|
||||
float3 bj = BT_GPU_make_float3(-sinB, cosB, 0.f);
|
||||
float4* pOut = contact + idx * MAX_VTX_PER_OBJ * 2;
|
||||
for(i = 0; i < MAX_VTX_PER_OBJ; i++)
|
||||
{
|
||||
pOut[i * 2].w = -1.f;
|
||||
pOut[i * 2 + 1].w = 0.f;
|
||||
}
|
||||
for(i = 0; i < numSphA; i++)
|
||||
{
|
||||
float3 va = aPos;
|
||||
va += ai * shapeA[i].x;
|
||||
va += aj * shapeA[i].y;
|
||||
float radA = shapeA[i].w;
|
||||
for(j = 0; j < numSphB; j++)
|
||||
{
|
||||
float3 vb = bPos;
|
||||
vb += bi * shapeB[j].x;
|
||||
vb += bj * shapeB[j].y;
|
||||
float radB = shapeB[j].w;
|
||||
testSphSph(va, vb, radA, radB, pOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BT_GPU___device__ float computeImpulse1(float3 rVel,
|
||||
float positionConstraint,
|
||||
float3 cNormal,
|
||||
float dt)
|
||||
{
|
||||
const float collisionConstant = 0.1f;
|
||||
const float baumgarteConstant = 0.5f;
|
||||
const float penetrationError = 0.02f;
|
||||
|
||||
float lambdaDt=0;
|
||||
float3 impulse=BT_GPU_make_float3(0.f,0.f,0.f);
|
||||
|
||||
if(positionConstraint > 0)
|
||||
return lambdaDt;
|
||||
|
||||
positionConstraint = min(0.0f,positionConstraint+penetrationError);
|
||||
|
||||
lambdaDt = -(BT_GPU_dot(cNormal,rVel)*(1+collisionConstant));
|
||||
lambdaDt -= (baumgarteConstant/dt*positionConstraint);
|
||||
|
||||
return lambdaDt;
|
||||
}
|
||||
|
||||
|
||||
BT_GPU___global__ void collisionWithWallBoxD(float4 *pos,
|
||||
float4 *vel,
|
||||
float *rotation,
|
||||
float *angVel,
|
||||
char* shapes,
|
||||
int2* shapeIds,
|
||||
btCudaPartProps pProp,
|
||||
btCudaBoxProps gProp,
|
||||
int nParticles,
|
||||
float dt)
|
||||
{
|
||||
int idx = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
|
||||
float3 aPos;
|
||||
float aRot;
|
||||
float positionConstraint;
|
||||
float3 impulse;
|
||||
|
||||
|
||||
if((idx > 0) && idx < nParticles)
|
||||
{
|
||||
aPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,idx));
|
||||
aRot=rotation[idx];
|
||||
float4* shape = (float4*)(shapes + shapeIds[idx].x);
|
||||
int numSph = shapeIds[idx].y;
|
||||
float cosA = cosf(aRot);
|
||||
float sinA = sinf(aRot);
|
||||
float3 ai = BT_GPU_make_float3(cosA, sinA, 0.f);
|
||||
float3 aj = BT_GPU_make_float3(-sinA, cosA, 0.f);
|
||||
|
||||
for(int iVtx=0;iVtx < numSph; iVtx++){
|
||||
float3 aVel = BT_GPU_make_float3(vel[idx].x, vel[idx].y, vel[idx].z);
|
||||
float aAngVel = angVel[idx];
|
||||
float3 rerVertex = ai * shape[iVtx].x;
|
||||
rerVertex += aj * shape[iVtx].y;
|
||||
float3 vPos = aPos + rerVertex;
|
||||
float rad = shape[iVtx].w;
|
||||
float3 vVel =aVel+BT_GPU_cross(BT_GPU_make_float3(0.0f,0.0f,aAngVel),rerVertex);
|
||||
float restitution=1.0;
|
||||
{
|
||||
positionConstraint =vPos.y - rad - gProp.minY;
|
||||
impulse =BT_GPU_make_float31(0.0f);
|
||||
|
||||
if(positionConstraint < 0){
|
||||
float3 groundNormal;
|
||||
groundNormal = BT_GPU_make_float3(0.0f,1.0f,0.0f);
|
||||
impulse =groundNormal*
|
||||
restitution * computeImpulse1(vVel,positionConstraint,
|
||||
groundNormal,
|
||||
dt);
|
||||
#if USE_FRICTION // only with ground for now
|
||||
float3 lat_vel = vVel - groundNormal * BT_GPU_dot(groundNormal,vVel);
|
||||
float lat_vel_len = BT_GPU_dot(lat_vel, lat_vel);
|
||||
if (lat_vel_len > 0)
|
||||
{
|
||||
lat_vel_len = sqrtf(lat_vel_len);
|
||||
lat_vel *= 1.f/lat_vel_len;
|
||||
impulse -= lat_vel * BT_GPU_dot(lat_vel, vVel) * FRICTION_BOX_GROUND_FACT;
|
||||
}
|
||||
#endif //USE_FRICTION
|
||||
vel[idx] += BT_GPU_make_float42(impulse,0.0f);
|
||||
angVel[idx] += BT_GPU_cross(rerVertex,impulse).z;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
positionConstraint =vPos.x - rad - gProp.minX;
|
||||
impulse =BT_GPU_make_float31(0.0f);
|
||||
|
||||
if(positionConstraint < 0){
|
||||
impulse =BT_GPU_make_float3(1.0f,0.0f,0.0f)*
|
||||
computeImpulse1(vVel,positionConstraint,
|
||||
BT_GPU_make_float3(1.0f,0.0f,0.0f),
|
||||
dt);
|
||||
|
||||
vel[idx] += BT_GPU_make_float42(impulse,0.0f);
|
||||
angVel[idx] += BT_GPU_cross(rerVertex,impulse).z;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
positionConstraint = gProp.maxX - vPos.x - rad;
|
||||
impulse =BT_GPU_make_float31(0.0f);
|
||||
|
||||
if(positionConstraint < 0){
|
||||
impulse =BT_GPU_make_float3(-1.0f,0.0f,0.0f)*
|
||||
computeImpulse1(vVel,positionConstraint,
|
||||
BT_GPU_make_float3(-1.0f,0.0f,0.0f),
|
||||
dt);
|
||||
|
||||
vel[idx] += BT_GPU_make_float42(impulse,0.0f);
|
||||
angVel[idx] += BT_GPU_cross(rerVertex,impulse).z;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BT_GPU___device__ void collisionResolutionBox( int constrId,
|
||||
int2* constraints,
|
||||
float4 *pos,
|
||||
float4 *vel,
|
||||
float *rotation,
|
||||
float *angularVel,
|
||||
float *lambdaDtBox,
|
||||
float4* contact,
|
||||
btCudaPartProps pProp,
|
||||
float dt)
|
||||
{
|
||||
#if 1
|
||||
float3 relVel;
|
||||
float3 impulse;
|
||||
float lambdaDt;
|
||||
float positionConstraint;
|
||||
int aId=constraints[constrId].x;
|
||||
int bId=constraints[constrId].y;
|
||||
float3 aPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,aId));
|
||||
float3 bPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,bId));
|
||||
float aRot=rotation[aId];
|
||||
float bRot=rotation[bId];
|
||||
float3 aVel=BT_GPU_make_float34(vel[aId]);
|
||||
float3 bVel=BT_GPU_make_float34(vel[bId]);
|
||||
float aAngVel=angularVel[aId];
|
||||
float bAngVel=angularVel[bId];
|
||||
float4* pCont = contact + constrId * MAX_VTX_PER_OBJ * 2;
|
||||
// test Vertices in A to Box B
|
||||
for(int iVtx=0;iVtx<MAX_VTX_PER_OBJ;iVtx++){
|
||||
float3 contactPoint = BT_GPU_make_float34(pCont[iVtx * 2]);
|
||||
contactPoint = contactPoint - aPos;
|
||||
positionConstraint = pCont[iVtx * 2].w;
|
||||
if(positionConstraint >= 0)
|
||||
{
|
||||
float3 contactNormal = BT_GPU_make_float34(pCont[iVtx * 2 + 1]);
|
||||
relVel=(aVel+BT_GPU_cross(BT_GPU_make_float3(0.0f,0.0f,aAngVel),
|
||||
contactPoint))
|
||||
-(bVel+BT_GPU_cross(BT_GPU_make_float3(0.0f,0.0f,bAngVel),
|
||||
contactPoint+aPos-bPos));
|
||||
|
||||
lambdaDt= computeImpulse1(relVel,-positionConstraint,
|
||||
contactNormal,dt);
|
||||
|
||||
{
|
||||
float rLambdaDt=lambdaDtBox[(MAX_VTX_PER_OBJ)*(2*constrId)+iVtx];
|
||||
float pLambdaDt=rLambdaDt;
|
||||
rLambdaDt=max(pLambdaDt+lambdaDt,0.0f);
|
||||
lambdaDt=rLambdaDt-pLambdaDt;
|
||||
lambdaDtBox[(MAX_VTX_PER_OBJ)*(2*constrId)+iVtx]=rLambdaDt;
|
||||
}
|
||||
impulse= contactNormal*lambdaDt*0.5;
|
||||
#if USE_FRICTION
|
||||
if(pCont[iVtx * 2 + 1].w <= 0)
|
||||
{
|
||||
float3 lat_vel = relVel - contactNormal * BT_GPU_dot(contactNormal, relVel);
|
||||
float lat_vel_len = BT_GPU_dot(lat_vel, lat_vel);
|
||||
if (lat_vel_len > 0)
|
||||
{
|
||||
lat_vel_len = sqrtf(lat_vel_len);
|
||||
lat_vel *= 1.f/lat_vel_len;
|
||||
impulse -= lat_vel * BT_GPU_dot(lat_vel , relVel) * FRICTION_BOX_BOX_FACT;
|
||||
}
|
||||
}
|
||||
#endif //USE_FRICTION
|
||||
if(aId)
|
||||
{
|
||||
aVel+= impulse;
|
||||
aAngVel+= BT_GPU_cross(contactPoint, impulse).z;
|
||||
}
|
||||
if(bId)
|
||||
{
|
||||
bVel-= impulse;
|
||||
bAngVel-= BT_GPU_cross(contactPoint+aPos-bPos, impulse).z;
|
||||
}
|
||||
}
|
||||
}
|
||||
vel[aId]=BT_GPU_make_float42(aVel,0.0f);
|
||||
vel[bId]=BT_GPU_make_float42(bVel,0.0f);
|
||||
angularVel[aId]=aAngVel;
|
||||
angularVel[bId]=bAngVel;
|
||||
#endif
|
||||
}
|
||||
|
||||
BT_GPU___global__ void collisionBatchResolutionBoxD(int2 *constraints,
|
||||
int *batch,
|
||||
int nConstraints,
|
||||
float4 *pos,
|
||||
float4 *vel,
|
||||
float *rotation,
|
||||
float *angularVel,
|
||||
float *lambdaDtBox,
|
||||
float4* contact,
|
||||
btCudaPartProps pProp,
|
||||
int iBatch,
|
||||
float dt)
|
||||
{
|
||||
int k_idx = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
|
||||
if(k_idx < nConstraints)
|
||||
{
|
||||
int idx = batch[k_idx];
|
||||
collisionResolutionBox( idx, constraints, pos, vel, rotation, angularVel, lambdaDtBox,
|
||||
contact, pProp, dt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
void BT_GPU_PREF(clearAccumulationOfLambdaDt(float* lambdaDtBox, int numConstraints, int numContPoints))
|
||||
{
|
||||
if(!numConstraints)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int numThreads, numBlocks;
|
||||
BT_GPU_PREF(computeGridSize)(numConstraints, 256, numBlocks, numThreads);
|
||||
// execute the kernel
|
||||
BT_GPU_EXECKERNEL(numBlocks, numThreads, clearAccumulationOfLambdaDtD, (lambdaDtBox, numConstraints, numContPoints));
|
||||
// check if kernel invocation generated an error
|
||||
BT_GPU_CHECK_ERROR("clearAccumulationOfLambdaDtD kernel execution failed");
|
||||
|
||||
}
|
||||
|
||||
void BT_GPU_PREF(setConstraintData(void* constraints,int numConstraints,int numObjs,void* pos,float *rotation,char* shapes,void* shapeIds,btCudaPartProps pProp,void* contact))
|
||||
{
|
||||
if(!numConstraints)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int2* pConst = (int2*)constraints;
|
||||
float4* pPos = (float4*)pos;
|
||||
float4* pCont = (float4*)contact;
|
||||
int2* pShapeIds = (int2*)shapeIds;
|
||||
|
||||
BT_GPU_SAFE_CALL(BT_GPU_BindTexture(0, posTex, pPos, numObjs * sizeof(float4)));
|
||||
|
||||
int numThreads, numBlocks;
|
||||
BT_GPU_PREF(computeGridSize)(numConstraints, 256, numBlocks, numThreads);
|
||||
// execute the kernel
|
||||
BT_GPU_EXECKERNEL(numBlocks, numThreads, setConstraintDataD, (pConst,numConstraints,pPos,rotation,shapes,pShapeIds,pProp,pCont));
|
||||
BT_GPU_SAFE_CALL(BT_GPU_UnbindTexture(posTex));
|
||||
// check if kernel invocation generated an error
|
||||
BT_GPU_CHECK_ERROR("setConstraintDataD kernel execution failed");
|
||||
}
|
||||
|
||||
void BT_GPU_PREF(collisionWithWallBox(void* pos,void* vel,float *rotation,float *angVel,char* shapes,void* shapeIds,btCudaPartProps pProp, btCudaBoxProps gProp,int numObjs,float dt))
|
||||
{
|
||||
if(!numObjs)
|
||||
{
|
||||
return;
|
||||
}
|
||||
float4* pPos = (float4*)pos;
|
||||
float4* pVel = (float4*)vel;
|
||||
int2* pShapeIds = (int2*)shapeIds;
|
||||
BT_GPU_SAFE_CALL(BT_GPU_BindTexture(0, posTex, pPos, numObjs * sizeof(float4)));
|
||||
|
||||
int numThreads, numBlocks;
|
||||
BT_GPU_PREF(computeGridSize)(numObjs, 256, numBlocks, numThreads);
|
||||
// execute the kernel
|
||||
BT_GPU_EXECKERNEL(numBlocks, numThreads, collisionWithWallBoxD, (pPos,pVel,rotation,angVel,shapes, pShapeIds,pProp,gProp,numObjs,dt));
|
||||
|
||||
BT_GPU_SAFE_CALL(BT_GPU_UnbindTexture(posTex));
|
||||
// check if kernel invocation generated an error
|
||||
BT_GPU_CHECK_ERROR("collisionWithWallBoxD kernel execution failed");
|
||||
}
|
||||
|
||||
void BT_GPU_PREF(collisionBatchResolutionBox(void* constraints,int *batch,int numConstraints,int numObjs,void *pos,void *vel,float *rotation,float *angularVel,float *lambdaDtBox,void* contact,btCudaPartProps pProp,int iBatch,float dt))
|
||||
{
|
||||
if(!numConstraints)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int2* pConstr = (int2*)constraints;
|
||||
float4* pPos = (float4*)pos;
|
||||
float4* pVel = (float4*)vel;
|
||||
float4* pCont = (float4*)contact;
|
||||
int numThreads, numBlocks;
|
||||
BT_GPU_PREF(computeGridSize)(numConstraints, 128, numBlocks, numThreads);
|
||||
BT_GPU_SAFE_CALL(BT_GPU_BindTexture(0, posTex, pPos, numObjs * sizeof(float4)));
|
||||
// execute the kernel
|
||||
BT_GPU_EXECKERNEL(numBlocks, numThreads, collisionBatchResolutionBoxD, (pConstr,batch,numConstraints,pPos,pVel,rotation,angularVel,lambdaDtBox,pCont,pProp,iBatch,dt));
|
||||
// check if kernel invocation generated an error
|
||||
BT_GPU_CHECK_ERROR("collisionBatchResolutionBox2D kernel execution failed");
|
||||
BT_GPU_SAFE_CALL(BT_GPU_UnbindTexture(posTex));
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // extern "C"
|
||||
33
Demos/Gpu2dDemo/btGpuDemo2dSharedDefs.h
Normal file
33
Demos/Gpu2dDemo/btGpuDemo2dSharedDefs.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Impulse based Rigid body simulation using CUDA
|
||||
Copyright (c) 2007 Takahiro Harada http://www.iii.u-tokyo.ac.jp/~takahiroharada/projects/impulseCUDA.html
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//---------- C o n s t r a i n t s o l v e r d e m o ----------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
void BT_GPU_PREF(clearAccumulationOfLambdaDt(float* lambdaDtBox, int numConstraints, int numContPoints));
|
||||
void BT_GPU_PREF(setConstraintData(void* constraints,int numConstraints,int numObjs,void* pos,float *rotation,char* shapes,void* shapeIds,btCudaPartProps pProp,void* oContact));
|
||||
void BT_GPU_PREF(collisionWithWallBox(void* pos,void* vel,float *rotation,float *angVel,char* shapes,void* shapeIds,btCudaPartProps pProp, btCudaBoxProps gProp,int numObjs,float dt));
|
||||
void BT_GPU_PREF(collisionBatchResolutionBox(void* constraints,int *batch,int numConstraints,int numObjs,void *pos,void *vel,float *rotation,float *angularVel,float *lambdaDtBox,void* contact,btCudaPartProps pProp,int iBatch,float dt));
|
||||
|
||||
} // extern "C"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
39
Demos/Gpu2dDemo/btGpuDemo2dSharedTypes.h
Normal file
39
Demos/Gpu2dDemo/btGpuDemo2dSharedTypes.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Impulse based Rigid body simulation using CUDA
|
||||
Copyright (c) 2007 Takahiro Harada http://www.iii.u-tokyo.ac.jp/~takahiroharada/projects/impulseCUDA.html
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//---------- C o n s t r a i n t s o l v e r d e m o ----------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
struct btCudaPartProps
|
||||
{
|
||||
float m_mass;
|
||||
float m_diameter;
|
||||
float m_restCoeff;
|
||||
};
|
||||
|
||||
struct btCudaBoxProps
|
||||
{
|
||||
float minX;
|
||||
float maxX;
|
||||
float minY;
|
||||
float maxY;
|
||||
float minZ;
|
||||
float maxZ;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
503
Demos/Gpu2dDemo/btGpuDemoDynamicsWorld.cpp
Normal file
503
Demos/Gpu2dDemo/btGpuDemoDynamicsWorld.cpp
Normal file
@@ -0,0 +1,503 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#include "btGpuDemoDynamicsWorld.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
|
||||
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
|
||||
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
||||
#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
|
||||
#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
#include "GlutStuff.h"
|
||||
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
|
||||
#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#define BT_GPU_PREF(func) btCuda_##func
|
||||
|
||||
#include "../../src/BulletMultiThreaded/btGpuUtilsSharedDefs.h"
|
||||
#include "btGpuDemo2dSharedDefs.h"
|
||||
#undef BT_GPU_PREF
|
||||
|
||||
#define BT_GPU_PREF(func) btGpu_##func
|
||||
#include "btGpuDemo2dSharedDefs.h"
|
||||
#undef BT_GPU_PREF
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
btGpuDemoDynamicsWorld* gpCudaDemoDynamicsWorld = NULL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void btGpuDemoDynamicsWorld::grabNonContactConstraintData()
|
||||
{
|
||||
m_numNonContactConstraints = 0;
|
||||
int numNonContactConstraints = getNumConstraints();
|
||||
for(int i = 0; i < numNonContactConstraints; i++)
|
||||
{
|
||||
btTypedConstraint* ct = m_constraints[i];
|
||||
int ctype = ct->getConstraintType();
|
||||
switch(ctype)
|
||||
{
|
||||
case POINT2POINT_CONSTRAINT_TYPE :
|
||||
grabP2PConstraintData((btPoint2PointConstraint*)ct);
|
||||
break;
|
||||
default :
|
||||
// warning (not supported) here?
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // btGpuDemoDynamicsWorld::grabNonContactConstraintData()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void btGpuDemoDynamicsWorld::grabP2PConstraintData(btPoint2PointConstraint* ct)
|
||||
{
|
||||
btRigidBody& bodyA = ct->getRigidBodyA();
|
||||
btTransform trA = bodyA.getCenterOfMassTransform();
|
||||
btVector3 pivotA = trA.getBasis() * ct->getPivotInA();
|
||||
btRigidBody& bodyB = ct->getRigidBodyB();
|
||||
btTransform trB = bodyB.getCenterOfMassTransform();
|
||||
btVector3 pivotB = trB.getBasis() * ct->getPivotInB();
|
||||
btVector3 pivotA_W = pivotA + trA.getOrigin();
|
||||
btVector3 pivotB_W = pivotB + trB.getOrigin();
|
||||
btVector3 delta = pivotB_W - pivotA_W;
|
||||
int idA = bodyA.getCompanionId();
|
||||
int idB = bodyB.getCompanionId();
|
||||
m_hIds[m_totalNumConstraints].x = idA;
|
||||
m_hIds[m_totalNumConstraints].y = (idB > 0) ? idB : 0;
|
||||
btVector3* pConstrData = (btVector3*)(m_hContact + m_totalNumConstraints * 2 * m_maxVtxPerObj);
|
||||
for(int k = 0; k < 2; k++)
|
||||
{
|
||||
btScalar penetration = delta[k];
|
||||
btScalar sign = (penetration < 0) ? btScalar(-1.f) : btScalar(1.f);
|
||||
btVector3 normal = btVector3(0., 0., 0.);
|
||||
normal[k] = sign;
|
||||
penetration *= sign;
|
||||
pConstrData[0] = pivotA_W;
|
||||
pConstrData[0][3] = penetration;
|
||||
pConstrData[1] = normal;
|
||||
pConstrData[1][3] = btScalar(1.f);
|
||||
pConstrData += 2;
|
||||
}
|
||||
for(int n = 2; n < m_maxVtxPerObj; n++)
|
||||
{
|
||||
pConstrData[0][3] = -1.f;
|
||||
pConstrData += 2;
|
||||
}
|
||||
m_totalNumConstraints++;
|
||||
m_numNonContactConstraints++;
|
||||
} // btGpuDemoDynamicsWorld::grabP2PConstraintData()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void btGpuDemoDynamicsWorld::grabData()
|
||||
{
|
||||
BT_PROFILE("grab data");
|
||||
m_numObj = getNumCollisionObjects();
|
||||
m_hPos[0].x = m_hPos[0].y = m_hPos[0].z = m_hPos[0].w = 0.f;
|
||||
m_hRot[0] = 0.f;
|
||||
m_hVel[0].x = m_hVel[0].y = m_hVel[0].z = m_hVel[0].w = 0.f;
|
||||
m_hAngVel[0] = 0.f;
|
||||
for(int i = 0; i < m_numObj; i++)
|
||||
{
|
||||
btCollisionObject* colObj = m_collisionObjects[i];
|
||||
btRigidBody* rb = btRigidBody::upcast(colObj);
|
||||
btVector3 v;
|
||||
v = rb->getCenterOfMassPosition();
|
||||
m_hPos[i+1] = *((float4*)&v);
|
||||
const btTransform& tr = rb->getCenterOfMassTransform();
|
||||
v = tr.getBasis().getColumn(0);
|
||||
float rot = btAtan2(v[1], v[0]);
|
||||
m_hRot[i+1] = rot;
|
||||
v = rb->getLinearVelocity();
|
||||
m_hVel[i+1] = *((float4*)&v);
|
||||
v = rb->getAngularVelocity();
|
||||
m_hAngVel[i+1] = v[2];
|
||||
}
|
||||
grabNonContactConstraintData();
|
||||
} // btGpuDemoDynamicsWorld::grabGata()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void btGpuDemoDynamicsWorld::createBatches2()
|
||||
{
|
||||
BT_PROFILE("create batches");
|
||||
int sz = m_maxObjs * m_maxNeighbors;
|
||||
for(int idx = 0; idx < sz; idx++)
|
||||
{
|
||||
m_hBatchIds[idx] = -1;
|
||||
}
|
||||
for(int i = 0; i < m_totalNumConstraints; i++)
|
||||
{
|
||||
m_hConstraintUsed[i] = 0;
|
||||
}
|
||||
int curBatchId=0;
|
||||
int* pBatchIds = m_hBatchIds;
|
||||
for(int stage = 0; stage < m_maxBatches; stage++)
|
||||
{
|
||||
bool isLast = (stage == m_maxBatches-1);
|
||||
for(int j = 0; j < m_numObj + 1; j++)
|
||||
{
|
||||
m_hConstraintCounter[j] = 0;
|
||||
}
|
||||
int numInBatch = 0;
|
||||
for(int i = 0; i < m_totalNumConstraints; i++)
|
||||
{
|
||||
if(m_hConstraintUsed[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int2 ids = m_hIds[i];
|
||||
if(!isLast)
|
||||
{
|
||||
if((m_hConstraintCounter[ids.x] == 0) && (m_hConstraintCounter[ids.y] == 0))
|
||||
{
|
||||
m_hConstraintCounter[ids.x]=1;
|
||||
m_hConstraintCounter[ids.y]=1;
|
||||
pBatchIds[numInBatch]=i;
|
||||
numInBatch++;
|
||||
m_hConstraintUsed[i] = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pBatchIds[numInBatch]=i;
|
||||
numInBatch++;
|
||||
m_hConstraintUsed[i] = 1;
|
||||
}
|
||||
}
|
||||
m_numInBatches[stage] = numInBatch;
|
||||
pBatchIds += numInBatch;
|
||||
}
|
||||
} // btGpuDemoDynamicsWorld::createBatches2()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void btGpuDemoDynamicsWorld::writebackData()
|
||||
{
|
||||
BT_PROFILE("copy velocity into btRigidBody");
|
||||
for(int i = 0; i < m_numObj; i++)
|
||||
{
|
||||
btCollisionObject* colObj = m_collisionObjects[i];
|
||||
btRigidBody* rb = btRigidBody::upcast(colObj);
|
||||
btVector3 v;
|
||||
v = *((btVector3*)(m_hVel + i + 1));
|
||||
v[2] = 0.f;
|
||||
rb->setLinearVelocity(v);
|
||||
v[0] = btScalar(0.f);
|
||||
v[1] = btScalar(0.f);
|
||||
v[2] = m_hAngVel[i + 1];
|
||||
rb->setAngularVelocity(v);
|
||||
}
|
||||
} // btGpuDemoDynamicsWorld::writebackData()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void btGpuDemoDynamicsWorld::copyDataToGPU()
|
||||
{
|
||||
BT_PROFILE("copyDataToGPU");
|
||||
|
||||
#ifdef BT_USE_CUDA
|
||||
|
||||
btCuda_copyArrayToDevice(m_dIds, m_hIds, sizeof(int2) * m_totalNumConstraints);
|
||||
btCuda_copyArrayToDevice(m_dBatchIds, m_hBatchIds, sizeof(int) * m_totalNumConstraints);
|
||||
|
||||
if(m_numNonContactConstraints)
|
||||
{ // non-contact constraints are set up by CPU, so copy data to GPU
|
||||
int nonContConstrOffs = (m_totalNumConstraints - m_numNonContactConstraints) * 2 * m_maxVtxPerObj;
|
||||
int nonContConstrSize = 2 * m_numNonContactConstraints * m_maxVtxPerObj;
|
||||
btCuda_copyArrayToDevice(m_dContact + nonContConstrOffs, m_hContact + nonContConstrOffs, sizeof(float4) * nonContConstrSize);
|
||||
}
|
||||
|
||||
if(m_numSimStep & 1)
|
||||
{
|
||||
m_dcPos = m_dpPos;
|
||||
m_dcVel = m_dpVel;
|
||||
m_dcRot = m_dpRot;
|
||||
m_dcAngVel = m_dpAngVel;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dcPos = m_dPos;
|
||||
m_dcVel = m_dVel;
|
||||
m_dcRot = m_dRot;
|
||||
m_dcAngVel = m_dAngVel;
|
||||
}
|
||||
btCuda_copyArrayToDevice(m_dcPos, m_hPos, (m_numObj + 1) * sizeof(float4));
|
||||
btCuda_copyArrayToDevice(m_dcVel, m_hVel, (m_numObj + 1) * sizeof(float4));
|
||||
btCuda_copyArrayToDevice(m_dcRot, m_hRot, (m_numObj + 1) * sizeof(float));
|
||||
btCuda_copyArrayToDevice(m_dcAngVel, m_hAngVel, (m_numObj + 1) * sizeof(float));
|
||||
if(m_copyShapeDataToGPU)
|
||||
{
|
||||
btCuda_copyArrayToDevice(m_dShapeBuffer, m_hShapeBuffer, m_firstFreeShapeBufferOffset);
|
||||
btCuda_copyArrayToDevice(m_dShapeIds, m_hShapeIds, (m_numObj + 1) * sizeof(int2));
|
||||
m_copyShapeDataToGPU = false;
|
||||
}
|
||||
#endif //BT_USE_CUDA
|
||||
|
||||
} // btGpuDemoDynamicsWorld::copyDataToGPU()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void btGpuDemoDynamicsWorld::setConstraintData(btCudaPartProps& partProps)
|
||||
{
|
||||
BT_PROFILE("set constraint data");
|
||||
partProps.m_mass = 1.0f;
|
||||
partProps.m_diameter = m_objRad * 2.0f;
|
||||
partProps.m_restCoeff = 1.0f;
|
||||
#ifdef BT_USE_CUDA
|
||||
btCuda_clearAccumulationOfLambdaDt(m_dLambdaDtBox, m_totalNumConstraints, m_maxVtxPerObj * 2);
|
||||
btCuda_setConstraintData(m_dIds, m_totalNumConstraints - m_numNonContactConstraints, m_numObj + 1, m_dcPos, m_dcRot, m_dShapeBuffer, m_dShapeIds,
|
||||
partProps, m_dContact);
|
||||
#endif //BT_USE_CUDA
|
||||
|
||||
} // btGpuDemoDynamicsWorld::setConstraintData()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void btGpuDemoDynamicsWorld::copyDataFromGPU()
|
||||
{
|
||||
BT_PROFILE("copy velocity data from device");
|
||||
#ifdef BT_USE_CUDA
|
||||
btCuda_copyArrayFromDevice(m_hVel, m_dcVel, (m_numObj + 1) * sizeof(float4));
|
||||
btCuda_copyArrayFromDevice(m_hAngVel, m_dcAngVel, (m_numObj + 1) * sizeof(float));
|
||||
#endif //BT_USE_CUDA
|
||||
} // btGpuDemoDynamicsWorld::copyDataFromGPU()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void btGpuDemoDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
|
||||
{
|
||||
if(m_useCPUSolver)
|
||||
{
|
||||
solveConstraintsCPU2(solverInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
solveConstraints2(solverInfo);
|
||||
}
|
||||
m_totalNumConstraints = 0;
|
||||
} // btGpuDemoDynamicsWorld::solveConstraints()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void btGpuDemoDynamicsWorld::solveConstraints2(btContactSolverInfo& solverInfo)
|
||||
{
|
||||
#ifdef BT_USE_CUDA
|
||||
BT_PROFILE("solveConstraints");
|
||||
grabData();
|
||||
createBatches2();
|
||||
copyDataToGPU();
|
||||
|
||||
btCudaPartProps partProps;
|
||||
setConstraintData(partProps);
|
||||
|
||||
btCudaBoxProps boxProps;
|
||||
boxProps.minX = m_worldMin[0];
|
||||
boxProps.maxX = m_worldMax[0];
|
||||
boxProps.minY = m_worldMin[1];
|
||||
boxProps.maxY = m_worldMax[1];
|
||||
{
|
||||
BT_PROFILE("btCuda_collisionBatchResolutionBox");
|
||||
|
||||
int nIter=getSolverInfo().m_numIterations;
|
||||
btDispatcherInfo& dispatchInfo = getDispatchInfo();
|
||||
btScalar timeStep = dispatchInfo.m_timeStep;
|
||||
|
||||
for(int i=0;i<nIter;i++)
|
||||
{
|
||||
btCuda_collisionWithWallBox(m_dcPos, m_dcVel, m_dcRot, m_dcAngVel,m_dShapeBuffer, m_dShapeIds,
|
||||
partProps, boxProps, m_numObj + 1, timeStep);
|
||||
int* pBatchIds = m_dBatchIds;
|
||||
for(int iBatch=0;iBatch < m_maxBatches;iBatch++)
|
||||
{
|
||||
int numConstraints = m_numInBatches[iBatch];
|
||||
btCuda_collisionBatchResolutionBox( m_dIds, pBatchIds, numConstraints, m_numObj + 1,
|
||||
m_dcPos, m_dcVel,
|
||||
m_dcRot, m_dcAngVel,
|
||||
m_dLambdaDtBox,
|
||||
m_dContact,
|
||||
partProps, iBatch, timeStep);
|
||||
pBatchIds += numConstraints;
|
||||
}
|
||||
}
|
||||
}
|
||||
copyDataFromGPU();
|
||||
writebackData();
|
||||
m_numSimStep++;
|
||||
#endif //BT_USE_CUDA
|
||||
} // btGpuDemoDynamicsWorld::solveConstraints2()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void btGpuDemoDynamicsWorld::solveConstraintsCPU2(btContactSolverInfo& solverInfo)
|
||||
{
|
||||
BT_PROFILE("solveConstraints");
|
||||
grabData();
|
||||
createBatches2();
|
||||
btCudaPartProps partProps;
|
||||
{
|
||||
BT_PROFILE("set constraint data CPU");
|
||||
|
||||
partProps.m_mass = 1.0f;
|
||||
partProps.m_diameter = m_objRad * 2.0f;
|
||||
partProps.m_restCoeff = 1.0f;
|
||||
|
||||
btGpu_clearAccumulationOfLambdaDt(m_hLambdaDtBox, m_totalNumConstraints, m_maxVtxPerObj * 2);
|
||||
|
||||
btGpu_setConstraintData(m_hIds, m_totalNumConstraints - m_numNonContactConstraints, m_numObj + 1, m_hPos, m_hRot,m_hShapeBuffer, m_hShapeIds,
|
||||
partProps, m_hContact);
|
||||
}
|
||||
|
||||
btCudaBoxProps boxProps;
|
||||
boxProps.minX = m_worldMin[0];
|
||||
boxProps.maxX = m_worldMax[0];
|
||||
boxProps.minY = m_worldMin[1];
|
||||
boxProps.maxY = m_worldMax[1];
|
||||
|
||||
{
|
||||
BT_PROFILE("btCuda_collisionBatchResolutionBox CPU");
|
||||
|
||||
int nIter=getSolverInfo().m_numIterations;
|
||||
btDispatcherInfo& dispatchInfo = getDispatchInfo();
|
||||
btScalar timeStep = dispatchInfo.m_timeStep;
|
||||
|
||||
for(int i=0;i<nIter;i++){
|
||||
btGpu_collisionWithWallBox(m_hPos, m_hVel, m_hRot, m_hAngVel,m_hShapeBuffer, m_hShapeIds,
|
||||
partProps, boxProps, m_numObj + 1, timeStep);
|
||||
int* pBatchIds = m_hBatchIds;
|
||||
for(int iBatch=0;iBatch < m_maxBatches;iBatch++)
|
||||
{
|
||||
int numContConstraints = m_numInBatches[iBatch];
|
||||
if(!numContConstraints)
|
||||
{
|
||||
break;
|
||||
}
|
||||
btGpu_collisionBatchResolutionBox( m_hIds, pBatchIds, numContConstraints, m_numObj + 1,
|
||||
m_hPos, m_hVel,
|
||||
m_hRot, m_hAngVel,
|
||||
m_hLambdaDtBox,
|
||||
m_hContact,
|
||||
partProps, iBatch, timeStep);
|
||||
pBatchIds += numContConstraints;
|
||||
}
|
||||
}
|
||||
}
|
||||
writebackData();
|
||||
m_numSimStep++;
|
||||
} // btGpuDemoDynamicsWorld::solveConstraintsCPU2()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void btGpuDemoDynamicsWorld::debugDrawConstraints(int selectedBatch, const float* pColorTab)
|
||||
{
|
||||
int* pBatchIds = m_hBatchIds;
|
||||
for(int stage = 0; stage < m_maxBatches; stage++)
|
||||
{
|
||||
int numConstraints = m_numInBatches[stage];
|
||||
if(!numConstraints)
|
||||
{
|
||||
break;
|
||||
}
|
||||
const float* pCol = pColorTab + stage * 3;
|
||||
if(selectedBatch < CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES)
|
||||
{
|
||||
if(stage != selectedBatch)
|
||||
{
|
||||
pBatchIds += numConstraints;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
glColor3f(pCol[0], pCol[1], pCol[2]);
|
||||
glBegin(GL_LINES);
|
||||
for(int i = 0; i < numConstraints; i++)
|
||||
{
|
||||
int indx = pBatchIds[i];
|
||||
int idA = m_hIds[indx].x;
|
||||
int idB = m_hIds[indx].y;
|
||||
if((idA > 0) && (idB > 0))
|
||||
{
|
||||
btCollisionObject* colObjA = m_collisionObjects[idA];
|
||||
btCollisionObject* colObjB = m_collisionObjects[idB];
|
||||
btVector3 vA = colObjA->getWorldTransform().getOrigin();
|
||||
btVector3 vB = colObjB->getWorldTransform().getOrigin();
|
||||
glVertex3f(vA[0], vA[1], vA[2]);
|
||||
glVertex3f(vB[0], vB[1], vB[2]);
|
||||
}
|
||||
}
|
||||
pBatchIds += numConstraints;
|
||||
glEnd();
|
||||
}
|
||||
} // btGpuDemoDynamicsWorld::debugDrawConstraints()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void btGpuDemoDynamicsWorld::initShapeBuffer(int maxShapeBufferSize)
|
||||
{
|
||||
m_maxShapeBufferSize = maxShapeBufferSize;
|
||||
m_firstFreeShapeBufferOffset = 0;
|
||||
m_hShapeBuffer = new char[m_maxShapeBufferSize];
|
||||
m_hShapeIds = new int2[m_maxObjs];
|
||||
|
||||
#ifdef BT_USE_CUDA
|
||||
btCuda_allocateArray((void**)&m_dShapeBuffer, m_maxShapeBufferSize);
|
||||
btCuda_allocateArray((void**)&m_dShapeIds, sizeof(int) * 2 * m_maxObjs);
|
||||
#endif //BT_USE_CUDA
|
||||
|
||||
m_copyShapeDataToGPU = true;
|
||||
} // btGpuDemoDynamicsWorld::initShapeBuffer()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void btGpuDemoDynamicsWorld::freeShapeBuffer()
|
||||
{
|
||||
delete [] m_hShapeBuffer;
|
||||
delete [] m_hShapeIds;
|
||||
#ifdef BT_USE_CUDA
|
||||
btCuda_freeArray(m_dShapeBuffer);
|
||||
btCuda_freeArray(m_dShapeIds);
|
||||
#endif //BT_USE_CUDA
|
||||
} // btGpuDemoDynamicsWorld::freeShapeBuffer()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void btGpuDemoDynamicsWorld::addSphere(btVector3& pos, btScalar rad)
|
||||
{
|
||||
btVector3* pBuf = (btVector3*)(m_hShapeBuffer + m_firstFreeShapeBufferOffset);
|
||||
*pBuf = pos;
|
||||
pBuf->setW(rad);
|
||||
m_firstFreeShapeBufferOffset += sizeof(btVector3);
|
||||
} // btGpuDemoDynamicsWorld::addSphere()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void btGpuDemoDynamicsWorld::addMultiShereObject(int numSpheres, int objIndex)
|
||||
{
|
||||
m_hShapeIds[objIndex].x = m_firstFreeShapeBufferOffset;
|
||||
m_hShapeIds[objIndex].y = numSpheres;
|
||||
return;
|
||||
} // btGpuDemoDynamicsWorld::addMultiShereObject()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
272
Demos/Gpu2dDemo/btGpuDemoDynamicsWorld.h
Normal file
272
Demos/Gpu2dDemo/btGpuDemoDynamicsWorld.h
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
|
||||
Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef BT_CUDA_DEMO_DYNAMICS_WORLD_H
|
||||
#define BT_CUDA_DEMO_DYNAMICS_WORLD_H
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
|
||||
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
|
||||
#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
|
||||
|
||||
|
||||
#ifdef BT_USE_CUDA
|
||||
#include "btCudaDemoPairCache.h"
|
||||
#include <vector_types.h>
|
||||
#define BT_GPU_PREF(func) btCuda_##func
|
||||
#include "../../src/BulletMultiThreaded/btGpuUtilsSharedDefs.h"
|
||||
#else
|
||||
#include "BulletMultiThreaded/btGpuDefines.h"
|
||||
#include "../../src/BulletMultiThreaded/btGpuUtilsSharedDefs.h"
|
||||
#endif
|
||||
|
||||
#undef BT_GPU_PREF
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#include "btGpuDemo2DSharedTypes.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#define CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES 20
|
||||
|
||||
#define CUDA_DEMO_DYNAMICS_WORLD_MAX_OBJS 1024
|
||||
#define CUDA_DEMO_DYNAMICS_WORLD_MAX_NEIGHBORS 24
|
||||
|
||||
#define CUDA_DEMO_DYNAMICS_WORLD_MAX_SPHERES_PER_OBJ 8
|
||||
|
||||
class btGpuDemoDynamicsWorld;
|
||||
|
||||
extern btGpuDemoDynamicsWorld* gpCudaDemoDynamicsWorld; // to access world members from pair cache
|
||||
|
||||
class btGpuDemoDynamicsWorld : public btDiscreteDynamicsWorld
|
||||
{
|
||||
protected:
|
||||
int m_maxObjs;
|
||||
int m_maxNeighbors;
|
||||
|
||||
int m_numObj;
|
||||
int m_numSimStep;
|
||||
bool m_useCPUSolver;
|
||||
|
||||
float4* m_hPos;
|
||||
float* m_hRot;
|
||||
float4* m_hVel;
|
||||
float* m_hAngVel;
|
||||
|
||||
#ifdef BT_USE_CUDA
|
||||
float4* m_dPos;
|
||||
float* m_dRot;
|
||||
float4* m_dVel;
|
||||
float* m_dAngVel;
|
||||
float4* m_dpPos;
|
||||
float* m_dpRot;
|
||||
float4* m_dpVel;
|
||||
float* m_dpAngVel;
|
||||
|
||||
float4* m_dcPos;
|
||||
float* m_dcRot;
|
||||
float4* m_dcVel;
|
||||
float* m_dcAngVel;
|
||||
#endif //BT_USE_CUDA
|
||||
|
||||
|
||||
btOverlappingPairCache* m_pairCache;
|
||||
int* m_hConstraintBuffer;
|
||||
int* m_hConstraintCounter;
|
||||
int m_maxBatches;
|
||||
int m_numBatches;
|
||||
int m_totalNumConstraints;
|
||||
int2* m_hIds;
|
||||
int* m_hBatchIds;
|
||||
|
||||
int m_maxVtxPerObj;
|
||||
|
||||
int2* m_dIds;
|
||||
int* m_dBatchIds;
|
||||
|
||||
float* m_dLambdaDtBox;
|
||||
float4* m_dContact; // 8 floats : pos.x, pos.y, pos.z, penetration, norm.x, norm.y, norm.z, reserved
|
||||
|
||||
// ------------- these are only needed for CPU version and for debugging
|
||||
float* m_hLambdaDtBox;
|
||||
float4* m_hContact; // 8 floats : pos.x, pos.y, pos.z, penetration, norm.x, norm.y, norm.z, reserved
|
||||
// -------------
|
||||
|
||||
btScalar m_objRad;
|
||||
btVector3 m_worldMin;
|
||||
btVector3 m_worldMax;
|
||||
|
||||
//-------------------------------
|
||||
int* m_hConstraintUsed;
|
||||
|
||||
//-------------------------------
|
||||
// shape buffer
|
||||
int m_maxShapeBufferSize;
|
||||
int m_firstFreeShapeBufferOffset;
|
||||
char* m_hShapeBuffer; // (pos.x, pos.y, pos.z, radius)
|
||||
char* m_dShapeBuffer;//pointer in device memory
|
||||
int2* m_hShapeIds;
|
||||
int2* m_dShapeIds;
|
||||
bool m_copyShapeDataToGPU;
|
||||
void initShapeBuffer(int maxShapeBufferSize);
|
||||
void freeShapeBuffer();
|
||||
void sendShapeDataToGpu();
|
||||
|
||||
//-------------------------------
|
||||
int m_numNonContactConstraints;
|
||||
void grabNonContactConstraintData();
|
||||
void grabP2PConstraintData(btPoint2PointConstraint* ct);
|
||||
|
||||
public:
|
||||
int m_numInBatches[CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES];
|
||||
void addSphere(btVector3& pos, btScalar rad);
|
||||
void addMultiShereObject(int numSpheres, int objIndex);
|
||||
|
||||
|
||||
btGpuDemoDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration,
|
||||
int maxObjs = CUDA_DEMO_DYNAMICS_WORLD_MAX_OBJS, int maxNeighbors = CUDA_DEMO_DYNAMICS_WORLD_MAX_NEIGHBORS)
|
||||
: btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration)
|
||||
{
|
||||
m_maxObjs = maxObjs;
|
||||
m_maxNeighbors = maxNeighbors;
|
||||
m_useCPUSolver = false;
|
||||
m_pairCache = pairCache->getOverlappingPairCache();
|
||||
int sz = m_maxObjs * m_maxNeighbors;
|
||||
m_hConstraintBuffer = new int[sz];
|
||||
m_hConstraintCounter = new int[m_maxObjs];
|
||||
m_maxBatches = CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES;
|
||||
m_hIds = new int2[sz];
|
||||
m_hBatchIds = new int[sz];
|
||||
for(int i = 0; i < sz; i++)
|
||||
{
|
||||
m_hBatchIds[i] = -1;
|
||||
}
|
||||
m_hPos = new float4[m_maxObjs];
|
||||
m_hVel = new float4[m_maxObjs];
|
||||
m_hRot = new float[m_maxObjs];
|
||||
m_hAngVel = new float[m_maxObjs];
|
||||
|
||||
m_maxVtxPerObj = 8;
|
||||
|
||||
#ifdef BT_USE_CUDA
|
||||
btCuda_allocateArray((void**)&m_dPos, sizeof(float4) * m_maxObjs);
|
||||
btCuda_allocateArray((void**)&m_dRot, sizeof(float) * m_maxObjs);
|
||||
btCuda_allocateArray((void**)&m_dVel, sizeof(float4) * m_maxObjs);
|
||||
btCuda_allocateArray((void**)&m_dAngVel, sizeof(float) * m_maxObjs);
|
||||
btCuda_allocateArray((void**)&m_dpPos, sizeof(float4) * m_maxObjs);
|
||||
btCuda_allocateArray((void**)&m_dpRot, sizeof(float) * m_maxObjs);
|
||||
btCuda_allocateArray((void**)&m_dpVel, sizeof(float4) * m_maxObjs);
|
||||
btCuda_allocateArray((void**)&m_dpAngVel, sizeof(float) * m_maxObjs);
|
||||
|
||||
btCuda_allocateArray((void**)&m_dIds, sizeof(int2) * sz);
|
||||
btCuda_allocateArray((void**)&m_dBatchIds, sizeof(int) * sz);
|
||||
|
||||
btCuda_allocateArray((void**)&m_dLambdaDtBox, sizeof(float) * sz * m_maxVtxPerObj);
|
||||
btCuda_allocateArray((void**)&m_dContact, sizeof(float) * sz * m_maxVtxPerObj * 8);
|
||||
// btCuda_allocateArray((void**)&m_dPositionConstraint, sizeof(float) * sz * m_maxVtxPerObj * 2);
|
||||
// btCuda_allocateArray((void**)&m_dNormal, sizeof(float3) * sz * m_maxVtxPerObj * 2);
|
||||
#endif //BT_USE_CUDA
|
||||
|
||||
|
||||
m_hLambdaDtBox = new float[sz * m_maxVtxPerObj];
|
||||
m_hContact = new float4[sz * m_maxVtxPerObj * 2];
|
||||
// m_hPositionConstraint = new float[sz * m_maxVtxPerObj * 2];
|
||||
// m_hNormal = new float3[sz * m_maxVtxPerObj * 2];
|
||||
|
||||
m_numSimStep = 0;
|
||||
|
||||
m_objRad = 1.0f;
|
||||
|
||||
m_hConstraintUsed = new int[sz];
|
||||
|
||||
|
||||
gpCudaDemoDynamicsWorld = this;
|
||||
m_totalNumConstraints = 0;
|
||||
|
||||
initShapeBuffer(m_maxObjs * CUDA_DEMO_DYNAMICS_WORLD_MAX_SPHERES_PER_OBJ * sizeof(float) * 4);
|
||||
|
||||
}
|
||||
virtual ~btGpuDemoDynamicsWorld()
|
||||
{
|
||||
delete [] m_hConstraintBuffer;
|
||||
delete [] m_hConstraintCounter;
|
||||
delete [] m_hIds;
|
||||
delete [] m_hBatchIds;
|
||||
delete [] m_hPos;
|
||||
delete [] m_hRot;
|
||||
delete [] m_hVel;
|
||||
delete [] m_hAngVel;
|
||||
#ifdef BT_USE_CUDA
|
||||
btCuda_freeArray(m_dPos);
|
||||
btCuda_freeArray(m_dRot);
|
||||
btCuda_freeArray(m_dVel);
|
||||
btCuda_freeArray(m_dAngVel);
|
||||
btCuda_freeArray(m_dpPos);
|
||||
btCuda_freeArray(m_dpRot);
|
||||
btCuda_freeArray(m_dpVel);
|
||||
btCuda_freeArray(m_dpAngVel);
|
||||
|
||||
btCuda_freeArray(m_dIds);
|
||||
btCuda_freeArray(m_dBatchIds);
|
||||
btCuda_freeArray(m_dLambdaDtBox);
|
||||
btCuda_freeArray(m_dContact);
|
||||
#endif //BT_USE_CUDA
|
||||
|
||||
delete [] m_hLambdaDtBox;
|
||||
delete [] m_hContact;
|
||||
delete [] m_hConstraintUsed;
|
||||
|
||||
gpCudaDemoDynamicsWorld = NULL;
|
||||
|
||||
freeShapeBuffer();
|
||||
}
|
||||
|
||||
virtual void calculateSimulationIslands()
|
||||
{
|
||||
}
|
||||
virtual void solveConstraints(btContactSolverInfo& solverInfo);
|
||||
void solveConstraints2(btContactSolverInfo& solverInfo);
|
||||
void solveConstraintsCPU2(btContactSolverInfo& solverInfo);
|
||||
|
||||
void debugDrawConstraints(int selectedBatch, const float* pColorTab);
|
||||
|
||||
void setObjRad(btScalar rad) { m_objRad = rad; }
|
||||
void setWorldMin(const btVector3& worldMin) { m_worldMin = worldMin; }
|
||||
void setWorldMax(const btVector3& worldMax) { m_worldMax = worldMax; }
|
||||
|
||||
void grabData();
|
||||
void copyDataToGPU();
|
||||
void setConstraintData(btCudaPartProps& partProps);
|
||||
void copyDataFromGPU();
|
||||
void writebackData();
|
||||
void setUseCPUSolver(bool useCPU) { m_useCPUSolver = useCPU; }
|
||||
|
||||
void createBatches2();
|
||||
|
||||
int2* getIdsPtr() { return m_hIds; }
|
||||
void setTotalNumConstraints(int totalNumConstraints) { m_totalNumConstraints = totalNumConstraints; }
|
||||
int getTotalNumConstraints() { return m_totalNumConstraints; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //BT_CUDA_DEMO_DYNAMICS_WORLD_H
|
||||
79
Demos/Gpu2dDemo/btGpuDemoPairCache.cpp
Normal file
79
Demos/Gpu2dDemo/btGpuDemoPairCache.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||
|
||||
#include "btGpuDemoPairCache.h"
|
||||
|
||||
#include "btGpuDemoDynamicsWorld.h"
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void btGpuDemoPairCache::processAllOverlappingPairs(btOverlapCallback* callback, btDispatcher* dispatcher)
|
||||
{
|
||||
int sz = m_maxProxies * m_maxNeighbors;
|
||||
int numContConstraints = 0;
|
||||
int2* pIds = gpCudaDemoDynamicsWorld->getIdsPtr();
|
||||
for(int idx = 0; idx < sz; idx++)
|
||||
{
|
||||
int neigh = m_hNeighbors[idx];
|
||||
if(neigh >= 0)
|
||||
{
|
||||
int i=idx / m_maxNeighbors;
|
||||
int j=idx % m_maxNeighbors;
|
||||
pIds[numContConstraints].x = i;
|
||||
pIds[numContConstraints].y = m_hNeighbors[i * m_maxNeighbors + j];
|
||||
numContConstraints++;
|
||||
}
|
||||
}
|
||||
gpCudaDemoDynamicsWorld->setTotalNumConstraints(numContConstraints);
|
||||
} // btGpuDemoPairCache::processAllOverlappingPairs()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// this will be called for each overlapping pair if collision detection uses pairCache other than btGpuDemoPairCache
|
||||
// IMPORTANT : m_numConstraints in gpCudaDemoDynamicsWorld is set to 0 at start of simulation step
|
||||
// IMPORTANT : companionIds for all objects should be properly set at start of simulation step
|
||||
void cudaDemoNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo)
|
||||
{
|
||||
btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
|
||||
btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
|
||||
if (dispatcher.needsCollision(colObj0,colObj1))
|
||||
{
|
||||
// int id0 = collisionPair.m_pProxy0->m_uniqueId - 2;
|
||||
// int id1 = collisionPair.m_pProxy1->m_uniqueId - 2;
|
||||
// cannot use m_uniqueId : it may be altered by broadphase code
|
||||
// so we'll use companionIds set on the initialization stage
|
||||
unsigned int id0 = colObj0->getCompanionId();
|
||||
unsigned int id1 = colObj1->getCompanionId();
|
||||
if(id0 > id1)
|
||||
{
|
||||
int tmp = id0; id0 = id1; id1 = tmp;
|
||||
}
|
||||
int totalNumConstraints = gpCudaDemoDynamicsWorld->getTotalNumConstraints();
|
||||
int2* pIds = gpCudaDemoDynamicsWorld->getIdsPtr();
|
||||
pIds += totalNumConstraints;
|
||||
pIds->x = id0;
|
||||
pIds->y = id1;
|
||||
totalNumConstraints++;
|
||||
gpCudaDemoDynamicsWorld->setTotalNumConstraints(totalNumConstraints);
|
||||
}
|
||||
} // cudaDemoNearCallback()
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------
|
||||
136
Demos/Gpu2dDemo/btGpuDemoPairCache.h
Normal file
136
Demos/Gpu2dDemo/btGpuDemoPairCache.h
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef CUDA_DEMO_PAIR_CACHE_H
|
||||
#define CUDA_DEMO_PAIR_CACHE_H
|
||||
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
class btGpuDemoPairCache : public btNullPairCache
|
||||
{
|
||||
public:
|
||||
int m_maxProxies;
|
||||
int m_maxNeighbors;
|
||||
int* m_hNeighbors;
|
||||
int m_numPairs;
|
||||
int m_numSmallProxies;
|
||||
int m_maxSmallProxies;
|
||||
|
||||
btGpuDemoPairCache(int maxProxies, int maxNeighbors, int maxSmallProxies)
|
||||
{
|
||||
m_maxProxies = maxProxies;
|
||||
m_maxNeighbors = maxNeighbors;
|
||||
m_maxSmallProxies = maxSmallProxies;
|
||||
int sz = maxProxies * maxNeighbors;
|
||||
m_hNeighbors = new int [sz];
|
||||
reset();
|
||||
}
|
||||
|
||||
~btGpuDemoPairCache()
|
||||
{
|
||||
delete [] m_hNeighbors;
|
||||
}
|
||||
|
||||
void reset(void)
|
||||
{
|
||||
int sz = m_maxProxies * m_maxNeighbors;
|
||||
for(int i = 0; i < sz; i++)
|
||||
{
|
||||
m_hNeighbors[i] = -1;
|
||||
}
|
||||
m_numPairs = 0;
|
||||
}
|
||||
|
||||
virtual int getNumOverlappingPairs() const
|
||||
{
|
||||
return m_numPairs;
|
||||
//return 0; // to skip btSimulationIslandManager::findUnions()
|
||||
}
|
||||
|
||||
virtual void processAllOverlappingPairs(btOverlapCallback* callback, btDispatcher* dispatcher);
|
||||
|
||||
virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
|
||||
{
|
||||
int id0 = proxy0->m_uniqueId - 2;
|
||||
int id1 = proxy1->m_uniqueId - 2;
|
||||
if(id0 >= m_maxSmallProxies)
|
||||
{
|
||||
id0 -= m_maxSmallProxies - m_numSmallProxies;
|
||||
}
|
||||
if(id1 >= m_maxSmallProxies)
|
||||
{
|
||||
id1 -= m_maxSmallProxies - m_numSmallProxies;
|
||||
}
|
||||
if(id0 > id1)
|
||||
{
|
||||
int tmp = id0; id0 = id1; id1 = tmp;
|
||||
}
|
||||
int offs = id0 * m_maxNeighbors;
|
||||
int i;
|
||||
for(i = 0; i < m_maxNeighbors; i++)
|
||||
{
|
||||
if(m_hNeighbors[offs + i] < 0)
|
||||
{
|
||||
m_hNeighbors[offs + i] = id1;
|
||||
m_numPairs++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// btAssert(i < m_maxNeighbors);
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1,btDispatcher* /*dispatcher*/)
|
||||
{
|
||||
int id0 = proxy0->m_uniqueId - 2;
|
||||
int id1 = proxy1->m_uniqueId - 2;
|
||||
if(id0 >= m_maxSmallProxies)
|
||||
{
|
||||
id0 -= m_maxSmallProxies - m_numSmallProxies;
|
||||
}
|
||||
if(id1 >= m_maxSmallProxies)
|
||||
{
|
||||
id1 -= m_maxSmallProxies - m_numSmallProxies;
|
||||
}
|
||||
if(id0 > id1)
|
||||
{
|
||||
int tmp = id0; id0 = id1; id1 = tmp;
|
||||
}
|
||||
int offs = id0 * m_maxNeighbors;
|
||||
int i;
|
||||
for(i = 0; i < m_maxNeighbors; i++)
|
||||
{
|
||||
if(m_hNeighbors[offs + i] == id1)
|
||||
{
|
||||
m_hNeighbors[offs + i] = -1;
|
||||
m_numPairs--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// btAssert(i < m_maxNeighbors);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
extern void cudaDemoNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo);
|
||||
|
||||
#endif //CUDA_DEMO_PAIR_CACHE_H
|
||||
|
||||
|
||||
62
Demos/Gpu2dDemo/main.cpp
Normal file
62
Demos/Gpu2dDemo/main.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "BasicDemo.h"
|
||||
#include "GlutStuff.h"
|
||||
#include "GLDebugDrawer.h"
|
||||
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "LinearMath/btHashMap.h"
|
||||
|
||||
class OurValue
|
||||
{
|
||||
int m_uid;
|
||||
|
||||
public:
|
||||
OurValue(const btVector3& initialPos)
|
||||
:m_position(initialPos)
|
||||
{
|
||||
static int gUid=0;
|
||||
m_uid=gUid;
|
||||
gUid++;
|
||||
}
|
||||
|
||||
btVector3 m_position;
|
||||
int getUid() const
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
};
|
||||
|
||||
GLDebugDrawer gDebugDrawer;
|
||||
|
||||
int main(int argc,char** argv)
|
||||
{
|
||||
|
||||
|
||||
BasicDemo ccdDemo;
|
||||
ccdDemo.initPhysics();
|
||||
ccdDemo.getDynamicsWorld()->setDebugDrawer(&gDebugDrawer);
|
||||
|
||||
|
||||
#ifdef CHECK_MEMORY_LEAKS
|
||||
ccdDemo.exitPhysics();
|
||||
#else
|
||||
return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bulletphysics.com",&ccdDemo);
|
||||
#endif
|
||||
|
||||
//default glut doesn't return from mainloop
|
||||
return 0;
|
||||
}
|
||||
252
Demos/Gpu2dDemo/oecakeLoader.cpp
Normal file
252
Demos/Gpu2dDemo/oecakeLoader.cpp
Normal file
@@ -0,0 +1,252 @@
|
||||
#include "oecakeLoader.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
|
||||
|
||||
btCompoundShape* shiftTransform(btCompoundShape* boxCompound,btScalar mass,btTransform& shift)
|
||||
{
|
||||
btTransform principal;
|
||||
btVector3 principalInertia;
|
||||
btScalar* masses = new btScalar[boxCompound->getNumChildShapes()];
|
||||
for (int j=0;j<boxCompound->getNumChildShapes();j++)
|
||||
{
|
||||
//evenly distribute mass
|
||||
masses[j]=mass/boxCompound->getNumChildShapes();
|
||||
}
|
||||
|
||||
|
||||
boxCompound->calculatePrincipalAxisTransform(masses,principal,principalInertia);
|
||||
|
||||
|
||||
///create a new compound with world transform/center of mass properly aligned with the principal axis
|
||||
|
||||
///non-recursive compound shapes perform better
|
||||
//#define USE_RECURSIVE_COMPOUND 1
|
||||
#ifdef USE_RECURSIVE_COMPOUND
|
||||
|
||||
btCompoundShape* newCompound = new btCompoundShape();
|
||||
newCompound->addChildShape(principal.inverse(),boxCompound);
|
||||
m_collisionShapes.push_back(newCompound);
|
||||
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,newCompound,principalInertia);
|
||||
|
||||
#else
|
||||
#ifdef CHANGE_COMPOUND_INPLACE
|
||||
for (int i=0;i<boxCompound->getNumChildShapes();i++)
|
||||
{
|
||||
btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);
|
||||
///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update
|
||||
boxCompound->updateChildTransform(i,newChildTransform);
|
||||
}
|
||||
if (isDynamic)
|
||||
boxCompound->calculateLocalInertia(mass,localInertia);
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,boxCompound,localInertia);
|
||||
#else
|
||||
///creation is faster using a new compound to store the shifted children
|
||||
btCompoundShape* newBoxCompound = new btCompoundShape();
|
||||
for (int i=0;i<boxCompound->getNumChildShapes();i++)
|
||||
{
|
||||
btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);
|
||||
///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update
|
||||
newBoxCompound->addChildShape(newChildTransform,boxCompound->getChildShape(i));
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif//USE_RECURSIVE_COMPOUND
|
||||
|
||||
shift = principal;
|
||||
return newBoxCompound;
|
||||
}
|
||||
|
||||
|
||||
void BasicOECakeReader::addParticle(int materialType, int pIndex, int pColor, float pPosX, float pPosY,float radius)
|
||||
{
|
||||
//determine that we have a new shape?
|
||||
if (m_particlePositions.size())
|
||||
{
|
||||
if (
|
||||
(materialType != m_materialType)
|
||||
||
|
||||
(pIndex != m_particleObjectIndex)
|
||||
)
|
||||
{
|
||||
convertParticleGroup();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//add to array
|
||||
m_materialType = materialType;
|
||||
m_particleObjectIndex = pIndex;
|
||||
m_particleColor = pColor;
|
||||
m_particlePositions.push_back(btVector3(pPosX,pPosY,0.));
|
||||
m_particleRadii.push_back(radius);
|
||||
|
||||
}
|
||||
|
||||
void BasicOECakeReader::convertParticleGroup()
|
||||
{
|
||||
printf("found a particle group of %d particles\n",m_particlePositions.size());
|
||||
if (m_particlePositions.size()>0)
|
||||
{
|
||||
addNewCollisionShape(m_particlePositions.size(),&m_particlePositions[0],&m_particleRadii[0],m_materialType,m_particleObjectIndex,m_particleColor);
|
||||
m_particlePositions.clear();
|
||||
m_particleRadii.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void BasicOECakeReader::addNewCollisionShape(int numParticles, btVector3* particlePositions, btScalar* radii, int materialType, int objectIndex,int color )
|
||||
{
|
||||
//create Bullet stuff
|
||||
btCompoundShape* colShape = 0;
|
||||
btScalar mass;
|
||||
|
||||
bool addConstraint = false;
|
||||
|
||||
|
||||
if (materialType&0x800000)
|
||||
{
|
||||
addConstraint = true;
|
||||
}
|
||||
|
||||
if ((materialType & 0x20000) ||(materialType & 0x12))
|
||||
{
|
||||
mass = 1.f;
|
||||
}
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
|
||||
|
||||
{
|
||||
|
||||
|
||||
btTransform localTrans;
|
||||
localTrans.setIdentity();
|
||||
|
||||
//static
|
||||
btCompoundShape* compound = new btCompoundShape();
|
||||
for (int i=0;i<numParticles;i++)
|
||||
{
|
||||
localTrans.setOrigin(particlePositions[i]);
|
||||
btSphereShape* particle = new btSphereShape(radii[i]);
|
||||
compound->addChildShape(localTrans,particle);
|
||||
}
|
||||
if (mass)
|
||||
{
|
||||
//shift the center of mass, based on all spheres
|
||||
btCompoundShape* newCompound = shiftTransform(compound,mass,startTransform);
|
||||
colShape = newCompound;
|
||||
} else
|
||||
{
|
||||
//use unmodified
|
||||
colShape = compound;
|
||||
}
|
||||
}
|
||||
|
||||
btDefaultMotionState* myMotionState = 0;
|
||||
|
||||
if (colShape)
|
||||
{
|
||||
createBodyForCompoundShape(colShape,addConstraint,startTransform,mass);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int BasicOECakeReader::processLine(char * buffer, int size)
|
||||
{
|
||||
int numBytesRead = 0;
|
||||
|
||||
if (buffer[0] == 'p')
|
||||
{
|
||||
int materialType;
|
||||
int particleObjectIndex;
|
||||
int particleColor;
|
||||
int dummy1;
|
||||
float particlePosX;
|
||||
float particlePosY;
|
||||
|
||||
if (sscanf (buffer, "p %x %x %x %x %f %f", &materialType,&particleObjectIndex,&dummy1, &particleColor, &particlePosX, &particlePosY) == 6)
|
||||
{
|
||||
addParticle(materialType,particleObjectIndex,particleColor,particlePosX,particlePosY);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("ERROR: invalid line (%s)\n", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
while (*buffer != '\n' && size != 0)
|
||||
{
|
||||
buffer++;
|
||||
numBytesRead++;
|
||||
}
|
||||
|
||||
|
||||
if (buffer[0]==0x0a)
|
||||
{
|
||||
buffer++;
|
||||
numBytesRead++;
|
||||
}
|
||||
|
||||
|
||||
return numBytesRead;
|
||||
}
|
||||
|
||||
bool BasicOECakeReader::processFile(char * fileName)
|
||||
{
|
||||
FILE * fp = fopen(fileName, "rb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
printf("ERROR: file(%s) not found", fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
int size;
|
||||
if (fseek(fp, 0, SEEK_END) || (size = ftell(fp)) == EOF || fseek(fp, 0, SEEK_SET))
|
||||
{
|
||||
printf("ERROR: problem reading file(%s)", fileName);
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
rewind (fp);
|
||||
char * buffer = (char *) malloc(size+1);
|
||||
memset(buffer,0,size);
|
||||
|
||||
if (fread(buffer,1,size,fp) != size)
|
||||
{
|
||||
printf("Error reading file %s!\n",fileName);
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
int totalBytesRead = 0;
|
||||
|
||||
while(totalBytesRead<size)
|
||||
{
|
||||
int remainingSize = size-totalBytesRead;
|
||||
if (remainingSize<1229)
|
||||
|
||||
{
|
||||
printf("..");
|
||||
}
|
||||
|
||||
|
||||
totalBytesRead +=processLine(&buffer[totalBytesRead],remainingSize);
|
||||
}
|
||||
}
|
||||
|
||||
convertParticleGroup();
|
||||
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
35
Demos/Gpu2dDemo/oecakeLoader.h
Normal file
35
Demos/Gpu2dDemo/oecakeLoader.h
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
#ifndef OE_CAKE_LOADER_H
|
||||
#define OE_CAKE_LOADER_H
|
||||
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
|
||||
|
||||
class BasicOECakeReader
|
||||
{
|
||||
int m_materialType;
|
||||
int m_particleObjectIndex;
|
||||
int m_particleColor;
|
||||
btAlignedObjectArray<btVector3> m_particlePositions;
|
||||
btAlignedObjectArray<btScalar> m_particleRadii;
|
||||
|
||||
void addParticle(int materialType, int pIndex, int pColor, float pPosX, float pPosY, float radius=1);
|
||||
|
||||
virtual void addNewCollisionShape(int numParticles, btVector3* particlePositions, btScalar* radii, int materialType, int objectIndex,int color );
|
||||
|
||||
int processLine(char * buffer, int size);
|
||||
|
||||
void convertParticleGroup();
|
||||
|
||||
public:
|
||||
|
||||
BasicOECakeReader()
|
||||
{
|
||||
}
|
||||
|
||||
bool processFile(char * fileName);
|
||||
|
||||
virtual void createBodyForCompoundShape(btCompoundShape* compound,bool addConstraint,const btTransform& worldTransform, btScalar mass) = 0;
|
||||
|
||||
};
|
||||
#endif //OE_CAKE_LOADER_H
|
||||
Reference in New Issue
Block a user