reorder files, in preparation for Bullet 3 -> Bullet 2 merge

This commit is contained in:
erwincoumans
2013-04-29 19:04:08 -07:00
parent 55b69201a9
commit 3ac332f3a7
162 changed files with 215 additions and 3070 deletions

View File

@@ -0,0 +1,28 @@
#include "Bullet2GpuDemo.h"
#include "../b3GpuDynamicsWorld.h"
#include "GpuRigidBodyDemoInternalData.h"
#include "BulletCollision/CollisionShapes/b3BoxShape.h"
#include "gpu_rigidbody/host/b3RigidBody.h"
void Bullet2GpuDemo::setupScene(const ConstructionInfo& ci)
{
// m_data->m_np = np;
// m_data->m_bp = bp;
// m_data->m_rigidBodyPipeline
m_gpuDynamicsWorld = new b3GpuDynamicsWorld(m_data->m_bp,m_data->m_np,m_data->m_rigidBodyPipeline);
b3Vector3 halfExtents(100,1,100);
b3BoxShape* boxShape = new b3BoxShape(halfExtents);
b3Vector3 localInertia;
b3Scalar mass=1.f;
boxShape->calculateLocalInertia(mass,localInertia);
b3RigidBody* body = new b3RigidBody(mass,0,boxShape,localInertia);
m_gpuDynamicsWorld->addRigidBody(body);
}
void Bullet2GpuDemo::destroyScene()
{
delete m_gpuDynamicsWorld;
m_gpuDynamicsWorld = 0;
}

View File

@@ -0,0 +1,31 @@
#ifndef BULLET2_GPU_DEMO_H
#define BULLET2_GPU_DEMO_H
#include "GpuRigidBodyDemo.h"
class Bullet2GpuDemo : public GpuRigidBodyDemo
{
protected:
class b3GpuDynamicsWorld* m_gpuDynamicsWorld;
public:
Bullet2GpuDemo(){}
virtual ~Bullet2GpuDemo(){}
virtual const char* getName()
{
return "Bullet2Gpu";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new Bullet2GpuDemo;
return demo;
}
virtual void setupScene(const ConstructionInfo& ci);
virtual void destroyScene();
};
#endif //BULLET2_GPU_DEMO_H

View File

@@ -0,0 +1,611 @@
/*
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 "b3CpuDynamicsWorld.h"
#include "b3GpuDynamicsWorld.h"
#define SCALING 1.
#define START_POS_X -5
#define START_POS_Y 10
#define START_POS_Z -3
#include "LinearMath/b3Vector3.h"
#include "GpuDemo.h"
//#include "GlutStuff.h"
///b3BulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
//#include "b3BulletDynamicsCommon.h"
#include "BulletCollision/CollisionShapes/b3TriangleMesh.h"
#include "BulletCollision/CollisionShapes/b3BvhTriangleMeshShape.h"
#include "BulletCollision/CollisionShapes/b3SphereShape.h"
#include "BulletCollision/CollisionShapes/b3ConvexHullShape.h"
#include "BulletCollision/CollisionShapes/b3BoxShape.h"
#include "BulletCollision/CollisionShapes/b3CompoundShape.h"
#include "BulletCollision/CollisionShapes/b3StaticPlaneShape.h"
#include "BulletDynamics/Dynamics/b3RigidBody.h"
#include "LinearMath/b3DefaultMotionState.h"
#include "LinearMath/b3Quickprof.h"
#include <stdio.h> //printf debugging
void GpuDemo::clientMoveAndDisplay()
{
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//simple dynamics world doesn't handle fixed-time-stepping
float dt = getDeltaTimeInSeconds();
///step the simulation
if (m_dynamicsWorld)
{
static bool once = true;
if (once)
{
once=false;
b3DefaultSerializer* serializer = new b3DefaultSerializer();
m_dynamicsWorld->serialize(serializer);
FILE* file = fopen("testFile.bullet","wb");
fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1, file);
fclose(file);
}
m_dynamicsWorld->stepSimulation(dt);
static int count=0;
count++;
if (count==25)
{
//b3ProfileManager::dumpAll();
}
}
// renderme();
//swapBuffers();
}
b3AlignedObjectArray<b3Vector3> vertices;
void EmptyDemo::setupScene(const ConstructionInfo& ci)
{
//empty test
}
void SpheresDemo::setupScene(const ConstructionInfo& ci)
{
if (1)
{
b3SphereShape* sphere = new b3SphereShape(1);
m_collisionShapes.push_back(sphere);
/// Create Dynamic Objects
b3Transform startTransform;
startTransform.setIdentity();
float start_x = START_POS_X - ci.gapX*ci.arraySizeX/2;
float start_y = START_POS_Y;
float start_z = START_POS_Z - ci.gapZ*ci.arraySizeZ/2;
for (int k=0;k<ci.arraySizeY;k++)
{
int sizeX = ci.arraySizeX;
int startX = -sizeX/2;
float gapX = ci.gapX;
for (int i=0;i<sizeX;i++)
{
int sizeZ = ci.arraySizeZ;
int startZ = -sizeX/2;
float gapZ =ci.gapZ;
for(int j = 0;j<sizeZ;j++)
{
//b3CollisionShape* shape = k==0? boxShape : colShape;
b3CollisionShape* shape = sphere;
b3Scalar mass = 1;
if (!ci.m_useConcaveMesh && k==0)
mass = k==0? 0.f : 1.f;
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
b3Vector3 localInertia(0,0,0);
if (isDynamic)
shape->calculateLocalInertia(mass,localInertia);
startTransform.setOrigin(SCALING*b3Vector3(
b3Scalar(gapX*i + start_x),
b3Scalar(ci.gapY*k + start_y),
b3Scalar(gapZ*j + start_z)));
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
b3DefaultMotionState* myMotionState = new b3DefaultMotionState(startTransform);
b3RigidBody::b3RigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia);
b3RigidBody* body = new b3RigidBody(rbInfo);
m_dynamicsWorld->addRigidBody(body);
}
}
}
}
{
b3Vector3 planeNormal(0,1,0);
b3Scalar planeConstant=0;
b3CollisionShape* shape = new b3StaticPlaneShape(planeNormal,planeConstant);
//b3BoxShape* plane = new b3BoxShape(b3Vector3(100,1,100));
//plane->initializePolyhedralFeatures();
//b3SphereShape* shape = new b3SphereShape(1000);
b3Scalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
b3Vector3 localInertia(0,0,0);
b3Transform groundTransform;
groundTransform.setIdentity();
groundTransform.setRotation(b3Quaternion(b3Vector3(1,0,0),0.3));
groundTransform.setOrigin(b3Vector3(0,0,0));
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
b3DefaultMotionState* myMotionState = new b3DefaultMotionState(groundTransform);
b3RigidBody::b3RigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia);
b3RigidBody* body = new b3RigidBody(rbInfo);
//add the body to the dynamics world
m_dynamicsWorld->addRigidBody(body);
}
}
void GpuCompoundDemo::setupScene(const ConstructionInfo& ci)
{
b3CollisionShape* groundShape =0;
// b3CollisionShape* groundShape = new b3StaticPlaneShape(b3Vector3(0,1,0),50);
if (ci.m_useConcaveMesh)
{
b3TriangleMesh* meshInterface = new b3TriangleMesh();
b3AlignedObjectArray<b3Vector3> concaveVertices;
concaveVertices.push_back(b3Vector3(0,-20,0));
concaveVertices.push_back(b3Vector3(80,10,80));
concaveVertices.push_back(b3Vector3(80,10,-80));
concaveVertices.push_back(b3Vector3(-80,10,-80));
concaveVertices.push_back(b3Vector3(-80,10,80));
meshInterface->addTriangle(concaveVertices[0],concaveVertices[1],concaveVertices[2],true);
meshInterface->addTriangle(concaveVertices[0],concaveVertices[2],concaveVertices[3],true);
meshInterface->addTriangle(concaveVertices[0],concaveVertices[3],concaveVertices[4],true);
meshInterface->addTriangle(concaveVertices[0],concaveVertices[4],concaveVertices[1],true);
#if 0
groundShape = new b3BvhTriangleMeshShape(meshInterface,true);//b3StaticPlaneShape(b3Vector3(0,1,0),50);
#else
b3BoxShape* shape =new b3BoxShape(b3Vector3(b3Scalar(250.),b3Scalar(10.),b3Scalar(250.)));
shape->initializePolyhedralFeatures();
groundShape = shape;
#endif
} else
{
groundShape = new b3BoxShape(b3Vector3(b3Scalar(250.),b3Scalar(50.),b3Scalar(250.)));
}
m_collisionShapes.push_back(groundShape);
b3Transform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(b3Vector3(0,0,0));
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
if (ci.m_useConcaveMesh)
{
b3Scalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
b3Vector3 localInertia(0,0,0);
if (isDynamic)
groundShape->calculateLocalInertia(mass,localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
b3DefaultMotionState* myMotionState = new b3DefaultMotionState(groundTransform);
b3RigidBody::b3RigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
b3RigidBody* body = new b3RigidBody(rbInfo);
//add the body to the dynamics world
m_dynamicsWorld->addRigidBody(body);
}
{
//create a few dynamic rigidbodies
// Re-using the same collision is better for memory usage and performance
//vertices.push_back(b3Vector3(0,1,0));
vertices.push_back(b3Vector3(1,1,1));
vertices.push_back(b3Vector3(1,1,-1));
vertices.push_back(b3Vector3(-1,1,-1));
vertices.push_back(b3Vector3(-1,1,1));
vertices.push_back(b3Vector3(1,-1,1));
vertices.push_back(b3Vector3(1,-1,-1));
vertices.push_back(b3Vector3(-1,-1,-1));
vertices.push_back(b3Vector3(-1,-1,1));
#if 0
b3PolyhedralConvexShape* colShape = new b3ConvexHullShape(&vertices[0].getX(),vertices.size());
colShape->initializePolyhedralFeatures();
#else
b3CompoundShape* compoundShape = 0;
{
b3PolyhedralConvexShape* colShape = new b3ConvexHullShape(&vertices[0].getX(),vertices.size());
colShape->initializePolyhedralFeatures();
compoundShape = new b3CompoundShape();
b3Transform tr;
tr.setIdentity();
tr.setOrigin(b3Vector3(0,-1,0));
compoundShape->addChildShape(tr,colShape);
tr.setOrigin(b3Vector3(0,0,2));
compoundShape->addChildShape(tr,colShape);
tr.setOrigin(b3Vector3(2,0,0));
compoundShape->addChildShape(tr,colShape);
}
b3CollisionShape* colShape = compoundShape;
#endif
b3PolyhedralConvexShape* boxShape = new b3BoxShape(b3Vector3(SCALING*1,SCALING*1,SCALING*1));
boxShape->initializePolyhedralFeatures();
//b3CollisionShape* colShape = new b3SphereShape(b3Scalar(1.));
m_collisionShapes.push_back(colShape);
m_collisionShapes.push_back(boxShape);
/// Create Dynamic Objects
b3Transform startTransform;
startTransform.setIdentity();
float start_x = START_POS_X - ci.arraySizeX/2;
float start_y = START_POS_Y;
float start_z = START_POS_Z - ci.arraySizeZ/2;
for (int k=0;k<ci.arraySizeY;k++)
{
int sizeX = ci.arraySizeX;
if (!ci.m_useConcaveMesh && k==0)
sizeX = 50;
int startX = !ci.m_useConcaveMesh&&k==0? -20 : 0;
float gapX = !ci.m_useConcaveMesh&&k==0? 3.05 : ci.gapX;
for (int i=0;i<sizeX;i++)
{
int sizeZ = !ci.m_useConcaveMesh&&k==0? 50 : ci.arraySizeZ;
int startZ = (!ci.m_useConcaveMesh)&&k==0? -20 : 0;
float gapZ = !ci.m_useConcaveMesh&&k==0? 3.05 : ci.gapZ;
for(int j = 0;j<sizeZ;j++)
{
//b3CollisionShape* shape = k==0? boxShape : colShape;
b3CollisionShape* shape = colShape;
b3Scalar mass = 1;
if (!ci.m_useConcaveMesh && k==0)
mass = k==0? 0.f : 1.f;
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
b3Vector3 localInertia(0,0,0);
if (isDynamic)
shape->calculateLocalInertia(mass,localInertia);
startTransform.setOrigin(SCALING*b3Vector3(
b3Scalar(startX+gapX*i + start_x),
b3Scalar(20+ci.gapY*k + start_y),
b3Scalar(startZ+gapZ*j + start_z)));
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
b3DefaultMotionState* myMotionState = new b3DefaultMotionState(startTransform);
b3RigidBody::b3RigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia);
b3RigidBody* body = new b3RigidBody(rbInfo);
m_dynamicsWorld->addRigidBody(body);
}
}
}
}
}
void GpuBoxDemo::setupScene(const ConstructionInfo& ci)
{
b3CollisionShape* groundShape =0;
// b3CollisionShape* groundShape = new b3StaticPlaneShape(b3Vector3(0,1,0),50);
if (ci.m_useConcaveMesh)
{
b3TriangleMesh* meshInterface = new b3TriangleMesh();
b3AlignedObjectArray<b3Vector3> concaveVertices;
concaveVertices.push_back(b3Vector3(0,-20,0));
concaveVertices.push_back(b3Vector3(80,10,80));
concaveVertices.push_back(b3Vector3(80,10,-80));
concaveVertices.push_back(b3Vector3(-80,10,-80));
concaveVertices.push_back(b3Vector3(-80,10,80));
meshInterface->addTriangle(concaveVertices[0],concaveVertices[1],concaveVertices[2],true);
meshInterface->addTriangle(concaveVertices[0],concaveVertices[2],concaveVertices[3],true);
meshInterface->addTriangle(concaveVertices[0],concaveVertices[3],concaveVertices[4],true);
meshInterface->addTriangle(concaveVertices[0],concaveVertices[4],concaveVertices[1],true);
#if 0
groundShape = new b3BvhTriangleMeshShape(meshInterface,true);//b3StaticPlaneShape(b3Vector3(0,1,0),50);
#else
b3BoxShape* shape =new b3BoxShape(b3Vector3(b3Scalar(250.),b3Scalar(10.),b3Scalar(250.)));
shape->initializePolyhedralFeatures();
groundShape = shape;
#endif
} else
{
groundShape = new b3BoxShape(b3Vector3(b3Scalar(250.),b3Scalar(50.),b3Scalar(250.)));
}
m_collisionShapes.push_back(groundShape);
b3Transform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(b3Vector3(0,0,0));
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
if (ci.m_useConcaveMesh)
{
b3Scalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
b3Vector3 localInertia(0,0,0);
if (isDynamic)
groundShape->calculateLocalInertia(mass,localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
b3DefaultMotionState* myMotionState = new b3DefaultMotionState(groundTransform);
b3RigidBody::b3RigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
b3RigidBody* body = new b3RigidBody(rbInfo);
//add the body to the dynamics world
m_dynamicsWorld->addRigidBody(body);
}
{
//create a few dynamic rigidbodies
// Re-using the same collision is better for memory usage and performance
//vertices.push_back(b3Vector3(0,1,0));
vertices.push_back(b3Vector3(1,1,1));
vertices.push_back(b3Vector3(1,1,-1));
vertices.push_back(b3Vector3(-1,1,-1));
vertices.push_back(b3Vector3(-1,1,1));
vertices.push_back(b3Vector3(1,-1,1));
vertices.push_back(b3Vector3(1,-1,-1));
vertices.push_back(b3Vector3(-1,-1,-1));
vertices.push_back(b3Vector3(-1,-1,1));
#if 1
b3PolyhedralConvexShape* colShape = new b3ConvexHullShape(&vertices[0].getX(),vertices.size());
colShape->initializePolyhedralFeatures();
#else
b3CompoundShape* compoundShape = 0;
{
b3PolyhedralConvexShape* colShape = new b3ConvexHullShape(&vertices[0].getX(),vertices.size());
colShape->initializePolyhedralFeatures();
compoundShape = new b3CompoundShape();
b3Transform tr;
tr.setIdentity();
tr.setOrigin(b3Vector3(0,-1,0));
compoundShape->addChildShape(tr,colShape);
tr.setOrigin(b3Vector3(0,0,2));
compoundShape->addChildShape(tr,colShape);
tr.setOrigin(b3Vector3(2,0,0));
compoundShape->addChildShape(tr,colShape);
}
b3CollisionShape* colShape = compoundShape;
#endif
b3PolyhedralConvexShape* boxShape = new b3BoxShape(b3Vector3(SCALING*1,SCALING*1,SCALING*1));
boxShape->initializePolyhedralFeatures();
//b3CollisionShape* colShape = new b3SphereShape(b3Scalar(1.));
m_collisionShapes.push_back(colShape);
m_collisionShapes.push_back(boxShape);
/// Create Dynamic Objects
b3Transform startTransform;
startTransform.setIdentity();
float start_x = START_POS_X - ci.arraySizeX/2;
float start_y = START_POS_Y;
float start_z = START_POS_Z - ci.arraySizeZ/2;
for (int k=0;k<ci.arraySizeY;k++)
{
int sizeX = ci.arraySizeX;
if (!ci.m_useConcaveMesh && k==0)
sizeX = 50;
int startX = !ci.m_useConcaveMesh&&k==0? -20 : 0;
float gapX = !ci.m_useConcaveMesh&&k==0? 3.05 : ci.gapX;
for (int i=0;i<sizeX;i++)
{
int sizeZ = !ci.m_useConcaveMesh&&k==0? 50 : ci.arraySizeZ;
int startZ = (!ci.m_useConcaveMesh)&&k==0? -20 : 0;
float gapZ = !ci.m_useConcaveMesh&&k==0? 3.05 : ci.gapZ;
for(int j = 0;j<sizeZ;j++)
{
//b3CollisionShape* shape = k==0? boxShape : colShape;
b3CollisionShape* shape = colShape;
b3Scalar mass = 1;
if (!ci.m_useConcaveMesh && k==0)
mass = k==0? 0.f : 1.f;
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
b3Vector3 localInertia(0,0,0);
if (isDynamic)
shape->calculateLocalInertia(mass,localInertia);
startTransform.setOrigin(SCALING*b3Vector3(
b3Scalar(startX+gapX*i + start_x),
b3Scalar(ci.gapY*(k+0.5) + start_y),
b3Scalar(startZ+gapZ*j + start_z)));
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
b3DefaultMotionState* myMotionState = new b3DefaultMotionState(startTransform);
b3RigidBody::b3RigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia);
b3RigidBody* body = new b3RigidBody(rbInfo);
m_dynamicsWorld->addRigidBody(body);
}
}
}
}
}
void GpuDemo::initPhysics(const ConstructionInfo& ci)
{
// setTexturing(true);
//setShadows(false);
// setCameraDistance(b3Scalar(SCALING*250.));
///collision configuration contains default setup for memory, collision setup
if (ci.useOpenCL)
{
m_dynamicsWorld = new b3GpuDynamicsWorld(ci.preferredOpenCLPlatformIndex,ci.preferredOpenCLDeviceIndex);
} else
{
m_dynamicsWorld = new b3CpuDynamicsWorld();
}
m_dynamicsWorld->setGravity(b3Vector3(0,-10,0));
///create a few basic rigid bodies
setupScene(ci);
}
/*void GpuDemo::clientResetScene()
{
exitPhysics();
initPhysics();
}
*/
void GpuDemo::exitPhysics()
{
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
int i;
if (m_dynamicsWorld)
{
for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
{
b3CollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
b3RigidBody* body = b3RigidBody::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++)
{
b3CollisionShape* shape = m_collisionShapes[j];
delete shape;
}
m_collisionShapes.clear();
delete m_dynamicsWorld;
m_dynamicsWorld=0;
}

184
Demos3/donttouch/GpuDemo.h Normal file
View File

@@ -0,0 +1,184 @@
/*
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 GPU_DEMO_H
#define GPU_DEMO_H
#include "Bullet3Common/b3AlignedObjectArray.h"
class b3BroadphaseInterface;
class b3CollisionShape;
class b3OverlappingPairCache;
class b3CollisionDispatcher;
class b3ConstraintSolver;
struct b3CollisionAlgorithmCreateFunc;
class b3DefaultCollisionConfiguration;
class b3DynamicsWorld;
class GLInstancingRenderer;
///GpuDemo is good starting point for learning the code base and porting.
class GpuDemo
{
protected:
b3DynamicsWorld* m_dynamicsWorld;
//keep the collision shapes, for deletion/cleanup
b3AlignedObjectArray<b3CollisionShape*> m_collisionShapes;
float getDeltaTimeInSeconds()
{
return 1./60.f;
}
public:
typedef class GpuDemo* (CreateFunc)();
struct ConstructionInfo
{
bool useOpenCL;
int preferredOpenCLPlatformIndex;
int preferredOpenCLDeviceIndex;
int arraySizeX;
int arraySizeY;
int arraySizeZ;
bool m_useConcaveMesh;
float gapX;
float gapY;
float gapZ;
GLInstancingRenderer* m_instancingRenderer;
ConstructionInfo()
:useOpenCL(false),//true),
preferredOpenCLPlatformIndex(-1),
preferredOpenCLDeviceIndex(-1),
arraySizeX(10),
arraySizeY(10 ),
arraySizeZ(10),
m_useConcaveMesh(false),
gapX(4.3),
gapY(4.0),
gapZ(4.3),
m_instancingRenderer(0)
{
}
};
protected:
virtual void setupScene(const ConstructionInfo& ci)=0;
public:
GpuDemo()
{
m_dynamicsWorld=0;
}
virtual ~GpuDemo()
{
exitPhysics();
}
virtual void initPhysics(const ConstructionInfo& ci);
virtual const char* getName()=0;
virtual void exitPhysics();
virtual const b3DynamicsWorld* getDynamicsWorld() const
{
return m_dynamicsWorld;
}
virtual void renderScene()
{
}
virtual void clientMoveAndDisplay();
//virtual void clientResetScene();
};
class GpuCompoundDemo : public GpuDemo
{
public:
virtual void setupScene(const ConstructionInfo& ci);
virtual const char* getName()
{
return "GpuCompoundDemo";
}
static GpuDemo* CreateFunc()
{
GpuDemo* demo = new GpuCompoundDemo;
return demo;
}
};
class GpuBoxDemo : public GpuDemo
{
public:
virtual void setupScene(const ConstructionInfo& ci);
virtual const char* getName()
{
return "GpuBoxDemo";
}
static GpuDemo* CreateFunc()
{
GpuDemo* demo = new GpuBoxDemo;
return demo;
}
};
class EmptyDemo : public GpuDemo
{
public:
virtual void setupScene(const ConstructionInfo& ci);
virtual const char* getName()
{
return "EmptyDemo";
}
static GpuDemo* CreateFunc()
{
GpuDemo* demo = new EmptyDemo;
return demo;
}
};
class SpheresDemo : public GpuDemo
{
public:
virtual void setupScene(const ConstructionInfo& ci);
virtual const char* getName()
{
return "SpheresDemo";
}
static GpuDemo* CreateFunc()
{
GpuDemo* demo = new SpheresDemo;
return demo;
}
};
#endif //GPU_DEMO_H

View File

@@ -0,0 +1,678 @@
#include "OpenGL3CoreRenderer.h"
#include "OpenGLWindow/GLInstancingRenderer.h"
#include "OpenGLWindow/ShapeData.h"
//#include "BulletDynamics/Dynamics/b3DiscreteDynamicsWorld.h"
//#include "BulletCollision/CollisionDispatch/b3CollisionObject.h"
#include "Bullet3Common/b3Quickprof.h"
/*#include "BulletCollision/CollisionShapes/b3BvhTriangleMeshShape.h"
#include "BulletCollision/CollisionShapes/b3ConvexPolyhedron.h"
#include "BulletCollision/CollisionShapes/b3ConvexHullShape.h"
#include "BulletCollision/CollisionShapes/b3CollisionShape.h"
#include "BulletCollision/CollisionShapes/b3BoxShape.h"
#include "BulletCollision/CollisionShapes/b3CompoundShape.h"
#include "BulletCollision/CollisionShapes/b3SphereShape.h"
#include "BulletCollision/CollisionShapes/b3StaticPlaneShape.h"
#include "../../rendering/WavefrontObjLoader/objLoader.h"
*/
OpenGL3CoreRenderer::OpenGL3CoreRenderer()
{
int maxNumObjects = 2*1024*1024;
m_instancingRenderer = new GLInstancingRenderer(maxNumObjects);
m_instancingRenderer->setCameraDistance(150);
}
OpenGL3CoreRenderer::~OpenGL3CoreRenderer()
{
delete m_instancingRenderer;
}
void OpenGL3CoreRenderer::init()
{
m_instancingRenderer->InitShaders();
}
void OpenGL3CoreRenderer::reshape(int w, int h)
{
m_instancingRenderer->resize(w,h);
}
void OpenGL3CoreRenderer::keyboardCallback(unsigned char key)
{
}
struct GraphicsVertex
{
float xyzw[4];
float normal[3];
float uv[2];
};
struct GraphicsShape
{
const float* m_vertices;
int m_numvertices;
const int* m_indices;
int m_numIndices;
float m_scaling[4];
};
GraphicsShape* createGraphicsShapeFromConvexHull(const b3ConvexPolyhedron* utilPtr)
{
b3AlignedObjectArray<GraphicsVertex>* vertices = new b3AlignedObjectArray<GraphicsVertex>;
{
int numVertices = utilPtr->m_vertices.size();
int numIndices = 0;
b3AlignedObjectArray<int>* indicesPtr = new b3AlignedObjectArray<int>;
for (int f=0;f<utilPtr->m_faces.size();f++)
{
const b3Face& face = utilPtr->m_faces[f];
b3Vector3 normal(face.m_plane[0],face.m_plane[1],face.m_plane[2]);
if (face.m_indices.size()>2)
{
GraphicsVertex vtx;
const b3Vector3& orgVertex = utilPtr->m_vertices[face.m_indices[0]];
vtx.xyzw[0] = orgVertex[0];vtx.xyzw[1] = orgVertex[1];vtx.xyzw[2] = orgVertex[2];vtx.xyzw[3] = 0.f;
vtx.normal[0] = normal[0];vtx.normal[1] = normal[1];vtx.normal[2] = normal[2];
vtx.uv[0] = 0.5f;vtx.uv[1] = 0.5f;
int newvtxindex0 = vertices->size();
vertices->push_back(vtx);
for (int j=1;j<face.m_indices.size()-1;j++)
{
indicesPtr->push_back(newvtxindex0);
{
GraphicsVertex vtx;
const b3Vector3& orgVertex = utilPtr->m_vertices[face.m_indices[j]];
vtx.xyzw[0] = orgVertex[0];vtx.xyzw[1] = orgVertex[1];vtx.xyzw[2] = orgVertex[2];vtx.xyzw[3] = 0.f;
vtx.normal[0] = normal[0];vtx.normal[1] = normal[1];vtx.normal[2] = normal[2];
vtx.uv[0] = 0.5f;vtx.uv[1] = 0.5f;
int newvtxindexj = vertices->size();
vertices->push_back(vtx);
indicesPtr->push_back(newvtxindexj);
}
{
GraphicsVertex vtx;
const b3Vector3& orgVertex = utilPtr->m_vertices[face.m_indices[j+1]];
vtx.xyzw[0] = orgVertex[0];vtx.xyzw[1] = orgVertex[1];vtx.xyzw[2] = orgVertex[2];vtx.xyzw[3] = 0.f;
vtx.normal[0] = normal[0];vtx.normal[1] = normal[1];vtx.normal[2] = normal[2];
vtx.uv[0] = 0.5f;vtx.uv[1] = 0.5f;
int newvtxindexj1 = vertices->size();
vertices->push_back(vtx);
indicesPtr->push_back(newvtxindexj1);
}
}
}
}
GraphicsShape* gfxShape = new GraphicsShape;
gfxShape->m_vertices = &vertices->at(0).xyzw[0];
gfxShape->m_numvertices = vertices->size();
gfxShape->m_indices = &indicesPtr->at(0);
gfxShape->m_numIndices = indicesPtr->size();
for (int i=0;i<4;i++)
gfxShape->m_scaling[i] = 1;//bake the scaling into the vertices
return gfxShape;
}
}
GraphicsShape* createGraphicsShapeFromCompoundShape(b3CompoundShape* compound)
{
GraphicsShape* gfxShape = new GraphicsShape();
b3AlignedObjectArray<GraphicsVertex>* vertexArray = new b3AlignedObjectArray<GraphicsVertex>;
b3AlignedObjectArray<int>* indexArray = new b3AlignedObjectArray<int>;
//create a graphics shape for each child, combine them into a single graphics shape using their child transforms
for (int i=0;i<compound->getNumChildShapes();i++)
{
b3Assert(compound->getChildShape(i)->isPolyhedral());
if (compound->getChildShape(i)->isPolyhedral())
{
b3PolyhedralConvexShape* convexHull = (b3PolyhedralConvexShape*) compound->getChildShape(i);
b3Transform tr = compound->getChildTransform(i);
const b3ConvexPolyhedron* polyhedron = convexHull->getConvexPolyhedron();
GraphicsShape* childGfxShape = createGraphicsShapeFromConvexHull(polyhedron);
int baseIndex = vertexArray->size();
for (int j=0;j<childGfxShape->m_numIndices;j++)
indexArray->push_back(childGfxShape->m_indices[j]+baseIndex);
GraphicsVertex* orgVerts = (GraphicsVertex*)childGfxShape->m_vertices;
for (int j=0;j<childGfxShape->m_numvertices;j++)
{
GraphicsVertex vtx;
b3Vector3 pos(orgVerts[j].xyzw[0],orgVerts[j].xyzw[1],orgVerts[j].xyzw[2]);
pos = tr*pos;
vtx.xyzw[0] = childGfxShape->m_scaling[0]*pos.getX();
vtx.xyzw[1] = childGfxShape->m_scaling[1]*pos.getY();
vtx.xyzw[2] = childGfxShape->m_scaling[2]*pos.getZ();
vtx.xyzw[3] = 10.f;
vtx.uv[0] = 0.5f;
vtx.uv[1] = 0.5f;
b3Vector3 normal(orgVerts[j].normal[0],orgVerts[j].normal[1],orgVerts[j].normal[2]);
normal = tr.getBasis()*normal;
vtx.normal[0] = normal.getX();
vtx.normal[1] = normal.getY();
vtx.normal[2] = normal.getZ();
vertexArray->push_back(vtx);
}
}
}
b3PolyhedralConvexShape* convexHull = (b3PolyhedralConvexShape*) compound->getChildShape(0);
const b3ConvexPolyhedron* polyhedron = convexHull->getConvexPolyhedron();
GraphicsShape* childGfxShape = createGraphicsShapeFromConvexHull(polyhedron);
gfxShape->m_indices = &indexArray->at(0);
gfxShape->m_numIndices = indexArray->size();
gfxShape->m_vertices = &vertexArray->at(0).xyzw[0];
gfxShape->m_numvertices = vertexArray->size();
gfxShape->m_scaling[0] = 1;
gfxShape->m_scaling[1] = 1;
gfxShape->m_scaling[2] = 1;
gfxShape->m_scaling[3] = 1;
return gfxShape;
}
GraphicsShape* createGraphicsShapeFromConcaveMesh(const b3BvhTriangleMeshShape* trimesh)
{
b3AlignedObjectArray<GraphicsVertex>* vertices = new b3AlignedObjectArray<GraphicsVertex>;
b3AlignedObjectArray<int>* indicesPtr = new b3AlignedObjectArray<int>;
const b3StridingMeshInterface* meshInterface = trimesh->getMeshInterface();
b3Vector3 trimeshScaling(1,1,1);
for (int partId=0;partId<meshInterface->getNumSubParts();partId++)
{
const unsigned char *vertexbase = 0;
int numverts = 0;
PHY_ScalarType type = PHY_INTEGER;
int stride = 0;
const unsigned char *indexbase = 0;
int indexstride = 0;
int numfaces = 0;
PHY_ScalarType indicestype = PHY_INTEGER;
//PHY_ScalarType indexType=0;
b3Vector3 triangleVerts[3];
meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,partId);
b3Vector3 aabbMin,aabbMax;
for (int triangleIndex = 0 ; triangleIndex < numfaces;triangleIndex++)
{
unsigned int* gfxbase = (unsigned int*)(indexbase+triangleIndex*indexstride);
for (int j=2;j>=0;j--)
{
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
if (type == PHY_FLOAT)
{
float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
triangleVerts[j] = b3Vector3(
graphicsbase[0]*trimeshScaling.getX(),
graphicsbase[1]*trimeshScaling.getY(),
graphicsbase[2]*trimeshScaling.getZ());
}
else
{
double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
triangleVerts[j] = b3Vector3( b3Scalar(graphicsbase[0]*trimeshScaling.getX()),
b3Scalar(graphicsbase[1]*trimeshScaling.getY()),
b3Scalar(graphicsbase[2]*trimeshScaling.getZ()));
}
}
b3Vector3 normal = (triangleVerts[2]-triangleVerts[0]).cross(triangleVerts[1]-triangleVerts[0]);
normal.normalize();
GraphicsVertex vtx0,vtx1,vtx2;
vtx0.xyzw[0] = triangleVerts[0].getX();
vtx0.xyzw[1] = triangleVerts[0].getY();
vtx0.xyzw[2] = triangleVerts[0].getZ();
vtx0.xyzw[3] = 0;
vtx0.uv[0] = 0.5f;
vtx0.uv[1] = 0.5f;
vtx0.normal[0] = normal[0];
vtx0.normal[1] = normal[1];
vtx0.normal[2] = normal[2];
vtx1.xyzw[0] = triangleVerts[1].getX();
vtx1.xyzw[1] = triangleVerts[1].getY();
vtx1.xyzw[2] = triangleVerts[1].getZ();
vtx1.xyzw[3] = 0;
vtx1.uv[0] = 0.5f;
vtx1.uv[1] = 0.5f;
vtx1.normal[0] = normal[0];
vtx1.normal[1] = normal[1];
vtx1.normal[2] = normal[2];
vtx2.xyzw[0] = triangleVerts[2].getX();
vtx2.xyzw[1] = triangleVerts[2].getY();
vtx2.xyzw[2] = triangleVerts[2].getZ();
vtx2.xyzw[3] = 0;
vtx2.uv[0] = 0.5f;
vtx2.uv[1] = 0.5f;
vtx2.normal[0] = normal[0];
vtx2.normal[1] = normal[1];
vtx2.normal[2] = normal[2];
// triangleVerts[1]
// triangleVerts[1]
// triangleVerts[2]
vertices->push_back(vtx0);
vertices->push_back(vtx1);
vertices->push_back(vtx2);
indicesPtr->push_back(indicesPtr->size());
indicesPtr->push_back(indicesPtr->size());
indicesPtr->push_back(indicesPtr->size());
}
}
GraphicsShape* gfxShape = new GraphicsShape;
gfxShape->m_vertices = &vertices->at(0).xyzw[0];
gfxShape->m_numvertices = vertices->size();
gfxShape->m_indices = &indicesPtr->at(0);
gfxShape->m_numIndices = indicesPtr->size();
for (int i=0;i<4;i++)
gfxShape->m_scaling[i] = 1;//bake the scaling into the vertices
return gfxShape;
}
GraphicsShape* createGraphicsShapeFromWavefrontObj(objLoader* obj)
{
b3AlignedObjectArray<GraphicsVertex>* vertices = new b3AlignedObjectArray<GraphicsVertex>;
{
// int numVertices = obj->vertexCount;
// int numIndices = 0;
b3AlignedObjectArray<int>* indicesPtr = new b3AlignedObjectArray<int>;
/*
for (int v=0;v<obj->vertexCount;v++)
{
vtx.xyzw[0] = obj->vertexList[v]->e[0];
vtx.xyzw[1] = obj->vertexList[v]->e[1];
vtx.xyzw[2] = obj->vertexList[v]->e[2];
b3Vector3 n(vtx.xyzw[0],vtx.xyzw[1],vtx.xyzw[2]);
if (n.length2()>B3_EPSILON)
{
n.normalize();
vtx.normal[0] = n[0];
vtx.normal[1] = n[1];
vtx.normal[2] = n[2];
} else
{
vtx.normal[0] = 0; //todo
vtx.normal[1] = 1;
vtx.normal[2] = 0;
}
vtx.uv[0] = 0.5f;vtx.uv[1] = 0.5f; //todo
vertices->push_back(vtx);
}
*/
for (int f=0;f<obj->faceCount;f++)
{
obj_face* face = obj->faceList[f];
//b3Vector3 normal(face.m_plane[0],face.m_plane[1],face.m_plane[2]);
if (face->vertex_count>=3)
{
b3Vector3 normal(0,1,0);
int vtxBaseIndex = vertices->size();
if (face->vertex_count<=4)
{
indicesPtr->push_back(vtxBaseIndex);
indicesPtr->push_back(vtxBaseIndex+1);
indicesPtr->push_back(vtxBaseIndex+2);
GraphicsVertex vtx0;
vtx0.xyzw[0] = obj->vertexList[face->vertex_index[0]]->e[0];
vtx0.xyzw[1] = obj->vertexList[face->vertex_index[0]]->e[1];
vtx0.xyzw[2] = obj->vertexList[face->vertex_index[0]]->e[2];
vtx0.uv[0] = obj->textureList[face->vertex_index[0]]->e[0];
vtx0.uv[1] = obj->textureList[face->vertex_index[0]]->e[1];
GraphicsVertex vtx1;
vtx1.xyzw[0] = obj->vertexList[face->vertex_index[1]]->e[0];
vtx1.xyzw[1] = obj->vertexList[face->vertex_index[1]]->e[1];
vtx1.xyzw[2] = obj->vertexList[face->vertex_index[1]]->e[2];
vtx1.uv[0] = obj->textureList[face->vertex_index[1]]->e[0];
vtx1.uv[1] = obj->textureList[face->vertex_index[1]]->e[1];
GraphicsVertex vtx2;
vtx2.xyzw[0] = obj->vertexList[face->vertex_index[2]]->e[0];
vtx2.xyzw[1] = obj->vertexList[face->vertex_index[2]]->e[1];
vtx2.xyzw[2] = obj->vertexList[face->vertex_index[2]]->e[2];
vtx2.uv[0] = obj->textureList[face->vertex_index[2]]->e[0];
vtx2.uv[1] = obj->textureList[face->vertex_index[2]]->e[1];
b3Vector3 v0(vtx0.xyzw[0],vtx0.xyzw[1],vtx0.xyzw[2]);
b3Vector3 v1(vtx1.xyzw[0],vtx1.xyzw[1],vtx1.xyzw[2]);
b3Vector3 v2(vtx2.xyzw[0],vtx2.xyzw[1],vtx2.xyzw[2]);
normal = (v1-v0).cross(v2-v0);
normal.normalize();
vtx0.normal[0] = normal[0];
vtx0.normal[1] = normal[1];
vtx0.normal[2] = normal[2];
vtx1.normal[0] = normal[0];
vtx1.normal[1] = normal[1];
vtx1.normal[2] = normal[2];
vtx2.normal[0] = normal[0];
vtx2.normal[1] = normal[1];
vtx2.normal[2] = normal[2];
vertices->push_back(vtx0);
vertices->push_back(vtx1);
vertices->push_back(vtx2);
}
if (face->vertex_count==4)
{
indicesPtr->push_back(vtxBaseIndex);
indicesPtr->push_back(vtxBaseIndex+1);
indicesPtr->push_back(vtxBaseIndex+2);
indicesPtr->push_back(vtxBaseIndex+3);
//
GraphicsVertex vtx3;
vtx3.xyzw[0] = obj->vertexList[face->vertex_index[3]]->e[0];
vtx3.xyzw[1] = obj->vertexList[face->vertex_index[3]]->e[1];
vtx3.xyzw[2] = obj->vertexList[face->vertex_index[3]]->e[2];
vtx3.uv[0] = 0.5;
vtx3.uv[1] = 0.5;
vtx3.normal[0] = normal[0];
vtx3.normal[1] = normal[1];
vtx3.normal[2] = normal[2];
vertices->push_back(vtx3);
}
}
}
GraphicsShape* gfxShape = new GraphicsShape;
gfxShape->m_vertices = &vertices->at(0).xyzw[0];
gfxShape->m_numvertices = vertices->size();
gfxShape->m_indices = &indicesPtr->at(0);
gfxShape->m_numIndices = indicesPtr->size();
for (int i=0;i<4;i++)
gfxShape->m_scaling[i] = 1;//bake the scaling into the vertices
return gfxShape;
}
}
//very incomplete conversion from physics to graphics
void graphics_from_physics(GLInstancingRenderer& renderer, bool syncTransformsOnly, int numObjects, b3CollisionObject** colObjArray)
{
///@todo: we need to sort the objects based on collision shape type, so we can share instances
B3_PROFILE("graphics_from_physics");
int strideInBytes = sizeof(float)*9;
int prevGraphicsShapeIndex = -1;
b3CollisionShape* prevShape = 0;
int numColObj = numObjects;
int curGraphicsIndex = 0;
float localScaling[4] = {1,1,1,1};
for (int i=0;i<numColObj;i++)
{
b3CollisionObject* colObj = colObjArray[i];
b3Vector3 pos = colObj->getWorldTransform().getOrigin();
b3Quaternion orn = colObj->getWorldTransform().getRotation();
float position[4] = {pos.getX(),pos.getY(),pos.getZ(),0.f};
float orientation[4] = {orn.getX(),orn.getY(),orn.getZ(),orn.getW()};
float color[4] = {0,0,0,1};
b3Vector3 localScaling = colObj->getCollisionShape()->getLocalScaling();
if (colObj->isStaticOrKinematicObject())
{
color[0]=1.f;
}else
{
color[1]=1.f;
}
if (!syncTransformsOnly)
{
if (prevShape != colObj->getCollisionShape())
{
if (colObj->getCollisionShape()->isPolyhedral())
{
b3PolyhedralConvexShape* polyShape = (b3PolyhedralConvexShape*)colObj->getCollisionShape();
const b3ConvexPolyhedron* pol = polyShape->getConvexPolyhedron();
GraphicsShape* gfxShape = createGraphicsShapeFromConvexHull(pol);
prevGraphicsShapeIndex = renderer.registerShape(&gfxShape->m_vertices[0],gfxShape->m_numvertices,gfxShape->m_indices,gfxShape->m_numIndices);
prevShape = colObj->getCollisionShape();
const b3Vector3& scaling = prevShape->getLocalScaling();
localScaling[0] = scaling.getX();localScaling[1] = scaling.getY();localScaling[2] = scaling.getZ();
} else
{
if (colObj->getCollisionShape()->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
{
b3BvhTriangleMeshShape* trimesh = (b3BvhTriangleMeshShape*) colObj->getCollisionShape();
GraphicsShape* gfxShape = createGraphicsShapeFromConcaveMesh(trimesh);
prevGraphicsShapeIndex = renderer.registerShape(&gfxShape->m_vertices[0],gfxShape->m_numvertices,gfxShape->m_indices,gfxShape->m_numIndices);
prevShape = colObj->getCollisionShape();
const b3Vector3& scaling = prevShape->getLocalScaling();
localScaling[0] = scaling.getX();localScaling[1] = scaling.getY();localScaling[2] = scaling.getZ();
} else
{
if (colObj->getCollisionShape()->getShapeType()==COMPOUND_SHAPE_PROXYTYPE)
{
b3CompoundShape* compound = (b3CompoundShape*) colObj->getCollisionShape();
GraphicsShape* gfxShape = createGraphicsShapeFromCompoundShape(compound);
if (gfxShape)
{
prevGraphicsShapeIndex = renderer.registerShape(&gfxShape->m_vertices[0],gfxShape->m_numvertices,gfxShape->m_indices,gfxShape->m_numIndices);
prevShape = colObj->getCollisionShape();
const b3Vector3& scaling = prevShape->getLocalScaling();
localScaling[0] = scaling.getX();localScaling[1] = scaling.getY();localScaling[2] = scaling.getZ();
} else
{
prevGraphicsShapeIndex = -1;
}
} else
{
if (colObj->getCollisionShape()->getShapeType()==SPHERE_SHAPE_PROXYTYPE)
{
b3SphereShape* sphere = (b3SphereShape*) colObj->getCollisionShape();
b3Scalar radius = sphere->getRadius();
//b3ConvexHullShape* spherePoly = new b3ConvexHullShape(
//const b3ConvexPolyhedron* pol = polyShape->getConvexPolyhedron();
/*
objLoader loader;
int result = loader.load("../../bin/wavefront/sphere_low.obj");
GraphicsShape* gfxShape = createGraphicsShapeFromWavefrontObj(&loader);
int vertexStrideInBytes = 9*sizeof(float);
printf("vertices (%d):\n",gfxShape->m_numvertices);
for (int i=0;i<gfxShape->m_numvertices;i++)
{
gfxShape->m_vertices[i*9+4] = gfxShape->m_vertices[i*9];
gfxShape->m_vertices[i*9+5] = gfxShape->m_vertices[i*9+1];
gfxShape->m_vertices[i*9+6] = gfxShape->m_vertices[i*9+2];
printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,\n",
gfxShape->m_vertices[i*9],
gfxShape->m_vertices[i*9+1],
gfxShape->m_vertices[i*9+2],
0.f,//gfxShape->m_vertices[i*9+3],
//gfxShape->m_vertices[i*9+4],//face normals
//gfxShape->m_vertices[i*9+5],
//gfxShape->m_vertices[i*9+6],
gfxShape->m_vertices[i*9+0],
gfxShape->m_vertices[i*9+1],
gfxShape->m_vertices[i*9+2],
gfxShape->m_vertices[i*9+7],
gfxShape->m_vertices[i*9+8]);
}
printf("indices (%d):\n",gfxShape->m_numIndices);
for (int i=0;i<gfxShape->m_numIndices/3;i++)
{
printf("%d,%d,%d,\n",gfxShape->m_indices[i*3],
gfxShape->m_indices[i*3+1],
gfxShape->m_indices[i*3+2]);
}
prevGraphicsShapeIndex = renderer.registerShape(&gfxShape->m_vertices[0],gfxShape->m_numvertices,gfxShape->m_indices,gfxShape->m_numIndices);
*/
if (radius>=100)
{
int numVertices = sizeof(detailed_sphere_vertices)/strideInBytes;
int numIndices = sizeof(detailed_sphere_indices)/sizeof(int);
prevGraphicsShapeIndex = renderer.registerShape(&detailed_sphere_vertices[0],numVertices,detailed_sphere_indices,numIndices);
} else
{
bool usePointSprites = true;
if (usePointSprites)
{
int numVertices = sizeof(point_sphere_vertices)/strideInBytes;
int numIndices = sizeof(point_sphere_indices)/sizeof(int);
prevGraphicsShapeIndex = renderer.registerShape(&point_sphere_vertices[0],numVertices,point_sphere_indices,numIndices,B3_GL_POINTS);
} else
{
if (radius>=10)
{
int numVertices = sizeof(medium_sphere_vertices)/strideInBytes;
int numIndices = sizeof(medium_sphere_indices)/sizeof(int);
prevGraphicsShapeIndex = renderer.registerShape(&medium_sphere_vertices[0],numVertices,medium_sphere_indices,numIndices);
} else
{
int numVertices = sizeof(low_sphere_vertices)/strideInBytes;
int numIndices = sizeof(low_sphere_indices)/sizeof(int);
prevGraphicsShapeIndex = renderer.registerShape(&low_sphere_vertices[0],numVertices,low_sphere_indices,numIndices);
}
}
}
prevShape = sphere;
const b3Vector3& scaling = prevShape->getLocalScaling();
//assume uniform scaling, using X component
float sphereScale = radius*scaling.getX();
localScaling[0] = sphereScale;
localScaling[1] = sphereScale;
localScaling[2] = sphereScale;
} else
{
if (colObj->getCollisionShape()->getShapeType()==STATIC_PLANE_PROXYTYPE)
{
b3StaticPlaneShape* plane= (b3StaticPlaneShape*) colObj->getCollisionShape();
prevShape = colObj->getCollisionShape();
//plane->getPlaneNormal()
//plane->getPlaneConstant()
if (1)
{
int numVertices = sizeof(quad_vertices)/strideInBytes;
int numIndices = sizeof(quad_indices)/sizeof(int);
prevGraphicsShapeIndex = renderer.registerShape(&quad_vertices[0],numVertices,quad_indices,numIndices);
} else
{
int numVertices = sizeof(detailed_sphere_vertices)/strideInBytes;
int numIndices = sizeof(detailed_sphere_indices)/sizeof(int);
prevGraphicsShapeIndex = renderer.registerShape(&detailed_sphere_vertices[0],numVertices,detailed_sphere_indices,numIndices);
}
localScaling[0] = 100;
localScaling[1] = 1;
localScaling[2] = 100;
} else
{
printf("Error: unsupported collision shape type in %s %d\n", __FILE__, __LINE__);
prevGraphicsShapeIndex = -1;
b3Assert(0);
}
}
}
}
}
}
}
{
if (!syncTransformsOnly)
{
if (prevShape && prevGraphicsShapeIndex>=0)
{
renderer.registerGraphicsInstance(prevGraphicsShapeIndex,position,orientation,color,localScaling);
}
}
else
{
renderer.writeSingleInstanceTransformToCPU(position,orientation,curGraphicsIndex);
}
curGraphicsIndex++;
}
}
}
void OpenGL3CoreRenderer::renderPhysicsWorld(int numObjects, b3CollisionObject** colObjArray, bool syncOnly)
{
//sync changes from physics world to render world
//for now, we don't deal with adding/removing objects to the world during the simulation, to keep the rendererer simpler
m_instancingRenderer->writeTransforms();
graphics_from_physics(*m_instancingRenderer,syncOnly,numObjects, colObjArray);
//render
m_instancingRenderer->RenderScene();
}

View File

@@ -0,0 +1,26 @@
#ifndef OPENGL3_CORE_RENDERER_H
#define OPENGL3_CORE_RENDERER_H
class b3CollisionObject;
class GLInstancingRenderer;
class OpenGL3CoreRenderer
{
GLInstancingRenderer* m_instancingRenderer;
public:
OpenGL3CoreRenderer();
virtual ~OpenGL3CoreRenderer();
void init();
void reshape(int w, int h);
void keyboardCallback(unsigned char key);
void renderPhysicsWorld(int numObjects, b3CollisionObject** colObjArray, bool syncOnly);
GLInstancingRenderer* getInstancingRenderer()
{
return m_instancingRenderer;
}
};
#endif //OPENGL3_CORE_RENDERER_H

View File

@@ -0,0 +1,17 @@
#include "b3CpuDynamicsWorld.h"
#include "b3BulletDynamicsCommon.h"
b3CpuDynamicsWorld::b3CpuDynamicsWorld()
:b3DiscreteDynamicsWorld(
new b3CollisionDispatcher(new b3DefaultCollisionConfiguration()),
new b3DynamicBvhBroadphase(),new b3SequentialImpulseConstraintSolver(),
new b3DefaultCollisionConfiguration()//todo: remove this!
)
{
}
b3CpuDynamicsWorld::~b3CpuDynamicsWorld()
{
}

View File

@@ -0,0 +1,24 @@
#ifndef B3_CPU_DYNAMICS_WORLD_H
#define B3_CPU_DYNAMICS_WORLD_H
class b3DefaultCollisionConfiguration;
class b3CollisionDispatcher;
struct b3DynamicBvhBroadphase;
class b3SequentialImpulseConstraintSolver;
#include "BulletDynamics/Dynamics/b3DiscreteDynamicsWorld.h"
class b3CpuDynamicsWorld : public b3DiscreteDynamicsWorld
{
public:
b3CpuDynamicsWorld();
virtual ~b3CpuDynamicsWorld();
};
#endif //B3_CPU_DYNAMICS_WORLD_H

View File

@@ -0,0 +1,300 @@
#include "b3GpuDynamicsWorld.h"
#include "BulletDynamics/Dynamics/b3RigidBody.h"
#include "../../../opencl/gpu_rigidbody_pipeline2/CLPhysicsDemo.h"
#include "../../../opencl/gpu_rigidbody_pipeline/b3GpuNarrowPhaseAndSolver.h"
#include "BulletCollision/CollisionShapes/b3PolyhedralConvexShape.h"
#include "BulletCollision/CollisionShapes/b3BvhTriangleMeshShape.h"
#include "BulletCollision/CollisionShapes/b3CompoundShape.h"
#include "BulletCollision/CollisionShapes/b3SphereShape.h"
#include "BulletCollision/CollisionShapes/b3StaticPlaneShape.h"
#include "LinearMath/b3Quickprof.h"
#ifdef _WIN32
#include <wiNdOws.h>
#endif
b3GpuDynamicsWorld::b3GpuDynamicsWorld(int preferredOpenCLPlatformIndex,int preferredOpenCLDeviceIndex)
:b3DynamicsWorld(0,0,0),
m_gravity(0,-10,0),
m_once(true)
{
m_gpuPhysics = new CLPhysicsDemo(512*1024, MAX_CONVEX_BODIES_CL);
bool useInterop = false;
///platform and device are swapped, todo: fix this and make it consistent
m_gpuPhysics->init(preferredOpenCLDeviceIndex,preferredOpenCLPlatformIndex,useInterop);
}
b3GpuDynamicsWorld::~b3GpuDynamicsWorld()
{
delete m_gpuPhysics;
}
void b3GpuDynamicsWorld::exitOpenCL()
{
}
int b3GpuDynamicsWorld::stepSimulation( b3Scalar timeStep,int maxSubSteps, b3Scalar fixedTimeStep)
{
#ifndef B3_NO_PROFILE
// b3ProfileManager::Reset();
#endif //B3_NO_PROFILE
B3_PROFILE("stepSimulation");
//convert all shapes now, and if any change, reset all (todo)
if (m_once)
{
m_once = false;
m_gpuPhysics->writeBodiesToGpu();
}
m_gpuPhysics->stepSimulation();
{
{
B3_PROFILE("readbackBodiesToCpu");
//now copy info back to rigid bodies....
m_gpuPhysics->readbackBodiesToCpu();
}
{
B3_PROFILE("scatter transforms into rigidbody (CPU)");
for (int i=0;i<this->m_collisionObjects.size();i++)
{
b3Vector3 pos;
b3Quaternion orn;
m_gpuPhysics->getObjectTransformFromCpu(&pos[0],&orn[0],i);
b3Transform newTrans;
newTrans.setOrigin(pos);
newTrans.setRotation(orn);
this->m_collisionObjects[i]->setWorldTransform(newTrans);
}
}
}
#ifndef B3_NO_PROFILE
//b3ProfileManager::Increment_Frame_Counter();
#endif //B3_NO_PROFILE
return 1;
}
void b3GpuDynamicsWorld::setGravity(const b3Vector3& gravity)
{
}
int b3GpuDynamicsWorld::findOrRegisterCollisionShape(const b3CollisionShape* colShape)
{
int index = m_uniqueShapes.findLinearSearch(colShape);
if (index==m_uniqueShapes.size())
{
if (colShape->isPolyhedral())
{
m_uniqueShapes.push_back(colShape);
b3PolyhedralConvexShape* convex = (b3PolyhedralConvexShape*)colShape;
int numVertices=convex->getNumVertices();
int strideInBytes=sizeof(b3Vector3);
b3AlignedObjectArray<b3Vector3> tmpVertices;
tmpVertices.resize(numVertices);
for (int i=0;i<numVertices;i++)
convex->getVertex(i,tmpVertices[i]);
const float scaling[4]={1,1,1,1};
bool noHeightField=true;
int gpuShapeIndex = m_gpuPhysics->registerConvexPolyhedron(&tmpVertices[0].getX(), strideInBytes, numVertices, scaling, noHeightField);
m_uniqueShapeMapping.push_back(gpuShapeIndex);
} else
{
if (colShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
{
m_uniqueShapes.push_back(colShape);
b3BvhTriangleMeshShape* trimesh = (b3BvhTriangleMeshShape*) colShape;
b3StridingMeshInterface* meshInterface = trimesh->getMeshInterface();
b3AlignedObjectArray<b3Vector3> vertices;
b3AlignedObjectArray<int> indices;
b3Vector3 trimeshScaling(1,1,1);
for (int partId=0;partId<meshInterface->getNumSubParts();partId++)
{
const unsigned char *vertexbase = 0;
int numverts = 0;
PHY_ScalarType type = PHY_INTEGER;
int stride = 0;
const unsigned char *indexbase = 0;
int indexstride = 0;
int numfaces = 0;
PHY_ScalarType indicestype = PHY_INTEGER;
//PHY_ScalarType indexType=0;
b3Vector3 triangleVerts[3];
meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,partId);
b3Vector3 aabbMin,aabbMax;
for (int triangleIndex = 0 ; triangleIndex < numfaces;triangleIndex++)
{
unsigned int* gfxbase = (unsigned int*)(indexbase+triangleIndex*indexstride);
for (int j=2;j>=0;j--)
{
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
if (type == PHY_FLOAT)
{
float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
triangleVerts[j] = b3Vector3(
graphicsbase[0]*trimeshScaling.getX(),
graphicsbase[1]*trimeshScaling.getY(),
graphicsbase[2]*trimeshScaling.getZ());
}
else
{
double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
triangleVerts[j] = b3Vector3( b3Scalar(graphicsbase[0]*trimeshScaling.getX()),
b3Scalar(graphicsbase[1]*trimeshScaling.getY()),
b3Scalar(graphicsbase[2]*trimeshScaling.getZ()));
}
}
vertices.push_back(triangleVerts[0]);
vertices.push_back(triangleVerts[1]);
vertices.push_back(triangleVerts[2]);
indices.push_back(indices.size());
indices.push_back(indices.size());
indices.push_back(indices.size());
}
}
//GraphicsShape* gfxShape = 0;//b3BulletDataExtractor::createGraphicsShapeFromWavefrontObj(objData);
//GraphicsShape* gfxShape = b3BulletDataExtractor::createGraphicsShapeFromConvexHull(&sUnitSpherePoints[0],MY_UNITSPHERE_POINTS);
float meshScaling[4] = {1,1,1,1};
//int shapeIndex = renderer.registerShape(gfxShape->m_vertices,gfxShape->m_numvertices,gfxShape->m_indices,gfxShape->m_numIndices);
float groundPos[4] = {0,0,0,0};
//renderer.registerGraphicsInstance(shapeIndex,groundPos,rotOrn,color,meshScaling);
if (vertices.size() && indices.size())
{
int gpuShapeIndex = m_gpuPhysics->registerConcaveMesh(&vertices,&indices, meshScaling);
m_uniqueShapeMapping.push_back(gpuShapeIndex);
} else
{
printf("Error: no vertices in mesh in b3GpuDynamicsWorld::addRigidBody\n");
index = -1;
b3Assert(0);
}
} else
{
if (colShape->getShapeType()==COMPOUND_SHAPE_PROXYTYPE)
{
b3CompoundShape* compound = (b3CompoundShape*) colShape;
b3AlignedObjectArray<b3GpuChildShape> childShapes;
for (int i=0;i<compound->getNumChildShapes();i++)
{
//for now, only support polyhedral child shapes
b3Assert(compound->getChildShape(i)->isPolyhedral());
b3GpuChildShape child;
child.m_shapeIndex = findOrRegisterCollisionShape(compound->getChildShape(i));
b3Vector3 pos = compound->getChildTransform(i).getOrigin();
b3Quaternion orn = compound->getChildTransform(i).getRotation();
for (int v=0;v<4;v++)
{
child.m_childPosition[v] = pos[v];
child.m_childOrientation[v] = orn[v];
}
childShapes.push_back(child);
}
index = m_uniqueShapes.size();
m_uniqueShapes.push_back(colShape);
int gpuShapeIndex = m_gpuPhysics->registerCompoundShape(&childShapes);
m_uniqueShapeMapping.push_back(gpuShapeIndex);
/*printf("Error: unsupported compound type (%d) in b3GpuDynamicsWorld::addRigidBody\n",colShape->getShapeType());
index = -1;
b3Assert(0);
*/
} else
{
if (colShape->getShapeType()==SPHERE_SHAPE_PROXYTYPE)
{
m_uniqueShapes.push_back(colShape);
b3SphereShape* sphere = (b3SphereShape*)colShape;
int gpuShapeIndex = m_gpuPhysics->registerSphereShape(sphere->getRadius());
m_uniqueShapeMapping.push_back(gpuShapeIndex);
} else
{
if (colShape->getShapeType()==STATIC_PLANE_PROXYTYPE)
{
m_uniqueShapes.push_back(colShape);
b3StaticPlaneShape* plane = (b3StaticPlaneShape*)colShape;
int gpuShapeIndex = m_gpuPhysics->registerPlaneShape(plane->getPlaneNormal(),plane->getPlaneConstant());
m_uniqueShapeMapping.push_back(gpuShapeIndex);
} else
{
printf("Error: unsupported shape type (%d) in b3GpuDynamicsWorld::addRigidBody\n",colShape->getShapeType());
index = -1;
b3Assert(0);
}
}
}
}
}
}
return index;
}
void b3GpuDynamicsWorld::addRigidBody(b3RigidBody* body)
{
body->setMotionState(0);
int index = findOrRegisterCollisionShape(body->getCollisionShape());
if (index>=0)
{
int gpuShapeIndex= m_uniqueShapeMapping[index];
float mass = body->getInvMass() ? 1.f/body->getInvMass() : 0.f;
b3Vector3 pos = body->getWorldTransform().getOrigin();
b3Quaternion orn = body->getWorldTransform().getRotation();
m_gpuPhysics->registerPhysicsInstance(mass,&pos.getX(),&orn.getX(),gpuShapeIndex,m_collisionObjects.size());
m_collisionObjects.push_back(body);
}
}
void b3GpuDynamicsWorld::removeCollisionObject(b3CollisionObject* colObj)
{
b3DynamicsWorld::removeCollisionObject(colObj);
}

View File

@@ -0,0 +1,109 @@
#ifndef B3_GPU_DYNAMICS_WORLD_H
#define B3_GPU_DYNAMICS_WORLD_H
class b3Vector3;
class b3RigidBody;
class b3CollisionObject;
struct b3GpuInternalData;//use this struct to avoid 'leaking' all OpenCL headers into clients code base
class CLPhysicsDemo;
#include "Bullet3Common/b3AlignedObjectArray.h"
//#include "BulletDynamics/Dynamics/b3DynamicsWorld.h"
class b3GpuDynamicsWorld //: public b3DynamicsWorld
{
b3AlignedObjectArray<const class b3CollisionShape*> m_uniqueShapes;
b3AlignedObjectArray<int> m_uniqueShapeMapping;
CLPhysicsDemo* m_gpuPhysics;
b3Vector3 m_gravity;
bool m_once;
bool initOpenCL(int preferredDeviceIndex, int preferredPlatformIndex, bool useInterop);
void exitOpenCL();
int findOrRegisterCollisionShape(const b3CollisionShape* colShape);
public:
b3GpuDynamicsWorld(int preferredOpenCLPlatformIndex,int preferredOpenCLDeviceIndex);
virtual ~b3GpuDynamicsWorld();
virtual int stepSimulation( b3Scalar timeStep,int maxSubSteps=1, b3Scalar fixedTimeStep=b3Scalar(1.)/b3Scalar(60.));
virtual void synchronizeMotionStates()
{
b3Assert(0);
}
void debugDrawWorld() {}
void setGravity(const b3Vector3& gravity);
void addRigidBody(b3RigidBody* body);
void removeCollisionObject(b3CollisionObject* colObj);
b3AlignedObjectArray<class b3CollisionObject*>& getCollisionObjectArray();
const b3AlignedObjectArray<class b3CollisionObject*>& getCollisionObjectArray() const;
virtual void addAction(b3ActionInterface* action)
{
b3Assert(0);
}
virtual void removeAction(b3ActionInterface* action)
{
b3Assert(0);
}
b3Vector3 getGravity () const
{
return m_gravity;
}
virtual void addRigidBody(b3RigidBody* body, short group, short mask)
{
addRigidBody(body);
}
virtual void removeRigidBody(b3RigidBody* body)
{
b3Assert(0);
}
virtual void setConstraintSolver(b3ConstraintSolver* solver)
{
b3Assert(0);
}
virtual b3ConstraintSolver* getConstraintSolver()
{
b3Assert(0);
return 0;
}
virtual b3DynamicsWorldType getWorldType() const
{
return B3_GPU_PHYSICS_WORLD;
}
virtual void clearForces()
{
b3Assert(0);
}
};
#endif //B3_GPU_DYNAMICS_WORLD_H