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

118
Demos3/GpuDemos/GpuDemo.cpp Normal file
View File

@@ -0,0 +1,118 @@
#include "GpuDemo.h"
#include "GpuDemoInternalData.h"
#include "Bullet3Common/b3Scalar.h"
#include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
#include "OpenGLWindow/ShapeData.h"
#include "OpenGLWindow/GLInstancingRenderer.h"
GpuDemo::GpuDemo()
:m_clData(0)
{
m_clData = new GpuDemoInternalData();
}
GpuDemo::~GpuDemo()
{
if (m_clData)
{
b3Assert(m_clData->m_clInitialized==false);
delete m_clData;
}
}
void GpuDemo::exitCL()
{
if (m_clData->m_clInitialized)
{
clReleaseCommandQueue(m_clData->m_clQueue);
clReleaseContext(m_clData->m_clContext);
m_clData->m_clInitialized = false;
}
}
void GpuDemo::initCL(int preferredDeviceIndex, int preferredPlatformIndex)
{
void* glCtx=0;
void* glDC = 0;
int ciErrNum = 0;
//#ifdef CL_PLATFORM_INTEL
//cl_device_type deviceType = CL_DEVICE_TYPE_ALL;
//#else
cl_device_type deviceType = CL_DEVICE_TYPE_GPU;
//#endif
cl_platform_id platformId;
// if (useInterop)
// {
// m_data->m_clContext = b3OpenCLUtils::createContextFromType(deviceType, &ciErrNum, glCtx, glDC);
// } else
{
m_clData->m_clContext = b3OpenCLUtils::createContextFromType(deviceType, &ciErrNum, 0,0,preferredDeviceIndex, preferredPlatformIndex,&platformId);
b3OpenCLUtils::printPlatformInfo(platformId);
}
oclCHECKERROR(ciErrNum, CL_SUCCESS);
int numDev = b3OpenCLUtils::getNumDevices(m_clData->m_clContext);
if (numDev>0)
{
m_clData->m_clDevice= b3OpenCLUtils::getDevice(m_clData->m_clContext,0);
m_clData->m_clQueue = clCreateCommandQueue(m_clData->m_clContext, m_clData->m_clDevice, 0, &ciErrNum);
oclCHECKERROR(ciErrNum, CL_SUCCESS);
b3OpenCLUtils::printDeviceInfo(m_clData->m_clDevice);
b3OpenCLDeviceInfo info;
b3OpenCLUtils::getDeviceInfo(m_clData->m_clDevice,&info);
m_clData->m_clDeviceName = info.m_deviceName;
m_clData->m_clInitialized = true;
}
}
int GpuDemo::registerGraphicsSphereShape(const ConstructionInfo& ci, float radius, bool usePointSprites, int largeSphereThreshold, int mediumSphereThreshold)
{
int strideInBytes = 9*sizeof(float);
int graphicsShapeIndex = -1;
if (radius>=largeSphereThreshold)
{
int numVertices = sizeof(detailed_sphere_vertices)/strideInBytes;
int numIndices = sizeof(detailed_sphere_indices)/sizeof(int);
graphicsShapeIndex = ci.m_instancingRenderer->registerShape(&detailed_sphere_vertices[0],numVertices,detailed_sphere_indices,numIndices);
} else
{
if (usePointSprites)
{
int numVertices = sizeof(point_sphere_vertices)/strideInBytes;
int numIndices = sizeof(point_sphere_indices)/sizeof(int);
graphicsShapeIndex = ci.m_instancingRenderer->registerShape(&point_sphere_vertices[0],numVertices,point_sphere_indices,numIndices,B3_GL_POINTS);
} else
{
if (radius>=mediumSphereThreshold)
{
int numVertices = sizeof(medium_sphere_vertices)/strideInBytes;
int numIndices = sizeof(medium_sphere_indices)/sizeof(int);
graphicsShapeIndex = ci.m_instancingRenderer->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);
graphicsShapeIndex = ci.m_instancingRenderer->registerShape(&low_sphere_vertices[0],numVertices,low_sphere_indices,numIndices);
}
}
}
return graphicsShapeIndex;
}

73
Demos3/GpuDemos/GpuDemo.h Normal file
View File

@@ -0,0 +1,73 @@
#ifndef GPU_DEMO_H
#define GPU_DEMO_H
class GLInstancingRenderer;
class GpuDemo
{
protected:
struct GpuDemoInternalData* m_clData;
virtual void initCL(int preferredDeviceIndex, int preferredPlatformIndex);
virtual void exitCL();
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;
class b3gWindowInterface* m_window;
class GwenUserInterface* m_gui;
ConstructionInfo()
:useOpenCL(true),
preferredOpenCLPlatformIndex(-1),
preferredOpenCLDeviceIndex(-1),
arraySizeX(20),
arraySizeY(20),
arraySizeZ(20),
m_useConcaveMesh(false),
gapX(14.3),
gapY(14.0),
gapZ(14.3),
m_instancingRenderer(0),
m_window(0),
m_gui(0)
{
}
};
GpuDemo();
virtual ~GpuDemo();
virtual const char* getName()=0;
virtual void initPhysics(const ConstructionInfo& ci)=0;
virtual void exitPhysics()=0;
virtual void renderScene()=0;
virtual void clientMoveAndDisplay()=0;
int registerGraphicsSphereShape(const ConstructionInfo& ci, float radius, bool usePointSprites=true, int largeSphereThreshold=100, int mediumSphereThreshold=10);
};
#endif

View File

@@ -0,0 +1,22 @@
#ifndef GPU_DEMO_INTERNAL_DATA_H
#define GPU_DEMO_INTERNAL_DATA_H
#include "Bullet3OpenCL/Initialize/b3OpenCLInclude.h"
struct GpuDemoInternalData
{
cl_context m_clContext;
cl_device_id m_clDevice;
cl_command_queue m_clQueue;
bool m_clInitialized;
char* m_clDeviceName;
GpuDemoInternalData()
:m_clInitialized(false),
m_clDeviceName(0)
{
}
};
#endif

View File

@@ -0,0 +1,479 @@
#include "ParticleDemo.h"
#include "OpenGLWindow/GLInstancingRenderer.h"
#include "OpenGLWindow/ShapeData.h"
#include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
#define MSTRINGIFY(A) #A
static char* particleKernelsString =
#include "ParticleKernels.cl"
#define INTEROPKERNEL_SRC_PATH "demo/gpudemo/ParticleKernels.cl"
#include "Bullet3Common/b3Vector3.h"
#include "OpenGLWindow/OpenGLInclude.h"
#include "OpenGLWindow/GLInstanceRendererInternalData.h"
#include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h"
//#include "../../opencl/primitives/AdlPrimitives/Math/Math.h"
//#include "../../opencl/broadphase_benchmark/b3GridBroadphaseCL.h"
#include "Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.h"
#include "GpuDemoInternalData.h"
#include "Bullet3Common/b3Quickprof.h"
//1000000 particles
//#define NUM_PARTICLES_X 100
//#define NUM_PARTICLES_Y 100
//#define NUM_PARTICLES_Z 100
//512k particles
//#define NUM_PARTICLES_X 80
//#define NUM_PARTICLES_Y 80
//#define NUM_PARTICLES_Z 80
//256k particles
//#define NUM_PARTICLES_X 60
//#define NUM_PARTICLES_Y 60
//#define NUM_PARTICLES_Z 60
//27k particles
#define NUM_PARTICLES_X 30
#define NUM_PARTICLES_Y 30
#define NUM_PARTICLES_Z 30
B3_ATTRIBUTE_ALIGNED16(struct) b3SimParams
{
B3_DECLARE_ALIGNED_ALLOCATOR();
b3Vector3 m_gravity;
float m_worldMin[4];
float m_worldMax[4];
float m_particleRad;
float m_globalDamping;
float m_boundaryDamping;
float m_collisionDamping;
float m_spring;
float m_shear;
float m_attraction;
float m_dummy;
b3SimParams()
{
m_gravity.setValue(0,-0.03,0.f);
m_particleRad = 0.023f;
m_globalDamping = 1.0f;
m_boundaryDamping = -0.5f;
m_collisionDamping = 0.025f;//0.02f;
m_spring = 0.5f;
m_shear = 0.1f;
m_attraction = 0.001f;
m_worldMin[0] = -1.f;
m_worldMin[1] = -2*m_particleRad;
m_worldMin[2] =-1.f;
m_worldMax[0] = 5.f;
m_worldMax[1] = 5.f;
m_worldMax[2] = 5.f;
}
};
struct ParticleInternalData
{
cl_kernel m_updatePositionsKernel;
cl_kernel m_updatePositionsKernel2;
cl_kernel m_updateAabbsKernel;
cl_kernel m_collideParticlesKernel;
b3GpuSapBroadphase* m_broadphaseGPU;
cl_mem m_clPositionBuffer;
b3AlignedObjectArray<b3Vector3> m_velocitiesCPU;
b3OpenCLArray<b3Vector3>* m_velocitiesGPU;
b3AlignedObjectArray<b3SimParams> m_simParamCPU;
b3OpenCLArray<b3SimParams>* m_simParamGPU;
ParticleInternalData()
:
m_clPositionBuffer(0),
m_velocitiesGPU(0),
m_simParamGPU(0),
m_updatePositionsKernel(0),
m_updatePositionsKernel2(0),
m_updateAabbsKernel(0),
m_collideParticlesKernel(0)
{
m_simParamCPU.resize(1);
}
};
ParticleDemo::ParticleDemo()
:m_instancingRenderer(0)
{
m_data = new ParticleInternalData;
}
ParticleDemo::~ParticleDemo()
{
exitCL();
delete m_data;
}
void ParticleDemo::exitCL()
{
if (m_clData->m_clInitialized)
{
clReleaseKernel(m_data->m_updatePositionsKernel);
clReleaseKernel(m_data->m_updatePositionsKernel2);
clReleaseKernel(m_data->m_updateAabbsKernel);
clReleaseKernel(m_data->m_collideParticlesKernel);
}
GpuDemo::exitCL();
}
void ParticleDemo::initCL(int preferredDeviceIndex, int preferredPlatformIndex)
{
GpuDemo::initCL(preferredDeviceIndex,preferredPlatformIndex);
}
void ParticleDemo::setupScene(const ConstructionInfo& ci)
{
initCL(ci.preferredOpenCLDeviceIndex,ci.preferredOpenCLPlatformIndex);
int numParticles = NUM_PARTICLES_X*NUM_PARTICLES_Y*NUM_PARTICLES_Z;
int maxObjects = NUM_PARTICLES_X*NUM_PARTICLES_Y*NUM_PARTICLES_Z+1024;
int maxPairsSmallProxy = 32;
float radius = 3.f*m_data->m_simParamCPU[0].m_particleRad;
m_data->m_broadphaseGPU = new b3GpuSapBroadphase(m_clData->m_clContext ,m_clData->m_clDevice,m_clData->m_clQueue);//overlappingPairCache,b3Vector3(4.f, 4.f, 4.f), 128, 128, 128,maxObjects, maxObjects, maxPairsSmallProxy, 100.f, 128,
/*m_data->m_broadphaseGPU = new b3GridBroadphaseCl(overlappingPairCache,b3Vector3(radius,radius,radius), 128, 128, 128,
maxObjects, maxObjects, maxPairsSmallProxy, 100.f, 128,
m_clData->m_clContext ,m_clData->m_clDevice,m_clData->m_clQueue);
*/
m_data->m_velocitiesGPU = new b3OpenCLArray<b3Vector3>(m_clData->m_clContext,m_clData->m_clQueue,numParticles);
m_data->m_velocitiesCPU.resize(numParticles);
for (int i=0;i<numParticles;i++)
{
m_data->m_velocitiesCPU[i].setValue(0,0,0);
}
m_data->m_velocitiesGPU->copyFromHost(m_data->m_velocitiesCPU);
m_data->m_simParamGPU = new b3OpenCLArray<b3SimParams>(m_clData->m_clContext,m_clData->m_clQueue,1,false);
m_data->m_simParamGPU->copyFromHost(m_data->m_simParamCPU);
cl_int pErrNum;
cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_clData->m_clContext,m_clData->m_clDevice,particleKernelsString,0,"",INTEROPKERNEL_SRC_PATH);
m_data->m_updatePositionsKernel = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext, m_clData->m_clDevice,particleKernelsString, "updatePositionsKernel" ,&pErrNum,prog);
oclCHECKERROR(pErrNum, CL_SUCCESS);
m_data->m_updatePositionsKernel2 = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext, m_clData->m_clDevice,particleKernelsString, "integrateMotionKernel" ,&pErrNum,prog);
oclCHECKERROR(pErrNum, CL_SUCCESS);
m_data->m_updateAabbsKernel= b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext, m_clData->m_clDevice,particleKernelsString, "updateAabbsKernel" ,&pErrNum,prog);
oclCHECKERROR(pErrNum, CL_SUCCESS);
m_data->m_collideParticlesKernel = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext, m_clData->m_clDevice,particleKernelsString, "collideParticlesKernel" ,&pErrNum,prog);
oclCHECKERROR(pErrNum, CL_SUCCESS);
m_instancingRenderer = ci.m_instancingRenderer;
int strideInBytes = 9*sizeof(float);
bool pointSprite = true;
int shapeId =-1;
if (pointSprite)
{
int numVertices = sizeof(point_sphere_vertices)/strideInBytes;
int numIndices = sizeof(point_sphere_indices)/sizeof(int);
shapeId = m_instancingRenderer->registerShape(&point_sphere_vertices[0],numVertices,point_sphere_indices,numIndices,B3_GL_POINTS);
} else
{
int numVertices = sizeof(low_sphere_vertices)/strideInBytes;
int numIndices = sizeof(low_sphere_indices)/sizeof(int);
shapeId = m_instancingRenderer->registerShape(&low_sphere_vertices[0],numVertices,low_sphere_indices,numIndices);
}
float position[4] = {0,0,0,0};
float quaternion[4] = {0,0,0,1};
float color[4]={1,0,0,1};
float scaling[4] = {0.023,0.023,0.023,1};
int userIndex = 0;
for (int x=0;x<NUM_PARTICLES_X;x++)
{
for (int y=0;y<NUM_PARTICLES_Y;y++)
{
for (int z=0;z<NUM_PARTICLES_Z;z++)
{
float rad = m_data->m_simParamCPU[0].m_particleRad;
position[0] = x*(rad*3);
position[1] = y*(rad*3);
position[2] = z*(rad*3);
color[0] = float(x)/float(NUM_PARTICLES_X);
color[1] = float(y)/float(NUM_PARTICLES_Y);
color[2] = float(z)/float(NUM_PARTICLES_Z);
int id = m_instancingRenderer->registerGraphicsInstance(shapeId,position,quaternion,color,scaling);
void* userPtr = (void*)userIndex;
int collidableIndex = userIndex;
b3Vector3 aabbMin,aabbMax;
b3Vector3 particleRadius(rad,rad,rad);
aabbMin = b3Vector3(position[0],position[1],position[2])-particleRadius;
aabbMax = b3Vector3(position[0],position[1],position[2])+particleRadius;
m_data->m_broadphaseGPU->createProxy(aabbMin,aabbMax,collidableIndex,1,1);
userIndex++;
}
}
}
m_data->m_broadphaseGPU->writeAabbsToGpu();
float camPos[4]={1.5,0.5,2.5,0};
m_instancingRenderer->setCameraTargetPosition(camPos);
m_instancingRenderer->setCameraDistance(4);
m_instancingRenderer->writeTransforms();
}
void ParticleDemo::initPhysics(const ConstructionInfo& ci)
{
setupScene(ci);
}
void ParticleDemo::exitPhysics()
{
}
void ParticleDemo::renderScene()
{
if (m_instancingRenderer)
{
m_instancingRenderer->RenderScene();
}
}
void ParticleDemo::clientMoveAndDisplay()
{
int numParticles = NUM_PARTICLES_X*NUM_PARTICLES_Y*NUM_PARTICLES_Z;
GLuint vbo = m_instancingRenderer->getInternalData()->m_vbo;
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glFlush();
int posArraySize = numParticles*sizeof(float)*4;
cl_bool blocking= CL_TRUE;
char* hostPtr= (char*)glMapBufferRange( GL_ARRAY_BUFFER,m_instancingRenderer->getMaxShapeCapacity(),posArraySize, GL_MAP_WRITE_BIT|GL_MAP_READ_BIT );//GL_READ_WRITE);//GL_WRITE_ONLY
GLint err = glGetError();
assert(err==GL_NO_ERROR);
glFinish();
#if 1
//do some stuff using the OpenCL buffer
bool useCpu = false;
if (useCpu)
{
float* posBuffer = (float*)hostPtr;
for (int i=0;i<numParticles;i++)
{
posBuffer[i*4+1] += 0.1;
}
}
else
{
cl_int ciErrNum;
if (!m_data->m_clPositionBuffer)
{
m_data->m_clPositionBuffer = clCreateBuffer(m_clData->m_clContext, CL_MEM_READ_WRITE,
posArraySize, 0, &ciErrNum);
clFinish(m_clData->m_clQueue);
oclCHECKERROR(ciErrNum, CL_SUCCESS);
ciErrNum = clEnqueueWriteBuffer ( m_clData->m_clQueue,m_data->m_clPositionBuffer,
blocking,0,posArraySize,hostPtr,0,0,0
);
clFinish(m_clData->m_clQueue);
}
if (0)
{
b3BufferInfoCL bInfo[] = {
b3BufferInfoCL( m_data->m_velocitiesGPU->getBufferCL(), true ),
b3BufferInfoCL( m_data->m_clPositionBuffer)
};
b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_updatePositionsKernel );
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) );
launcher.setConst( numParticles);
launcher.launch1D( numParticles);
clFinish(m_clData->m_clQueue);
}
if (1)
{
b3BufferInfoCL bInfo[] = {
b3BufferInfoCL( m_data->m_clPositionBuffer),
b3BufferInfoCL( m_data->m_velocitiesGPU->getBufferCL() ),
b3BufferInfoCL( m_data->m_simParamGPU->getBufferCL(),true)
};
b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_updatePositionsKernel2 );
launcher.setConst( numParticles);
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) );
float timeStep = 1.f/60.f;
launcher.setConst( timeStep);
launcher.launch1D( numParticles);
clFinish(m_clData->m_clQueue);
}
{
b3BufferInfoCL bInfo[] = {
b3BufferInfoCL( m_data->m_clPositionBuffer),
b3BufferInfoCL( m_data->m_broadphaseGPU->getAabbBufferWS()),
};
b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_updateAabbsKernel );
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) );
launcher.setConst( m_data->m_simParamCPU[0].m_particleRad);
launcher.setConst( numParticles);
launcher.launch1D( numParticles);
clFinish(m_clData->m_clQueue);
}
//broadphase
int numPairsGPU=0;
cl_mem pairsGPU = 0;
{
m_data->m_broadphaseGPU->calculateOverlappingPairs();
pairsGPU = m_data->m_broadphaseGPU->getOverlappingPairBuffer();
numPairsGPU = m_data->m_broadphaseGPU->getNumOverlap();
}
if (numPairsGPU)
{
b3BufferInfoCL bInfo[] = {
b3BufferInfoCL( m_data->m_clPositionBuffer),
b3BufferInfoCL( m_data->m_velocitiesGPU->getBufferCL() ),
b3BufferInfoCL( m_data->m_broadphaseGPU->getOverlappingPairBuffer(),true),
};
b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_collideParticlesKernel);
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) );
launcher.setConst( numPairsGPU);
launcher.launch1D( numPairsGPU);
clFinish(m_clData->m_clQueue);
//__kernel void collideParticlesKernel( __global float4* pPos, __global float4* pVel, __global int2* pairs, const int numPairs)
}
if (1)
{
ciErrNum = clEnqueueReadBuffer ( m_clData->m_clQueue,
m_data->m_clPositionBuffer,
blocking,
0,
posArraySize,
hostPtr,0,0,0);
//clReleaseMemObject(clBuffer);
clFinish(m_clData->m_clQueue);
}
}
#endif
glUnmapBuffer( GL_ARRAY_BUFFER);
glFlush();
/*
int numParticles = NUM_PARTICLES_X*NUM_PARTICLES_Y*NUM_PARTICLES_Z;
for (int objectIndex=0;objectIndex<numParticles;objectIndex++)
{
float pos[4]={0,0,0,0};
float orn[4]={0,0,0,1};
// m_instancingRenderer->writeSingleInstanceTransformToGPU(pos,orn,i);
{
glBindBuffer(GL_ARRAY_BUFFER, m_instancingRenderer->getInternalData()->m_vbo);
glFlush();
char* orgBase = (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_READ_WRITE);
//b3GraphicsInstance* gfxObj = m_graphicsInstances[k];
int totalNumInstances= numParticles;
int POSITION_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4);
char* base = orgBase;
int capInBytes = m_instancingRenderer->getMaxShapeCapacity();
float* positions = (float*)(base+capInBytes);
float* orientations = (float*)(base+capInBytes+ POSITION_BUFFER_SIZE);
positions[objectIndex*4+1] += 0.1f;
glUnmapBuffer( GL_ARRAY_BUFFER);
glFlush();
}
}
*/
}
// m_data->m_positionOffsetInBytes = demo.m_maxShapeBufferCapacity/4;

View File

@@ -0,0 +1,49 @@
#ifndef PARTICLE_DEMO_H
#define PARTICLE_DEMO_H
#include "GpuDemo.h"
struct GLInstancingRenderer;
class ParticleDemo : public GpuDemo
{
public:
protected:
struct ParticleInternalData* m_data;
GLInstancingRenderer* m_instancingRenderer;
virtual void initCL(int preferredDeviceIndex, int preferredPlatformIndex);
virtual void exitCL();
public:
ParticleDemo();
virtual ~ParticleDemo();
virtual void setupScene(const ConstructionInfo& ci);
virtual void initPhysics(const ConstructionInfo& ci);
virtual void exitPhysics();
virtual const char* getName()
{
return "ParticleDemo";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new ParticleDemo;
return demo;
}
virtual void renderScene();
virtual void clientMoveAndDisplay();
};
#endif //PARTICLE_DEMO_H

View File

@@ -0,0 +1,149 @@
MSTRINGIFY(
typedef struct
{
float4 m_gravity;
float4 m_worldMin;
float4 m_worldMax;
float m_particleRad;
float m_globalDamping;
float m_boundaryDamping;
float m_collisionDamping;
float m_spring;
float m_shear;
float m_attraction;
float m_dummy;
} btSimParams;
__kernel void updatePositionsKernel( __global float4* linearVelocities, __global float4* positions,const int numNodes)
{
int nodeID = get_global_id(0);
float timeStep = 0.0166666;
float BT_GPU_ANGULAR_MOTION_THRESHOLD = (0.25f * 3.14159254);
if( nodeID < numNodes )
{
positions[nodeID] += linearVelocities[nodeID]*timeStep;
}
}
__kernel void integrateMotionKernel( int numParticles,
__global float4* pPos,
__global float4* pVel,
__global const btSimParams* simParams,
float timeStep GUID_ARG)
{
int index = get_global_id(0);
if(index >= numParticles)
{
return;
}
float4 pos = pPos[index];
float4 vel = pVel[index];
pos.w = 1.0f;
vel.w = 0.0f;
// apply gravity
float4 gravity = simParams[0].m_gravity;
float particleRad = simParams[0].m_particleRad;
float globalDamping = simParams[0].m_globalDamping;
float boundaryDamping = simParams[0].m_boundaryDamping;
vel += gravity * timeStep;
vel *= globalDamping;
// integrate position
pos += vel * timeStep;
// collide with world boundaries
float4 worldMin = simParams[0].m_worldMin;
float4 worldMax = simParams[0].m_worldMax;
if(pos.x < (worldMin.x + 2*particleRad))
{
pos.x = worldMin.x + 2*particleRad;
vel.x *= boundaryDamping;
}
if(pos.x > (worldMax.x - 2*particleRad))
{
pos.x = worldMax.x - 2*particleRad;
vel.x *= boundaryDamping;
}
if(pos.y < (worldMin.y + 2*particleRad))
{
pos.y = worldMin.y + 2*particleRad;
vel.y *= boundaryDamping;
}
if(pos.y > (worldMax.y - 2*particleRad))
{
pos.y = worldMax.y - 2*particleRad;
vel.y *= boundaryDamping;
}
if(pos.z < (worldMin.z + 2*particleRad))
{
pos.z = worldMin.z + 2*particleRad;
vel.z *= boundaryDamping;
}
if(pos.z > (worldMax.z - 2*particleRad))
{
pos.z = worldMax.z - 2*particleRad;
vel.z *= boundaryDamping;
}
// write back position and velocity
pPos[index] = pos;
pVel[index] = vel;
}
typedef struct
{
float fx;
float fy;
float fz;
int uw;
} btAABBCL;
__kernel void collideParticlesKernel( __global float4* pPos, __global float4* pVel, __global int2* pairs, const int numPairs)
{
int index = get_global_id(0);
if (index<numPairs)
{
pPos[pairs[index].x].x = -30*index;
pPos[pairs[index].x].z = -30*index;
pPos[pairs[index].y].x = 30*index;
pPos[pairs[index].y].z = 30*index;
}
}
__kernel void updateAabbsKernel( __global float4* pPos, __global btAABBCL* pAABB, float particleRadius, const int numNodes)
{
int nodeID = get_global_id(0);
if( nodeID < numNodes )
{
float4 position = pPos[nodeID];
float4 extent = (float4) ( particleRadius,particleRadius,particleRadius,0.f);
pAABB[nodeID*2].fx = position.x-extent.x;
pAABB[nodeID*2].fy = position.y-extent.y;
pAABB[nodeID*2].fz = position.z-extent.z;
pAABB[nodeID*2].uw = nodeID;
pAABB[nodeID*2+1].fx = position.x+extent.x;
pAABB[nodeID*2+1].fy = position.y+extent.y;
pAABB[nodeID*2+1].fz = position.z+extent.z;
pAABB[nodeID*2+1].uw = nodeID;
}
}
);

View File

@@ -0,0 +1,351 @@
#include "PairBench.h"
#include "Bullet3Common/b3Quickprof.h"
#include "OpenGLWindow/ShapeData.h"
#include "OpenGLWindow/GLInstancingRenderer.h"
#include "Bullet3Common/b3Quaternion.h"
#include "OpenGLWindow/b3gWindowInterface.h"
#include "Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.h"
#include "../GpuDemoInternalData.h"
#include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
#include "OpenGLWindow/OpenGLInclude.h"
#include "OpenGLWindow/GLInstanceRendererInternalData.h"
#include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h"
static b3KeyboardCallback oldCallback = 0;
extern bool gReset;
#define MSTRINGIFY(A) #A
static const char* s_pairBenchKernelString = MSTRINGIFY(
__kernel void moveObjectsKernel(__global float4* posOrnColors, int numObjects)
{
int iGID = get_global_id(0);
if (iGID>=numObjects)
return;
__global float4* positions = &posOrnColors[0];
if (iGID<0.5*numObjects)
{
positions[iGID].y +=0.01f;
}
__global float4* colors = &posOrnColors[numObjects*2];
colors[iGID] = (float4)(0,0,1,1);
}
__kernel void colorPairsKernel(__global float4* posOrnColors, int numObjects, __global const int2* pairs, int numPairs)
{
int iPairId = get_global_id(0);
if (iPairId>=numPairs)
return;
__global float4* colors = &posOrnColors[numObjects*2];
int iObjectA = pairs[iPairId].x;
int iObjectB = pairs[iPairId].y;
colors[iObjectA] = (float4)(1,0,0,1);
colors[iObjectB] = (float4)(1,0,0,1);
}
__kernel void
sineWaveKernel( __global float4* posOrnColors, __global float* pBodyTimes,const int numNodes)
{
int nodeID = get_global_id(0);
float timeStepPos = 0.000166666;
float mAmplitude = 26.f;
if( nodeID < numNodes )
{
pBodyTimes[nodeID] += timeStepPos;
float4 position = posOrnColors[nodeID];
position.x = native_cos(pBodyTimes[nodeID]*2.17f)*mAmplitude + native_sin(pBodyTimes[nodeID])*mAmplitude*0.5f;
position.y = native_cos(pBodyTimes[nodeID]*1.38f)*mAmplitude + native_sin(pBodyTimes[nodeID]*mAmplitude);
position.z = native_cos(pBodyTimes[nodeID]*2.17f)*mAmplitude + native_sin(pBodyTimes[nodeID]*0.777f)*mAmplitude;
posOrnColors[nodeID] = position;
__global float4* colors = &posOrnColors[numNodes*2];
colors[nodeID] = (float4)(0,0,1,1);
}
}
typedef struct
{
float fx;
float fy;
float fz;
int uw;
} b3AABBCL;
__kernel void updateAabbSimple( __global float4* posOrnColors, const int numNodes, __global b3AABBCL* pAABB)
{
int nodeId = get_global_id(0);
if( nodeId < numNodes )
{
float4 position = posOrnColors[nodeId];
float4 halfExtents = (float4)(1.01f,1.01f,1.01f,0.f);
pAABB[nodeId*2].fx = position.x-halfExtents.x;
pAABB[nodeId*2].fy = position.y-halfExtents.y;
pAABB[nodeId*2].fz = position.z-halfExtents.z;
pAABB[nodeId*2].uw = nodeId;
pAABB[nodeId*2+1].fx = position.x+halfExtents.x;
pAABB[nodeId*2+1].fy = position.y+halfExtents.y;
pAABB[nodeId*2+1].fz = position.z+halfExtents.z;
pAABB[nodeId*2+1].uw = nodeId;
}
}
);
struct PairBenchInternalData
{
b3GpuSapBroadphase* m_broadphaseGPU;
cl_kernel m_moveObjectsKernel;
cl_kernel m_sineWaveKernel;
cl_kernel m_colorPairsKernel;
cl_kernel m_updateAabbSimple;
b3OpenCLArray<b3Vector4>* m_instancePosOrnColor;
b3OpenCLArray<float>* m_bodyTimes;
PairBenchInternalData()
:m_broadphaseGPU(0),
m_moveObjectsKernel(0),
m_sineWaveKernel(0),
m_colorPairsKernel(0),
m_instancePosOrnColor(0),
m_bodyTimes(0),
m_updateAabbSimple(0)
{
}
};
PairBench::PairBench()
:m_instancingRenderer(0),
m_window(0)
{
m_data = new PairBenchInternalData;
}
PairBench::~PairBench()
{
delete m_data;
}
static void PairKeyboardCallback(int key, int state)
{
if (key=='R' && state)
{
gReset = true;
}
//b3DefaultKeyboardCallback(key,state);
oldCallback(key,state);
}
void PairBench::initPhysics(const ConstructionInfo& ci)
{
initCL(ci.preferredOpenCLDeviceIndex,ci.preferredOpenCLPlatformIndex);
if (m_clData->m_clContext)
{
m_data->m_broadphaseGPU = new b3GpuSapBroadphase(m_clData->m_clContext,m_clData->m_clDevice,m_clData->m_clQueue);
cl_program pairBenchProg=0;
int errNum=0;
m_data->m_moveObjectsKernel = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext,m_clData->m_clDevice,s_pairBenchKernelString,"moveObjectsKernel",&errNum,pairBenchProg);
m_data->m_sineWaveKernel = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext,m_clData->m_clDevice,s_pairBenchKernelString,"sineWaveKernel",&errNum,pairBenchProg);
m_data->m_colorPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext,m_clData->m_clDevice,s_pairBenchKernelString,"colorPairsKernel",&errNum,pairBenchProg);
m_data->m_updateAabbSimple = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext,m_clData->m_clDevice,s_pairBenchKernelString,"updateAabbSimple",&errNum,pairBenchProg);
}
if (ci.m_window)
{
m_window = ci.m_window;
oldCallback = ci.m_window->getKeyboardCallback();
ci.m_window->setKeyboardCallback(PairKeyboardCallback);
}
m_instancingRenderer = ci.m_instancingRenderer;
b3ProfileManager::CleanupMemory();
int strideInBytes = 9*sizeof(float);
int numVertices = sizeof(cube_vertices)/strideInBytes;
int numIndices = sizeof(cube_vertices)/sizeof(int);
int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int group=1;
int mask=1;
int index=10;
for (int i=0;i<ci.arraySizeX;i++)
{
for (int j=0;j<ci.arraySizeY;j++)
{
for (int k=0;k<ci.arraySizeZ;k++)
{
b3Vector3 position(k*3,i*3,j*3);
b3Quaternion orn(0,0,0,1);
b3Vector4 color(0,1,0,1);
b3Vector4 scaling(1,1,1,1);
int id = ci.m_instancingRenderer->registerGraphicsInstance(shapeId,position,orn,color,scaling);
b3Vector3 aabbHalfExtents(1,1,1);
b3Vector3 aabbMin = position-aabbHalfExtents;
b3Vector3 aabbMax = position+aabbHalfExtents;
m_data->m_broadphaseGPU->createProxy(aabbMin,aabbMax,index,group,mask);
index++;
}
}
}
float camPos[4]={15.5,12.5,15.5,0};
m_instancingRenderer->setCameraTargetPosition(camPos);
m_instancingRenderer->setCameraDistance(60);
m_instancingRenderer->writeTransforms();
m_data->m_broadphaseGPU->writeAabbsToGpu();
}
void PairBench::exitPhysics()
{
delete m_data->m_broadphaseGPU;
delete m_data->m_instancePosOrnColor;
delete m_data->m_bodyTimes;
m_data->m_broadphaseGPU = 0;
m_window->setKeyboardCallback(oldCallback);
exitCL();
}
void PairBench::renderScene()
{
m_instancingRenderer->RenderScene();
}
void PairBench::clientMoveAndDisplay()
{
//color all objects blue
bool animate=true;
int numObjects= m_instancingRenderer->getInternalData()->m_totalNumInstances;
b3Vector4* positions = 0;
if (animate)
{
GLuint vbo = m_instancingRenderer->getInternalData()->m_vbo;
int arraySizeInBytes = numObjects * (3)*sizeof(b3Vector4);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
cl_bool blocking= CL_TRUE;
char* hostPtr= (char*)glMapBufferRange( GL_ARRAY_BUFFER,m_instancingRenderer->getMaxShapeCapacity(),arraySizeInBytes, GL_MAP_WRITE_BIT|GL_MAP_READ_BIT );//GL_READ_WRITE);//GL_WRITE_ONLY
GLint err = glGetError();
assert(err==GL_NO_ERROR);
positions = (b3Vector4*)hostPtr;
if (m_data->m_instancePosOrnColor && m_data->m_instancePosOrnColor->size() != 3*numObjects)
{
delete m_data->m_instancePosOrnColor;
m_data->m_instancePosOrnColor=0;
}
if (!m_data->m_instancePosOrnColor)
{
m_data->m_instancePosOrnColor = new b3OpenCLArray<b3Vector4>(m_clData->m_clContext,m_clData->m_clQueue);
m_data->m_instancePosOrnColor->resize(3*numObjects);
m_data->m_instancePosOrnColor->copyFromHostPointer(positions,3*numObjects,0);
m_data->m_bodyTimes = new b3OpenCLArray<float>(m_clData->m_clContext,m_clData->m_clQueue);
m_data->m_bodyTimes ->resize(numObjects);
b3AlignedObjectArray<float> tmp;
tmp.resize(numObjects);
for (int i=0;i<numObjects;i++)
{
tmp[i] = float(i)*(1024.f/numObjects);
}
m_data->m_bodyTimes->copyFromHost(tmp);
}
if (1)
{
if (1)
{
b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_sineWaveKernel);
launcher.setBuffer(m_data->m_instancePosOrnColor->getBufferCL() );
launcher.setBuffer(m_data->m_bodyTimes->getBufferCL() );
launcher.setConst( numObjects);
launcher.launch1D( numObjects);
clFinish(m_clData->m_clQueue);
}
else
{
b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_moveObjectsKernel);
launcher.setBuffer(m_data->m_instancePosOrnColor->getBufferCL() );
launcher.setConst( numObjects);
launcher.launch1D( numObjects);
clFinish(m_clData->m_clQueue);
}
}
}
{
b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_updateAabbSimple);
launcher.setBuffer(m_data->m_instancePosOrnColor->getBufferCL() );
launcher.setConst( numObjects);
launcher.setBuffer(m_data->m_broadphaseGPU->getAabbBufferWS());
launcher.launch1D( numObjects);
clFinish(m_clData->m_clQueue);
}
{
B3_PROFILE("calculateOverlappingPairs");
m_data->m_broadphaseGPU->calculateOverlappingPairs();
//int numPairs = m_data->m_broadphaseGPU->getNumOverlap();
//printf("numPairs = %d\n", numPairs);
}
if (animate)
{
GLint err = glGetError();
assert(err==GL_NO_ERROR);
//color overlapping objects in red
if (m_data->m_broadphaseGPU->getNumOverlap())
{
bool colorPairsOnHost = false;
if (colorPairsOnHost )
{
} else
{
int numPairs = m_data->m_broadphaseGPU->getNumOverlap();
cl_mem pairBuf = m_data->m_broadphaseGPU->getOverlappingPairBuffer();
b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_colorPairsKernel);
launcher.setBuffer(m_data->m_instancePosOrnColor->getBufferCL() );
launcher.setConst( numObjects);
launcher.setBuffer( pairBuf);
launcher.setConst( numPairs);
launcher.launch1D( numPairs);
clFinish(m_clData->m_clQueue);
}
}
m_data->m_instancePosOrnColor->copyToHostPointer(positions,3*numObjects,0);
glUnmapBuffer( GL_ARRAY_BUFFER);
err = glGetError();
assert(err==GL_NO_ERROR);
}
}

View File

@@ -0,0 +1,43 @@
#ifndef PAIR_BENCH_H
#define PAIR_BENCH_H
#include "../GpuDemo.h"
class PairBench : public GpuDemo
{
class GLInstancingRenderer* m_instancingRenderer;
class b3gWindowInterface* m_window;
struct PairBenchInternalData* m_data;
public:
PairBench();
virtual ~PairBench();
virtual void initPhysics(const ConstructionInfo& ci);
virtual void exitPhysics();
virtual const char* getName()
{
return "PairBench";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new PairBench;
return demo;
}
virtual void renderScene();
virtual void clientMoveAndDisplay();
};
#endif

View File

@@ -0,0 +1,346 @@
#include "gwenUserInterface.h"
#include "OpenGLWindow/GwenOpenGL3CoreRenderer.h"
#include "OpenGLWindow/GLPrimitiveRenderer.h"
#include "Gwen/Platform.h"
#include "Gwen/Controls/TreeControl.h"
#include "Gwen/Controls/RadioButtonController.h"
#include "Gwen/Controls/VerticalSlider.h"
#include "Gwen/Controls/HorizontalSlider.h"
#include "Gwen/Controls/GroupBox.h"
#include "Gwen/Controls/CheckBox.h"
#include "Gwen/Controls/StatusBar.h"
#include "Gwen/Controls/Button.h"
#include "Gwen/Controls/ComboBox.h"
#include "Gwen/Controls/MenuStrip.h"
#include "Gwen/Controls/Property/Text.h"
#include "Gwen/Controls/SplitterBar.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "Gwen/Gwen.h"
#include "Gwen/Align.h"
#include "Gwen/Utility.h"
#include "Gwen/Controls/WindowControl.h"
#include "Gwen/Controls/TabControl.h"
#include "Gwen/Controls/ListBox.h"
#include "Gwen/Skins/Simple.h"
//#include "Gwen/Skins/TexturedBase.h"
struct GwenInternalData
{
struct sth_stash;
class GwenOpenGL3CoreRenderer* pRenderer;
Gwen::Skin::Simple skin;
Gwen::Controls::Canvas* pCanvas;
GLPrimitiveRenderer* m_primRenderer;
Gwen::Controls::TabButton* m_demoPage;
Gwen::Controls::Label* m_rightStatusBar;
Gwen::Controls::Label* m_leftStatusBar;
b3AlignedObjectArray<struct Gwen::Event::Handler*> m_handlers;
b3ToggleButtonCallback m_toggleButtonCallback;
b3ComboBoxCallback m_comboBoxCallback;
};
GwenUserInterface::GwenUserInterface()
{
m_data = new GwenInternalData();
m_data->m_toggleButtonCallback = 0;
m_data->m_comboBoxCallback = 0;
}
GwenUserInterface::~GwenUserInterface()
{
delete m_data;
}
struct MyTestMenuBar : public Gwen::Controls::MenuStrip
{
MyTestMenuBar(Gwen::Controls::Base* pParent)
:Gwen::Controls::MenuStrip(pParent)
{
// Gwen::Controls::MenuStrip* menu = new Gwen::Controls::MenuStrip( pParent );
{
Gwen::Controls::MenuItem* pRoot = AddItem( L"File" );
pRoot = AddItem( L"View" );
// Gwen::Event::Handler* handler = GWEN_MCALL(&MyTestMenuBar::MenuItemSelect );
pRoot->GetMenu()->AddItem( L"Profiler");//,,m_profileWindow,(Gwen::Event::Handler::Function)&MyProfileWindow::MenuItemSelect);
/* pRoot->GetMenu()->AddItem( L"New", L"test16.png", GWEN_MCALL( ThisClass::MenuItemSelect ) );
pRoot->GetMenu()->AddItem( L"Load", L"test16.png", GWEN_MCALL( ThisClass::MenuItemSelect ) );
pRoot->GetMenu()->AddItem( L"Save", GWEN_MCALL( ThisClass::MenuItemSelect ) );
pRoot->GetMenu()->AddItem( L"Save As..", GWEN_MCALL( ThisClass::MenuItemSelect ) );
pRoot->GetMenu()->AddItem( L"Quit", GWEN_MCALL( ThisClass::MenuItemSelect ) );
*/
}
}
};
void GwenUserInterface::resize(int width, int height)
{
m_data->pCanvas->SetSize(width,height);
}
struct MyComboBoxHander :public Gwen::Event::Handler
{
GwenInternalData* m_data;
int m_buttonId;
MyComboBoxHander (GwenInternalData* data, int buttonId)
:m_data(data),
m_buttonId(buttonId)
{
}
void onSelect( Gwen::Controls::Base* pControl )
{
Gwen::Controls::ComboBox* but = (Gwen::Controls::ComboBox*) pControl;
Gwen::String str = Gwen::Utility::UnicodeToString( but->GetSelectedItem()->GetText());
if (m_data->m_comboBoxCallback)
(*m_data->m_comboBoxCallback)(m_buttonId,str.c_str());
}
};
struct MyButtonHander :public Gwen::Event::Handler
{
GwenInternalData* m_data;
int m_buttonId;
MyButtonHander (GwenInternalData* data, int buttonId)
:m_data(data),
m_buttonId(buttonId)
{
}
void onButtonA( Gwen::Controls::Base* pControl )
{
Gwen::Controls::Button* but = (Gwen::Controls::Button*) pControl;
int dep = but->IsDepressed();
int tog = but->GetToggleState();
if (m_data->m_toggleButtonCallback)
(*m_data->m_toggleButtonCallback)(m_buttonId,tog);
}
};
void GwenUserInterface::setStatusBarMessage(const char* message, bool isLeft)
{
Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(message);
if (isLeft)
{
m_data->m_leftStatusBar->SetText( msg);
} else
{
m_data->m_rightStatusBar->SetText( msg);
}
}
void GwenUserInterface::init(int width, int height,struct sth_stash* stash,float retinaScale)
{
m_data->m_primRenderer = new GLPrimitiveRenderer(width,height);
m_data->pRenderer = new GwenOpenGL3CoreRenderer(m_data->m_primRenderer,stash,width,height,retinaScale);
m_data->skin.SetRender( m_data->pRenderer );
m_data->pCanvas= new Gwen::Controls::Canvas( &m_data->skin );
m_data->pCanvas->SetSize( width,height);
m_data->pCanvas->SetDrawBackground( false);
m_data->pCanvas->SetBackgroundColor( Gwen::Color( 150, 170, 170, 255 ) );
MyTestMenuBar* menubar = new MyTestMenuBar(m_data->pCanvas);
Gwen::Controls::StatusBar* bar = new Gwen::Controls::StatusBar(m_data->pCanvas);
m_data->m_rightStatusBar = new Gwen::Controls::Label( bar );
m_data->m_rightStatusBar->SetWidth(width/2);
//m_data->m_rightStatusBar->SetText( L"Label Added to Right" );
bar->AddControl( m_data->m_rightStatusBar, true );
m_data->m_leftStatusBar = new Gwen::Controls::Label( bar );
//m_data->m_leftStatusBar->SetText( L"Label Added to Left" );
m_data->m_leftStatusBar->SetWidth(width/2);
bar->AddControl( m_data->m_leftStatusBar,false);
/*Gwen::Controls::GroupBox* box = new Gwen::Controls::GroupBox(m_data->pCanvas);
box->SetText("text");
box->SetName("name");
box->SetHeight(500);
*/
Gwen::Controls::ScrollControl* windowLeft= new Gwen::Controls::ScrollControl(m_data->pCanvas);
windowLeft->Dock(Gwen::Pos::Right);
windowLeft->SetWidth(150);
windowLeft->SetHeight(250);
windowLeft->SetScroll(false,true);
/*Gwen::Controls::WindowControl* windowLeft = new Gwen::Controls::WindowControl(m_data->pCanvas);
windowLeft->Dock(Gwen::Pos::Left);
windowLeft->SetTitle("title");
windowLeft->SetWidth(150);
windowLeft->SetClosable(false);
windowLeft->SetShouldDrawBackground(true);
windowLeft->SetTabable(true);
*/
//windowLeft->SetSkin(
Gwen::Controls::TabControl* tab = new Gwen::Controls::TabControl(windowLeft);
//tab->SetHeight(300);
tab->SetWidth(140);
tab->SetHeight(250);
//tab->Dock(Gwen::Pos::Left);
tab->Dock( Gwen::Pos::Fill );
//tab->SetMargin( Gwen::Margin( 2, 2, 2, 2 ) );
Gwen::UnicodeString str1(L"Main");
m_data->m_demoPage = tab->AddPage(str1);
Gwen::UnicodeString str2(L"OpenCL");
tab->AddPage(str2);
//Gwen::UnicodeString str3(L"page3");
// tab->AddPage(str3);
//but->onPress.Add(handler, &MyHander::onButtonA);
//box->Dock(Gwen::Pos::Left);
/*Gwen::Controls::WindowControl* windowBottom = new Gwen::Controls::WindowControl(m_data->pCanvas);
windowBottom->SetHeight(100);
windowBottom->Dock(Gwen::Pos::Bottom);
windowBottom->SetTitle("bottom");
*/
// Gwen::Controls::Property::Text* prop = new Gwen::Controls::Property::Text(m_data->pCanvas);
//prop->Dock(Gwen::Pos::Bottom);
/*Gwen::Controls::SplitterBar* split = new Gwen::Controls::SplitterBar(m_data->pCanvas);
split->Dock(Gwen::Pos::Center);
split->SetHeight(300);
split->SetWidth(300);
*/
/*
*/
}
void GwenUserInterface::setToggleButtonCallback(b3ToggleButtonCallback callback)
{
m_data->m_toggleButtonCallback = callback;
}
void GwenUserInterface::registerToggleButton(int buttonId, const char* name)
{
assert(m_data);
assert(m_data->m_demoPage);
Gwen::Controls::Button* but = new Gwen::Controls::Button(m_data->m_demoPage->GetPage());
///some heuristic to find the button location
int ypos = m_data->m_handlers.size()*20;
but->SetPos(10, ypos );
but->SetWidth( 100 );
//but->SetBounds( 200, 30, 300, 200 );
MyButtonHander* handler = new MyButtonHander(m_data, buttonId);
m_data->m_handlers.push_back(handler);
but->onToggle.Add(handler, &MyButtonHander::onButtonA);
but->SetIsToggle(true);
but->SetToggleState(false);
but->SetText(name);
}
void GwenUserInterface::setComboBoxCallback(b3ComboBoxCallback callback)
{
m_data->m_comboBoxCallback = callback;
}
void GwenUserInterface::registerComboBox(int comboboxId, int numItems, const char** items)
{
Gwen::Controls::ComboBox* combobox = new Gwen::Controls::ComboBox(m_data->m_demoPage->GetPage());
MyComboBoxHander* handler = new MyComboBoxHander(m_data, comboboxId);
m_data->m_handlers.push_back(handler);
combobox->onSelection.Add(handler,&MyComboBoxHander::onSelect);
int ypos = m_data->m_handlers.size()*20;
combobox->SetPos(10, ypos );
combobox->SetWidth( 100 );
//box->SetPos(120,130);
for (int i=0;i<numItems;i++)
combobox->AddItem(Gwen::Utility::StringToUnicode(items[i]));
}
void GwenUserInterface::draw(int width, int height)
{
// printf("width = %d, height=%d\n", width,height);
if (m_data->pCanvas)
{
m_data->pCanvas->SetSize(width,height);
m_data->m_primRenderer->setScreenSize(width,height);
m_data->pRenderer->resize(width,height);
m_data->pCanvas->RenderCanvas();
//restoreOpenGLState();
}
}
bool GwenUserInterface::mouseMoveCallback( float x, float y)
{
bool handled = false;
static int m_lastmousepos[2] = {0,0};
static bool isInitialized = false;
if (m_data->pCanvas)
{
if (!isInitialized)
{
isInitialized = true;
m_lastmousepos[0] = x+1;
m_lastmousepos[1] = y+1;
}
handled = m_data->pCanvas->InputMouseMoved(x,y,m_lastmousepos[0],m_lastmousepos[1]);
}
return handled;
}
bool GwenUserInterface::mouseButtonCallback(int button, int state, float x, float y)
{
bool handled = false;
if (m_data->pCanvas)
{
handled = m_data->pCanvas->InputMouseMoved(x,y,x, y);
if (button>=0)
{
handled = m_data->pCanvas->InputMouseButton(button,state);
if (handled)
{
//if (!state)
// return false;
}
}
}
return handled;
}

View File

@@ -0,0 +1,38 @@
#ifndef _GWEN_USER_INTERFACE_H
#define _GWEN_USER_INTERFACE_H
struct GwenInternalData;
typedef void (*b3ComboBoxCallback) (int combobox, const char* item);
typedef void (*b3ToggleButtonCallback)(int button, int state);
class GwenUserInterface
{
GwenInternalData* m_data;
public:
GwenUserInterface();
virtual ~GwenUserInterface();
void init(int width, int height,struct sth_stash* stash,float retinaScale);
void draw(int width, int height);
void resize(int width, int height);
bool mouseMoveCallback( float x, float y);
bool mouseButtonCallback(int button, int state, float x, float y);
void setToggleButtonCallback(b3ToggleButtonCallback callback);
void registerToggleButton(int buttonId, const char* name);
void setComboBoxCallback(b3ComboBoxCallback callback);
void registerComboBox(int buttonId, int numItems, const char** items);
void setStatusBarMessage(const char* message, bool isLeft=true);
};
#endif //_GWEN_USER_INTERFACE_H

View File

@@ -0,0 +1,738 @@
//#include "GpuDemo.h"
#ifdef _WIN32
#include <Windows.h> //for GetLocalTime/GetSystemTime
#endif
#ifdef __APPLE__
#include "OpenGLWindow/MacOpenGLWindow.h"
#elif defined _WIN32
#include "OpenGLWindow/Win32OpenGLWindow.h"
#elif defined __linux
#include "OpenGLWindow/X11OpenGLWindow.h"
#endif
#include "OpenGLWindow/GLPrimitiveRenderer.h"
#include "OpenGLWindow/GLInstancingRenderer.h"
//#include "OpenGL3CoreRenderer.h"
#include "Bullet3Common/b3Quickprof.h"
//#include "b3GpuDynamicsWorld.h"
#include <assert.h>
#include <string.h>
#include "OpenGLTrueTypeFont/fontstash.h"
#include "OpenGLTrueTypeFont/opengl_fontstashcallbacks.h"
#include "gwenUserInterface.h"
#include "ParticleDemo.h"
#include "broadphase/PairBench.h"
#include "rigidbody/GpuRigidBodyDemo.h"
#include "rigidbody/ConcaveScene.h"
#include "rigidbody/GpuConvexScene.h"
#include "rigidbody/GpuCompoundScene.h"
#include "rigidbody/GpuSphereScene.h"
#include "rigidbody/Bullet2FileDemo.h"
//#include "BroadphaseBenchmark.h"
int g_OpenGLWidth=1024;
int g_OpenGLHeight = 768;
bool dump_timings = false;
extern char OpenSansData[];
static void MyResizeCallback( float width, float height)
{
g_OpenGLWidth = width;
g_OpenGLHeight = height;
}
b3gWindowInterface* window=0;
GwenUserInterface* gui = 0;
bool gPause = false;
bool gReset = false;
enum
{
MYPAUSE=1,
MYPROFILE=2,
MYRESET,
};
enum
{
MYCOMBOBOX1 = 1,
};
b3AlignedObjectArray<const char*> demoNames;
int selectedDemo = 0;
GpuDemo::CreateFunc* allDemos[]=
{
// ConcaveCompound2Scene::MyCreateFunc,
Bullet2FileDemo::MyCreateFunc,
GpuBoxPlaneScene::MyCreateFunc,
GpuConvexPlaneScene::MyCreateFunc,
ConcaveSphereScene::MyCreateFunc,
GpuCompoundScene::MyCreateFunc,
GpuConvexScene::MyCreateFunc,
ConcaveSphereScene::MyCreateFunc,
ConcaveScene::MyCreateFunc,
ConcaveCompoundScene::MyCreateFunc,
GpuCompoundPlaneScene::MyCreateFunc,
GpuSphereScene::MyCreateFunc,
PairBench::MyCreateFunc,
//GpuRigidBodyDemo::MyCreateFunc,
//BroadphaseBenchmark::CreateFunc,
//GpuBoxDemo::CreateFunc,
//ParticleDemo::MyCreateFunc,
//GpuCompoundDemo::CreateFunc,
//EmptyDemo::CreateFunc,
};
void MyComboBoxCallback(int comboId, const char* item)
{
int numDemos = demoNames.size();
for (int i=0;i<numDemos;i++)
{
if (!strcmp(demoNames[i],item))
{
if (selectedDemo != i)
{
gReset = true;
selectedDemo = i;
printf("selected demo %s!\n", item);
}
}
}
}
void MyButtonCallback(int buttonId, int state)
{
switch (buttonId)
{
case MYPAUSE:
{
gPause =!gPause;
break;
}
case MYPROFILE:
{
dump_timings = !dump_timings;
break;
}
case MYRESET:
{
gReset=!gReset;
break;
}
default:
{
printf("hello\n");
}
}
}
static void MyMouseMoveCallback( float x, float y)
{
if (gui)
{
bool handled = gui ->mouseMoveCallback(x,y);
if (!handled)
b3DefaultMouseMoveCallback(x,y);
}
}
static void MyMouseButtonCallback(int button, int state, float x, float y)
{
if (gui)
{
bool handled = gui->mouseButtonCallback(button,state,x,y);
if (!handled)
b3DefaultMouseButtonCallback(button,state,x,y);
}
}
void MyKeyboardCallback(int key, int state)
{
if (key==B3G_ESCAPE && window)
{
window->setRequestExit();
}
b3DefaultKeyboardCallback(key,state);
}
bool enableExperimentalCpuConcaveCollision=false;
int droidRegular=0;//, droidItalic, droidBold, droidJapanese, dejavu;
sth_stash* stash=0;
sth_stash* initFont(GLPrimitiveRenderer* primRender)
{
GLint err;
struct sth_stash* stash = 0;
int datasize;
float sx,sy,dx,dy,lh;
GLuint texture;
OpenGL2RenderCallbacks* renderCallbacks = new OpenGL2RenderCallbacks(primRender);
stash = sth_create(512,512,renderCallbacks);//256,256);//,1024);//512,512);
err = glGetError();
assert(err==GL_NO_ERROR);
if (!stash)
{
fprintf(stderr, "Could not create stash.\n");
return 0;
}
#ifdef LOAD_FONT_FROM_FILE
unsigned char* data=0;
const char* fontPaths[]={
"./",
"../../bin/",
"../bin/",
"bin/"
};
int numPaths=sizeof(fontPaths)/sizeof(char*);
// Load the first truetype font from memory (just because we can).
FILE* fp = 0;
const char* fontPath ="./";
char fullFontFileName[1024];
for (int i=0;i<numPaths;i++)
{
fontPath = fontPaths[i];
//sprintf(fullFontFileName,"%s%s",fontPath,"OpenSans.ttf");//"DroidSerif-Regular.ttf");
sprintf(fullFontFileName,"%s%s",fontPath,"DroidSerif-Regular.ttf");//OpenSans.ttf");//"DroidSerif-Regular.ttf");
fp = fopen(fullFontFileName, "rb");
if (fp)
break;
}
err = glGetError();
assert(err==GL_NO_ERROR);
assert(fp);
if (fp)
{
fseek(fp, 0, SEEK_END);
datasize = (int)ftell(fp);
fseek(fp, 0, SEEK_SET);
data = (unsigned char*)malloc(datasize);
if (data == NULL)
{
assert(0);
return 0;
}
else
fread(data, 1, datasize, fp);
fclose(fp);
fp = 0;
}
if (!(droidRegular = sth_add_font_from_memory(stash, data)))
{
assert(0);
return 0;
}
err = glGetError();
assert(err==GL_NO_ERROR);
// Load the remaining truetype fonts directly.
sprintf(fullFontFileName,"%s%s",fontPath,"DroidSerif-Italic.ttf");
if (!(droidItalic = sth_add_font(stash,fullFontFileName)))
{
assert(0);
return 0;
}
sprintf(fullFontFileName,"%s%s",fontPath,"DroidSerif-Bold.ttf");
if (!(droidBold = sth_add_font(stash,fullFontFileName)))
{
assert(0);
return 0;
}
err = glGetError();
assert(err==GL_NO_ERROR);
sprintf(fullFontFileName,"%s%s",fontPath,"DroidSansJapanese.ttf");
if (!(droidJapanese = sth_add_font(stash,fullFontFileName)))
{
assert(0);
return 0;
}
#else//LOAD_FONT_FROM_FILE
char* data2 = OpenSansData;
unsigned char* data = (unsigned char*) data2;
if (!(droidRegular = sth_add_font_from_memory(stash, data)))
{
printf("error!\n");
}
#endif//LOAD_FONT_FROM_FILE
err = glGetError();
assert(err==GL_NO_ERROR);
return stash;
}
#include "OpenGLWindow/OpenGLInclude.h"
#include "Bullet3Common/b3CommandLineArgs.h"
void Usage()
{
printf("\nprogram.exe [--selected_demo=<int>] [--cl_device=<int>] [--benchmark] [--disable_opencl] [--cl_platform=<int>] [--x_dim=<int>] [--y_dim=<num>] [--z_dim=<int>] [--x_gap=<float>] [--y_gap=<float>] [--z_gap=<float>] [--use_concave_mesh] [--new_batching]\n");
};
void DumpSimulationTime(FILE* f)
{
b3ProfileIterator* profileIterator = b3ProfileManager::Get_Iterator();
profileIterator->First();
if (profileIterator->Is_Done())
return;
float accumulated_time=0,parent_time = profileIterator->Is_Root() ? b3ProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time();
int i;
int frames_since_reset = b3ProfileManager::Get_Frame_Count_Since_Reset();
//fprintf(f,"%.3f,", parent_time );
float totalTime = 0.f;
static bool headersOnce = true;
if (headersOnce)
{
headersOnce = false;
fprintf(f,"root,");
for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next())
{
float current_total_time = profileIterator->Get_Current_Total_Time();
accumulated_time += current_total_time;
float fraction = parent_time > B3_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
const char* name = profileIterator->Get_Current_Name();
fprintf(f,"%s,",name);
}
fprintf(f,"\n");
}
fprintf(f,"%.3f,",parent_time);
profileIterator->First();
for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next())
{
float current_total_time = profileIterator->Get_Current_Total_Time();
accumulated_time += current_total_time;
float fraction = parent_time > B3_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
const char* name = profileIterator->Get_Current_Name();
//if (!strcmp(name,"stepSimulation"))
{
fprintf(f,"%.3f,",current_total_time);
}
totalTime += current_total_time;
//recurse into children
}
fprintf(f,"\n");
b3ProfileManager::Release_Iterator(profileIterator);
}
///extern const char* g_deviceName;
const char* g_deviceName = "blaat";
extern bool useNewBatchingKernel;
#include "Bullet3Common/b3Vector3.h"
int main(int argc, char* argv[])
{
b3Vector3 test(1,2,3);
test.x = 1;
test.y = 4;
printf("main start");
b3CommandLineArgs args(argc,argv);
ParticleDemo::ConstructionInfo ci;
if (args.CheckCmdLineFlag("help"))
{
Usage();
return 0;
}
args.GetCmdLineArgument("selected_demo",selectedDemo);
if (args.CheckCmdLineFlag("new_batching"))
{
useNewBatchingKernel = true;
}
bool benchmark=args.CheckCmdLineFlag("benchmark");
dump_timings=args.CheckCmdLineFlag("dump_timings");
ci.useOpenCL = !args.CheckCmdLineFlag("disable_opencl");
ci.m_useConcaveMesh = true;//args.CheckCmdLineFlag("use_concave_mesh");
if (ci.m_useConcaveMesh)
{
enableExperimentalCpuConcaveCollision = true;
}
args.GetCmdLineArgument("cl_device", ci.preferredOpenCLDeviceIndex);
args.GetCmdLineArgument("cl_platform", ci.preferredOpenCLPlatformIndex);
args.GetCmdLineArgument("x_dim", ci.arraySizeX);
args.GetCmdLineArgument("y_dim", ci.arraySizeY);
args.GetCmdLineArgument("z_dim", ci.arraySizeZ);
args.GetCmdLineArgument("x_gap", ci.gapX);
args.GetCmdLineArgument("y_gap", ci.gapY);
args.GetCmdLineArgument("z_gap", ci.gapZ);
printf("Demo settings:\n");
printf("x_dim=%d, y_dim=%d, z_dim=%d\n",ci.arraySizeX,ci.arraySizeY,ci.arraySizeZ);
printf("x_gap=%f, y_gap=%f, z_gap=%f\n",ci.gapX,ci.gapY,ci.gapZ);
printf("Preferred cl_device index %d\n", ci.preferredOpenCLDeviceIndex);
printf("Preferred cl_platform index%d\n", ci.preferredOpenCLPlatformIndex);
printf("-----------------------------------------------------\n");
#ifndef B3_NO_PROFILE
b3ProfileManager::Reset();
#endif //B3_NO_PROFILE
window = new b3gDefaultOpenGLWindow();
b3gWindowConstructionInfo wci(g_OpenGLWidth,g_OpenGLHeight);
window->createWindow(wci);
window->setResizeCallback(MyResizeCallback);
window->setMouseMoveCallback(MyMouseMoveCallback);
window->setMouseButtonCallback(MyMouseButtonCallback);
window->setKeyboardCallback(MyKeyboardCallback);
window->setWindowTitle("Bullet 3.x GPU Rigid Body http://bulletphysics.org");
printf("-----------------------------------------------------\n");
#ifndef __APPLE__
glewInit();
#endif
gui = new GwenUserInterface();
printf("started GwenUserInterface");
GLPrimitiveRenderer prim(g_OpenGLWidth,g_OpenGLHeight);
stash = initFont(&prim);
gui->init(g_OpenGLWidth,g_OpenGLHeight,stash,window->getRetinaScale());
printf("init fonts");
gui->setToggleButtonCallback(MyButtonCallback);
gui->registerToggleButton(MYPAUSE,"Pause");
gui->registerToggleButton(MYPROFILE,"Profile");
gui->registerToggleButton(MYRESET,"Reset");
int numItems = sizeof(allDemos)/sizeof(ParticleDemo::CreateFunc*);
demoNames.clear();
for (int i=0;i<numItems;i++)
{
GpuDemo* demo = allDemos[i]();
demoNames.push_back(demo->getName());
delete demo;
}
gui->registerComboBox(MYCOMBOBOX1,numItems,&demoNames[0]);
gui->setComboBoxCallback(MyComboBoxCallback);
do
{
bool syncOnly = false;
gReset = false;
static bool once=true;
glClearColor(1,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
{
window->startRendering();
glFinish();
float color[4] = {1,1,1,1};
prim.drawRect(0,0,200,200,color);
float retinaScale = 1;
float x = 10;
float y=220;
float dx=0;
if (1)
{
B3_PROFILE("font sth_draw_text");
glEnable(GL_BLEND);
GLint err = glGetError();
assert(err==GL_NO_ERROR);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
err = glGetError();
assert(err==GL_NO_ERROR);
glDisable(GL_DEPTH_TEST);
err = glGetError();
assert(err==GL_NO_ERROR);
glDisable(GL_CULL_FACE);
sth_begin_draw(stash);
sth_flush_draw(stash);
sth_draw_text(stash, droidRegular,20.f, x, y, "Non-retina font rendering !@#$", &dx,g_OpenGLWidth,g_OpenGLHeight,0,1);//retinaScale);
if (retinaScale!=1.f)
sth_draw_text(stash, droidRegular,20.f*retinaScale, x, y+20, "Retina font rendering!@#$", &dx,g_OpenGLWidth,g_OpenGLHeight,0,retinaScale);
sth_flush_draw(stash);
sth_end_draw(stash);
}
gui->draw(g_OpenGLWidth,g_OpenGLHeight);
window->endRendering();
glFinish();
}
once=false;
// OpenGL3CoreRenderer render;
glClearColor(0,1,0,1);
glClear(GL_COLOR_BUFFER_BIT);
window->endRendering();
glFinish();
window->setWheelCallback(b3DefaultWheelCallback);
{
GpuDemo* demo = allDemos[selectedDemo]();
// demo->myinit();
bool useGpu = false;
int maxObjectCapacity=256*1024;
ci.m_instancingRenderer = new GLInstancingRenderer(maxObjectCapacity);//render.getInstancingRenderer();
ci.m_window = window;
ci.m_gui = gui;
ci.m_instancingRenderer->init();
ci.m_instancingRenderer->InitShaders();
// render.init();
demo->initPhysics(ci);
printf("-----------------------------------------------------\n");
FILE* f = 0;
if (benchmark)
{
gPause = false;
char fileName[1024];
#ifdef _WIN32
SYSTEMTIME time;
GetLocalTime(&time);
char buf[1024];
DWORD dwCompNameLen = 1024;
if (0 != GetComputerName(buf, &dwCompNameLen))
{
printf("%s", buf);
} else
{
printf("unknown", buf);
}
sprintf(fileName,"%s_%s_%s_%d_%d_%d_date_%d-%d-%d_time_%d-%d-%d.csv",g_deviceName,buf,demoNames[selectedDemo],ci.arraySizeX,ci.arraySizeY,ci.arraySizeZ,time.wDay,time.wMonth,time.wYear,time.wHour,time.wMinute,time.wSecond);
printf("Open file %s\n", fileName);
#else
sprintf(fileName,"%s_%d_%d_%d.csv",g_deviceName,ci.arraySizeX,ci.arraySizeY,ci.arraySizeZ);
printf("Open file %s\n", fileName);
#endif
//GetSystemTime(&time2);
f=fopen(fileName,"w");
//if (f)
// fprintf(f,"%s (%dx%dx%d=%d),\n", g_deviceName,ci.arraySizeX,ci.arraySizeY,ci.arraySizeZ,ci.arraySizeX*ci.arraySizeY*ci.arraySizeZ);
}
printf("-----------------------------------------------------\n");
do
{
b3ProfileManager::Reset();
b3ProfileManager::Increment_Frame_Counter();
// render.reshape(g_OpenGLWidth,g_OpenGLHeight);
window->startRendering();
glClearColor(0.6,0.6,0.6,1);
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
if (!gPause)
{
B3_PROFILE("clientMoveAndDisplay");
demo->clientMoveAndDisplay();
}
else
{
}
{
B3_PROFILE("renderScene");
demo->renderScene();
}
/*if (demo->getDynamicsWorld() && demo->getDynamicsWorld()->getNumCollisionObjects())
{
B3_PROFILE("renderPhysicsWorld");
b3AlignedObjectArray<b3CollisionObject*> arr = demo->getDynamicsWorld()->getCollisionObjectArray();
b3CollisionObject** colObjArray = &arr[0];
render.renderPhysicsWorld(demo->getDynamicsWorld()->getNumCollisionObjects(),colObjArray, syncOnly);
syncOnly = true;
}
*/
{
B3_PROFILE("gui->draw");
gui->draw(g_OpenGLWidth,g_OpenGLHeight);
}
{
B3_PROFILE("window->endRendering");
window->endRendering();
}
{
B3_PROFILE("glFinish");
}
if (dump_timings)
b3ProfileManager::dumpAll();
if (f)
{
static int count=0;
if (count>2 && count<102)
{
DumpSimulationTime(f);
}
if (count>=102)
window->setRequestExit();
count++;
}
} while (!window->requestedExit() && !gReset);
demo->exitPhysics();
b3ProfileManager::CleanupMemory();
delete demo;
if (f)
fclose(f);
}
} while (gReset);
gui->setComboBoxCallback(0);
delete gui;
gui=0;
window->closeWindow();
delete window;
window = 0;
return 0;
}

View File

@@ -0,0 +1,94 @@
function createProject(vendor)
hasCL = findOpenCL(vendor)
if (hasCL) then
project ("App_Bullet3_OpenCL_Demos_" .. vendor)
initOpenCL(vendor)
language "C++"
kind "ConsoleApp"
targetdir "../../bin"
initOpenGL()
initGlew()
includedirs {
"..",
"../../src",
"../../btgui"
}
links {
"gwen",
"Bullet3Common",
"Bullet3Geometry",
"Bullet3Collision",
"Bullet3Dynamics",
"Bullet2FileLoader",
"Bullet3OpenCL_" .. vendor
}
files {
"**.cpp",
"**.h",
"../Wavefront/string_extra.cpp",
"../Wavefront/string_extra.h",
"../Wavefront/objLoader.cpp",
"../Wavefront/objLoader.h",
"../Wavefront/obj_parser.cpp",
"../Wavefront/obj_parser.h",
"../Wavefront/list.cpp",
"../Wavefront/list.h",
"../../btgui/OpenGLWindow/GLInstancingRenderer.cpp",
"../../btgui/OpenGLWindow/GLInstancingRenderer.h",
"../../btgui/OpenGLWindow/GLPrimitiveRenderer.cpp",
"../../btgui/OpenGLWindow/GLPrimitiveRenderer.h",
"../../btgui/OpenGLWindow/LoadShader.cpp",
"../../btgui/OpenGLWindow/LoadShader.h",
"../../btgui/OpenGLWindow/TwFonts.cpp",
"../../btgui/OpenGLWindow/TwFonts.h",
"../../btgui/OpenGLTrueTypeFont/fontstash.cpp",
"../../btgui/OpenGLTrueTypeFont/fontstash.h",
"../../btgui/OpenGLTrueTypeFont/opengl_fontstashcallbacks.cpp",
"../../btgui/OpenGLTrueTypeFont/opengl_fontstashcallbacks.h",
"../../btgui/FontFiles/OpenSans.cpp",
}
if os.is("Windows") then
files{
"../../btgui/OpenGLWindow/Win32OpenGLWindow.cpp",
"../../btgui/OpenGLWindow/Win32OpenGLWindow.h",
"../../btgui/OpenGLWindow/Win32Window.cpp",
"../../btgui/OpenGLWindow/Win32Window.h",
}
end
if os.is("Linux") then
files {
"../../btgui/OpenGLWindow/X11OpenGLWindow.cpp",
"../../btgui/OpenGLWindow/X11OpenGLWindows.h"
}
end
if os.is("MacOSX") then
links {"Cocoa.framework"}
files {
"../../btgui/OpenGLWindow/MacOpenGLWindow.h",
"../../btgui/OpenGLWindow/MacOpenGLWindow.mm",
}
end
end
end
createProject("Apple")
createProject("AMD")
createProject("Intel")
createProject("NVIDIA")

View File

@@ -0,0 +1,44 @@
#include "Bullet2FileDemo.h"
#include "BulletDataExtractor.h"
#include "GpuRigidBodyDemoInternalData.h"
#include "OpenGLWindow/GLInstancingRenderer.h"
Bullet2FileDemo::Bullet2FileDemo()
{
m_loader = 0;
}
Bullet2FileDemo::~Bullet2FileDemo()
{
delete m_loader;
}
void Bullet2FileDemo::setupScene(const ConstructionInfo& ci)
{
b3Assert(ci.m_instancingRenderer);
const char* fileName="data/testFile.bullet";
FILE* f = 0;
const char* prefix[]={"./","../","../../","../../../","../../../../"};
int numPrefixes = sizeof(prefix)/sizeof(const char*);
char relativeFileName[1024];
for (int i=0;!f && i<numPrefixes;i++)
{
sprintf(relativeFileName,"%s%s",prefix[i],fileName);
f = fopen(relativeFileName,"rb");
}
if (f)
{
fclose(f);
createScene(*ci.m_instancingRenderer,*m_data->m_np,*m_data->m_rigidBodyPipeline,relativeFileName);
}
// m_loader = new b3BulletDataExtractor(*ci.m_instancingRenderer,*m_data->m_np,*m_data->m_rigidBodyPipeline);
// m_loader->convertAllObjects(bulletFile);
b3Vector3 pos(-20,10,0);
ci.m_instancingRenderer->setCameraTargetPosition(pos);
ci.m_instancingRenderer->setCameraDistance(10);
}

View File

@@ -0,0 +1,32 @@
#ifndef BULLET2_FILE_DEMO_H
#define BULLET2_FILE_DEMO_H
#include "GpuRigidBodyDemo.h"
class Bullet2FileDemo : public GpuRigidBodyDemo
{
class b3BulletDataExtractor* m_loader;
public:
Bullet2FileDemo();
virtual ~Bullet2FileDemo();
virtual const char* getName()
{
return "Bullet2File";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new Bullet2FileDemo;
return demo;
}
virtual void setupScene(const ConstructionInfo& ci);
};
#endif//BULLET2_FILE_DEMO_H

View File

@@ -0,0 +1,768 @@
int NUM_OBJECTS_X = 20;
int NUM_OBJECTS_Y = 20;
int NUM_OBJECTS_Z = 20;
float X_GAP = 2.3f;
float Y_GAP = 2.f;
float Z_GAP = 2.3f;
#include "BulletDataExtractor.h"
#include "Bullet3Serialize/Bullet2FileLoader/b3BulletFile.h"
bool keepStaticObjects = true;
extern bool enableExperimentalCpuConcaveCollision;
#include <stdio.h>
#include "OpenGLWindow/OpenGLInclude.h"
#include "OpenGLWindow/GLInstancingRenderer.h"
//#include "LinearMath/b3Quickprof.h"
#include "Bullet3Common/b3Quaternion.h"
#include "Bullet3Common/b3Matrix3x3.h"
#include "Bullet3OpenCL/NarrowphaseCollision/b3ConvexUtility.h"
#include "OpenGLWindow/ShapeData.h"
#include "../../Wavefront/objLoader.h"
#include "Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipeline.h"
#include "Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.h"
///work-in-progress
///This ReadBulletSample is kept as simple as possible without dependencies to the Bullet SDK.
///It can be used to load .bullet data for other physics SDKs
///For a more complete example how to load and convert Bullet data using the Bullet SDK check out
///the Bullet/Demos/SerializeDemo and Bullet/Serialize/BulletWorldImporter
//using namespace Bullet;
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];
};
struct InstanceGroup
{
Bullet3SerializeBullet2::b3CollisionShapeData* m_shape;
int m_collisionShapeIndex;
b3AlignedObjectArray<bParse::bStructHandle*> m_rigidBodies;
};
void createScene( GLInstancingRenderer& renderer,b3GpuNarrowPhase& np, b3GpuRigidBodyPipeline& rbWorld, const char* fileName)
{
//const char* fileName="../../bin/convex-trimesh.bullet";
//const char* fileName="../../bin/1000 convex.bullet";
//const char* fileName="../../bin/1000 stack.bullet";
//const char* fileName="../../bin/3000 fall.bullet";
//const char* fileName="../../bin/testFile.bullet";
FILE* f = fopen(fileName,"rb");
if (f)
{
fclose(f);
bool verboseDumpAllTypes = false;
bParse::b3BulletFile* bulletFile2 = new bParse::b3BulletFile(fileName);
bool ok = (bulletFile2->getFlags()& bParse::FD_OK)!=0;
if (ok)
bulletFile2->parse(verboseDumpAllTypes);
else
{
printf("Error loading file %s.\n",fileName);
exit(0);
}
ok = (bulletFile2->getFlags()& bParse::FD_OK)!=0;
if (!(bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION))
{
if (!ok)
{
printf("Error parsing file %s.\n",fileName);
exit(0);
}
if (verboseDumpAllTypes)
{
bulletFile2->dumpChunks(bulletFile2->getFileDNA());
}
b3BulletDataExtractor extractor(renderer,np,rbWorld);
extractor.convertAllObjects(bulletFile2);
delete bulletFile2;
return;
} else
{
printf("Error: double precision .bullet files not supported in this demo\n");
}
delete bulletFile2;
} else
{
printf("Warning: cannot find file %s, using programmatically created scene instead.\n",fileName);
}
}
enum LocalBroadphaseNativeTypes
{
// polyhedral convex shapes
BOX_SHAPE_PROXYTYPE,
TRIANGLE_SHAPE_PROXYTYPE,
TETRAHEDRAL_SHAPE_PROXYTYPE,
CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE,
CONVEX_HULL_SHAPE_PROXYTYPE,
CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE,
CUSTOM_POLYHEDRAL_SHAPE_TYPE,
//implicit convex shapes
IMPLICIT_CONVEX_SHAPES_START_HERE,
SPHERE_SHAPE_PROXYTYPE,
MULTI_SPHERE_SHAPE_PROXYTYPE,
CAPSULE_SHAPE_PROXYTYPE,
CONE_SHAPE_PROXYTYPE,
CONVEX_SHAPE_PROXYTYPE,
CYLINDER_SHAPE_PROXYTYPE,
UNIFORM_SCALING_SHAPE_PROXYTYPE,
MINKOWSKI_SUM_SHAPE_PROXYTYPE,
MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE,
BOX_2D_SHAPE_PROXYTYPE,
CONVEX_2D_SHAPE_PROXYTYPE,
CUSTOM_CONVEX_SHAPE_TYPE,
//concave shapes
CONCAVE_SHAPES_START_HERE,
//keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!
TRIANGLE_MESH_SHAPE_PROXYTYPE,
SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE,
///used for demo integration FAST/Swift collision library and Bullet
FAST_CONCAVE_MESH_PROXYTYPE,
//terrain
TERRAIN_SHAPE_PROXYTYPE,
///Used for GIMPACT Trimesh integration
GIMPACT_SHAPE_PROXYTYPE,
///Multimaterial mesh
MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE,
EMPTY_SHAPE_PROXYTYPE,
STATIC_PLANE_PROXYTYPE,
CUSTOM_CONCAVE_SHAPE_TYPE,
CONCAVE_SHAPES_END_HERE,
COMPOUND_SHAPE_PROXYTYPE,
SOFTBODY_SHAPE_PROXYTYPE,
HFFLUID_SHAPE_PROXYTYPE,
HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE,
INVALID_SHAPE_PROXYTYPE,
MAX_BROADPHASE_COLLISION_TYPES
};
b3BulletDataExtractor::b3BulletDataExtractor(GLInstancingRenderer& renderer, b3GpuNarrowPhase& np, b3GpuRigidBodyPipeline& rbWorld)
:m_renderer(renderer), m_np(np), m_rbPipeline(rbWorld)
{
}
b3BulletDataExtractor::~b3BulletDataExtractor()
{
}
void b3BulletDataExtractor::convertAllObjects(bParse::b3BulletFile* bulletFile2)
{
int i;
for (i=0;i<bulletFile2->m_collisionShapes.size();i++)
{
Bullet3SerializeBullet2::b3CollisionShapeData* shapeData = (Bullet3SerializeBullet2::b3CollisionShapeData*)bulletFile2->m_collisionShapes[i];
if (shapeData->m_name)
printf("converting shape %s\n", shapeData->m_name);
int shapeIndex = convertCollisionShape(shapeData);
//valid conversion?
if (shapeIndex>=0)
{
InstanceGroup* group = new InstanceGroup;
group->m_shape = shapeData;
group->m_collisionShapeIndex = shapeIndex;
m_instanceGroups.push_back(group);
}
}
for (i=0;i<bulletFile2->m_rigidBodies.size();i++)
{
Bullet3SerializeBullet2::b3RigidBodyFloatData* colObjData = (Bullet3SerializeBullet2::b3RigidBodyFloatData*)bulletFile2->m_rigidBodies[i];
Bullet3SerializeBullet2::b3CollisionShapeData* shapeData = (Bullet3SerializeBullet2::b3CollisionShapeData*)colObjData->m_collisionObjectData.m_collisionShape;
for (int j=0;j<m_instanceGroups.size();j++)
{
if (m_instanceGroups[j]->m_shape == shapeData)
{
m_instanceGroups[j]->m_rigidBodies.push_back(bulletFile2->m_rigidBodies[i]);
}
}
}
//now register all objects in order
for (int i=0;i<m_instanceGroups.size();i++)
{
if (m_instanceGroups[i]->m_rigidBodies.size()>0)
{
m_renderer.registerShape(m_graphicsShapes[i]->m_vertices,m_graphicsShapes[i]->m_numvertices,m_graphicsShapes[i]->m_indices,m_graphicsShapes[i]->m_numIndices);
for (int j=0;j<m_instanceGroups[i]->m_rigidBodies.size();j++)
{
Bullet3SerializeBullet2::b3RigidBodyFloatData* colObjData = (Bullet3SerializeBullet2::b3RigidBodyFloatData*)m_instanceGroups[i]->m_rigidBodies[j];
b3Matrix3x3 mat;
mat.deSerializeFloat((const b3Matrix3x3FloatData&)colObjData->m_collisionObjectData.m_worldTransform.m_basis);
b3Quaternion orn;
mat.getRotation(orn);
float quaternion[4] = {orn[0],orn[1],orn[2],orn[3]};
float pos[4] = {colObjData->m_collisionObjectData.m_worldTransform.m_origin.m_floats[0],
colObjData->m_collisionObjectData.m_worldTransform.m_origin.m_floats[1],
colObjData->m_collisionObjectData.m_worldTransform.m_origin.m_floats[2],
0.f};
float color[4] = {0,0,0,1};
float mass = 0.f;
if (colObjData->m_inverseMass==0.f)
{
color[1] = 1;
} else
{
mass = 1.f/colObjData->m_inverseMass;
color[2] = 1;
}
if (keepStaticObjects || colObjData->m_inverseMass!=0.f)
{
m_rbPipeline.registerPhysicsInstance(mass,pos,quaternion,m_instanceGroups[i]->m_collisionShapeIndex,0,true);
m_renderer.registerGraphicsInstance(m_instanceGroups[i]->m_collisionShapeIndex,pos,quaternion,color,m_graphicsShapes[i]->m_scaling);
}
}
}
}
for (i=0;i<bulletFile2->m_collisionObjects.size();i++)
{
}
m_rbPipeline.writeAllInstancesToGpu();
}
int b3BulletDataExtractor::convertCollisionShape( Bullet3SerializeBullet2::b3CollisionShapeData* shapeData )
{
int shapeIndex = -1;
switch (shapeData->m_shapeType)
{
case STATIC_PLANE_PROXYTYPE:
{
Bullet3SerializeBullet2::b3StaticPlaneShapeData* planeData = (Bullet3SerializeBullet2::b3StaticPlaneShapeData*)shapeData;
shapeIndex = createPlaneShape(planeData->m_planeNormal,planeData->m_planeConstant, planeData->m_localScaling);
break;
}
case CYLINDER_SHAPE_PROXYTYPE:
case CAPSULE_SHAPE_PROXYTYPE:
case BOX_SHAPE_PROXYTYPE:
case SPHERE_SHAPE_PROXYTYPE:
case MULTI_SPHERE_SHAPE_PROXYTYPE:
case CONVEX_HULL_SHAPE_PROXYTYPE:
{
Bullet3SerializeBullet2::b3ConvexInternalShapeData* bsd = (Bullet3SerializeBullet2::b3ConvexInternalShapeData*)shapeData;
switch (shapeData->m_shapeType)
{
case BOX_SHAPE_PROXYTYPE:
{
shapeIndex = createBoxShape(bsd->m_implicitShapeDimensions, bsd->m_localScaling,bsd->m_collisionMargin);
break;
}
case SPHERE_SHAPE_PROXYTYPE:
{
shapeIndex = createSphereShape(bsd->m_implicitShapeDimensions.m_floats[0],bsd->m_localScaling, bsd->m_collisionMargin);
break;
}
case CONVEX_HULL_SHAPE_PROXYTYPE:
{
Bullet3SerializeBullet2::b3ConvexHullShapeData* convexData = (Bullet3SerializeBullet2::b3ConvexHullShapeData*)bsd;
int numPoints = convexData->m_numUnscaledPoints;
b3Vector3 localScaling;
localScaling.deSerializeFloat((b3Vector3FloatData&)bsd->m_localScaling);
b3AlignedObjectArray<b3Vector3> tmpPoints;
int i;
if (convexData->m_unscaledPointsFloatPtr)
{
for ( i=0;i<numPoints;i++)
{
b3Vector3 pt = b3Vector3(convexData->m_unscaledPointsFloatPtr[i].m_floats[0],
convexData->m_unscaledPointsFloatPtr[i].m_floats[1],
convexData->m_unscaledPointsFloatPtr[i].m_floats[2]);//convexData->m_unscaledPointsFloatPtr[i].m_floats[3]);
tmpPoints.push_back(pt*localScaling);
}
}
float unitScaling[4] = {1,1,1,1};
int strideInBytes = sizeof(b3Vector3);
strideInBytes = 4*sizeof(float);
int noHeightField = 1;
shapeIndex = m_np.registerConvexHullShape(&tmpPoints[0].m_floats[0],strideInBytes, numPoints,&unitScaling[0]);
printf("createConvexHull with %d vertices\n",numPoints);
GraphicsShape* gfxShape = createGraphicsShapeFromConvexHull(&tmpPoints[0],tmpPoints.size());
m_graphicsShapes.push_back(gfxShape);
return shapeIndex;
break;
}
#if 0
case CAPSULE_SHAPE_PROXYTYPE:
{
b3CapsuleShapeData* capData = (b3CapsuleShapeData*)shapeData;
switch (capData->m_upAxis)
{
case 0:
{
shape = createCapsuleShapeX(implicitShapeDimensions.getY(),2*implicitShapeDimensions.getX());
break;
}
case 1:
{
shape = createCapsuleShapeY(implicitShapeDimensions.getX(),2*implicitShapeDimensions.getY());
break;
}
case 2:
{
shape = createCapsuleShapeZ(implicitShapeDimensions.getX(),2*implicitShapeDimensions.getZ());
break;
}
default:
{
printf("error: wrong up axis for b3CapsuleShape\n");
}
};
break;
}
case CYLINDER_SHAPE_PROXYTYPE:
{
b3CylinderShapeData* cylData = (b3CylinderShapeData*) shapeData;
b3Vector3 halfExtents = implicitShapeDimensions+margin;
switch (cylData->m_upAxis)
{
case 0:
{
shape = createCylinderShapeX(halfExtents.getY(),halfExtents.getX());
break;
}
case 1:
{
shape = createCylinderShapeY(halfExtents.getX(),halfExtents.getY());
break;
}
case 2:
{
shape = createCylinderShapeZ(halfExtents.getX(),halfExtents.getZ());
break;
}
default:
{
printf("unknown Cylinder up axis\n");
}
};
break;
}
case MULTI_SPHERE_SHAPE_PROXYTYPE:
{
b3MultiSphereShapeData* mss = (b3MultiSphereShapeData*)bsd;
int numSpheres = mss->m_localPositionArraySize;
int i;
for ( i=0;i<numSpheres;i++)
{
tmpPos[i].deSerializeFloat(mss->m_localPositionArrayPtr[i].m_pos);
radii[i] = mss->m_localPositionArrayPtr[i].m_radius;
}
shape = new b3MultiSphereShape(&tmpPos[0],&radii[0],numSpheres);
break;
}
#endif
default:
{
printf("error: cannot create shape type (%d)\n",shapeData->m_shapeType);
}
}
break;
}
case TRIANGLE_MESH_SHAPE_PROXYTYPE:
{
Bullet3SerializeBullet2::b3TriangleMeshShapeData* trimesh = (Bullet3SerializeBullet2::b3TriangleMeshShapeData*)shapeData;
printf("numparts = %d\n",trimesh->m_meshInterface.m_numMeshParts);
if (trimesh->m_meshInterface.m_numMeshParts)
{
for (int i=0;i<trimesh->m_meshInterface.m_numMeshParts;i++)
{
Bullet3SerializeBullet2::b3MeshPartData& dat = trimesh->m_meshInterface.m_meshPartsPtr[i];
printf("numtris = %d, numverts = %d\n", dat.m_numTriangles,dat.m_numVertices);//,dat.m_vertices3f,dat.m_3indices16
printf("scaling = %f,%f,%f\n", trimesh->m_meshInterface.m_scaling.m_floats[0],trimesh->m_meshInterface.m_scaling.m_floats[1],trimesh->m_meshInterface.m_scaling.m_floats[2]);
// dat.
//dat.
}
///trimesh->m_meshInterface.m_meshPartsPtr
//trimesh->m_meshInterface.m_scaling
}
//trimesh->m_meshInterface
//b3TriangleIndexVertexArray* meshInterface = createMeshInterface(trimesh->m_meshInterface);
//scaling
//b3Vector3 scaling; scaling.deSerializeFloat(trimesh->m_meshInterface.m_scaling);
//meshInterface->setScaling(scaling);
//printf("trimesh->m_collisionMargin=%f\n",trimesh->m_collisionMargin);
break;
}
#if 0
case COMPOUND_SHAPE_PROXYTYPE:
{
b3CompoundShapeData* compoundData = (b3CompoundShapeData*)shapeData;
b3CompoundShape* compoundShape = createCompoundShape();
b3AlignedObjectArray<b3CollisionShape*> childShapes;
for (int i=0;i<compoundData->m_numChildShapes;i++)
{
b3CollisionShape* childShape = convertCollisionShape(compoundData->m_childShapePtr[i].m_childShape);
if (childShape)
{
b3Transform localTransform;
localTransform.deSerializeFloat(compoundData->m_childShapePtr[i].m_transform);
compoundShape->addChildShape(localTransform,childShape);
} else
{
printf("error: couldn't create childShape for compoundShape\n");
}
}
shape = compoundShape;
break;
}
case GIMPACT_SHAPE_PROXYTYPE:
{
b3GImpactMeshShapeData* gimpactData = (b3GImpactMeshShapeData*) shapeData;
if (gimpactData->m_gimpactSubType == CONST_GIMPACT_TRIMESH_SHAPE)
{
b3TriangleIndexVertexArray* meshInterface = createMeshInterface(gimpactData->m_meshInterface);
b3GImpactMeshShape* gimpactShape = createGimpactShape(meshInterface);
b3Vector3 localScaling;
localScaling.deSerializeFloat(gimpactData->m_localScaling);
gimpactShape->setLocalScaling(localScaling);
gimpactShape->setMargin(b3Scalar(gimpactData->m_collisionMargin));
gimpactShape->updateBound();
shape = gimpactShape;
} else
{
printf("unsupported gimpact sub type\n");
}
break;
}
case SOFTBODY_SHAPE_PROXYTYPE:
{
return 0;
}
#endif
default:
{
printf("unsupported shape type (%d)\n",shapeData->m_shapeType);
}
}
return shapeIndex;
}
int b3BulletDataExtractor::createBoxShape( const Bullet3SerializeBullet2::b3Vector3FloatData& halfDimensions, const Bullet3SerializeBullet2::b3Vector3FloatData& localScaling, float collisionMargin)
{
float cubeScaling[4] = {
halfDimensions.m_floats[0]*localScaling.m_floats[0]+collisionMargin,
halfDimensions.m_floats[1]*localScaling.m_floats[1]+collisionMargin,
halfDimensions.m_floats[2]*localScaling.m_floats[2]+collisionMargin,
1};
int strideInBytes = sizeof(float)*9;
int noHeightField = 1;
int cubeCollisionShapeIndex = m_np.registerConvexHullShape(&cube_vertices[0],strideInBytes, sizeof(cube_vertices)/strideInBytes,&cubeScaling[0]);
{
int numVertices = sizeof(cube_vertices)/strideInBytes;
int numIndices = sizeof(cube_indices)/sizeof(int);
GraphicsShape* gfxShape = new GraphicsShape;
gfxShape->m_vertices = cube_vertices;
gfxShape->m_numvertices = numVertices;
gfxShape->m_indices = cube_indices;
gfxShape->m_numIndices = numIndices;
for (int i=0;i<4;i++)
gfxShape->m_scaling[i] = cubeScaling[i];
m_graphicsShapes.push_back(gfxShape);
}
printf("createBoxShape with half extents %f,%f,%f\n",cubeScaling[0], cubeScaling[1],cubeScaling[2]);
//halfDimensions * localScaling
return cubeCollisionShapeIndex;
}
int b3BulletDataExtractor::createSphereShape( float radius, const Bullet3SerializeBullet2::b3Vector3FloatData& localScaling, float collisionMargin)
{
printf("createSphereShape with radius %f\n",radius);
return -1;
}
int b3BulletDataExtractor::createPlaneShape( const Bullet3SerializeBullet2::b3Vector3FloatData& planeNormal, float planeConstant, const Bullet3SerializeBullet2::b3Vector3FloatData& localScaling)
{
printf("createPlaneShape with normal %f,%f,%f and planeConstant\n",planeNormal.m_floats[0], planeNormal.m_floats[1],planeNormal.m_floats[2],planeConstant);
return -1;
}
GraphicsShape* b3BulletDataExtractor::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] = 0.5;
vtx0.uv[1] = 0.5;
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] = 0.5;
vtx1.uv[1] = 0.5;
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] = 0.5;
vtx2.uv[1] = 0.5;
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;
}
}
GraphicsShape* b3BulletDataExtractor::createGraphicsShapeFromConvexHull(const b3Vector3* tmpPoints, int numPoints)
{
b3ConvexUtility* utilPtr = new b3ConvexUtility();
bool merge = true;
utilPtr->initializePolyhedralFeatures(tmpPoints,numPoints,merge);
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 b3MyFace& 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;
}
}

View File

@@ -0,0 +1,53 @@
#ifndef BULLET_DATA_EXTRACTOR_H
#define BULLET_DATA_EXTRACTOR_H
#include "Bullet3Serialize/Bullet2FileLoader/autogenerated/bullet2.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "Bullet3Common/b3Vector3.h"
class GLInstancingRenderer;
class b3GpuRigidBodyPipeline;
class b3GpuNarrowPhase;
void createScene(GLInstancingRenderer& renderer,b3GpuNarrowPhase& np, b3GpuRigidBodyPipeline& rbWorld, const char* fileName);
namespace bParse
{
class b3BulletFile;
};
class b3BulletDataExtractor
{
GLInstancingRenderer& m_renderer;
b3GpuNarrowPhase& m_np;
b3GpuRigidBodyPipeline& m_rbPipeline;
public:
b3AlignedObjectArray<struct InstanceGroup*> m_instanceGroups;
b3AlignedObjectArray<struct GraphicsShape*> m_graphicsShapes;
b3BulletDataExtractor(GLInstancingRenderer& renderer, b3GpuNarrowPhase& np, b3GpuRigidBodyPipeline& rbPipeline);
virtual ~b3BulletDataExtractor();
virtual void convertAllObjects(bParse::b3BulletFile* bulletFile);
//return -1 for invalid
virtual int convertCollisionShape( Bullet3SerializeBullet2::b3CollisionShapeData* shapeData );
virtual int createPlaneShape( const Bullet3SerializeBullet2::b3Vector3FloatData& planeNormal, float planeConstant, const Bullet3SerializeBullet2::b3Vector3FloatData& localScaling);
virtual int createBoxShape( const Bullet3SerializeBullet2::b3Vector3FloatData& halfDimensions, const Bullet3SerializeBullet2::b3Vector3FloatData& localScaling, float collisionMargin);
virtual int createSphereShape( float radius, const Bullet3SerializeBullet2::b3Vector3FloatData& localScaling, float collisionMargin);
static GraphicsShape* createGraphicsShapeFromConvexHull(const b3Vector3* tmpPoints, int numPoints);
static GraphicsShape* createGraphicsShapeFromWavefrontObj(class objLoader* obj);
};
#endif //BULLET_DATA_EXTRACTOR_H

View File

@@ -0,0 +1,757 @@
#include "ConcaveScene.h"
#include "GpuRigidBodyDemo.h"
#include "Bullet3Common/b3Quickprof.h"
#include "OpenGLWindow/ShapeData.h"
#include "OpenGLWindow/GLInstancingRenderer.h"
#include "Bullet3Common/b3Quaternion.h"
#include "OpenGLWindow/b3gWindowInterface.h"
#include "Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.h"
#include "../GpuDemoInternalData.h"
#include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
#include "OpenGLWindow/OpenGLInclude.h"
#include "OpenGLWindow/GLInstanceRendererInternalData.h"
#include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h"
#include "Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipeline.h"
#include "Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.h"
#include "Bullet3OpenCL/RigidBody/b3Config.h"
#include "GpuRigidBodyDemoInternalData.h"
#include"../../Wavefront/objLoader.h"
#include "Bullet3Common/b3Transform.h"
#include "OpenGLWindow/GLInstanceGraphicsShape.h"
#define CONCAVE_GAPX 16
#define CONCAVE_GAPY 8
#define CONCAVE_GAPZ 16
GLInstanceGraphicsShape* createGraphicsShapeFromWavefrontObj(objLoader* obj)
{
b3AlignedObjectArray<GLInstanceVertex>* vertices = new b3AlignedObjectArray<GLInstanceVertex>;
{
// 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);
GLInstanceVertex 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.xyzw[3] = 0.f;//obj->vertexList[face->vertex_index[0]]->e[2];
vtx0.uv[0] = 0.5f;//obj->textureList[face->vertex_index[0]]->e[0];
vtx0.uv[1] = 0.5f;//obj->textureList[face->vertex_index[0]]->e[1];
GLInstanceVertex 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.xyzw[3]= 0.f;
vtx1.uv[0] = 0.5f;//obj->textureList[face->vertex_index[1]]->e[0];
vtx1.uv[1] = 0.5f;//obj->textureList[face->vertex_index[1]]->e[1];
GLInstanceVertex 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.xyzw[3] = 0.f;
vtx2.uv[0] = 0.5f;obj->textureList[face->vertex_index[2]]->e[0];
vtx2.uv[1] = 0.5f;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);
//
GLInstanceVertex 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);
}
}
}
GLInstanceGraphicsShape* gfxShape = new GLInstanceGraphicsShape;
gfxShape->m_vertices = vertices;
gfxShape->m_numvertices = vertices->size();
gfxShape->m_indices = indicesPtr;
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;
}
}
void ConcaveScene::createConcaveMesh(const ConstructionInfo& ci, const char* fileName, const b3Vector3& shift, const b3Vector3& scaling)
{
objLoader* objData = new objLoader();
FILE* f = 0;
char relativeFileName[1024];
{
const char* prefix[]={"./","../","../../","../../../","../../../../"};
int numPrefixes = sizeof(prefix)/sizeof(char*);
for (int i=0;i<numPrefixes;i++)
{
sprintf(relativeFileName,"%s%s",prefix[i],fileName);
f = fopen(relativeFileName,"r");
if (f)
{
fclose(f);
break;
}
}
}
if (f)
fclose(f);
else
return;
objData->load(relativeFileName);
int index=10;
{
GLInstanceGraphicsShape* shape = createGraphicsShapeFromWavefrontObj(objData);
b3AlignedObjectArray<b3Vector3> verts;
for (int i=0;i<shape->m_numvertices;i++)
{
for (int j=0;j<3;j++)
shape->m_vertices->at(i).xyzw[j] += shift[j];
b3Vector3 vtx(shape->m_vertices->at(i).xyzw[0],
shape->m_vertices->at(i).xyzw[1],
shape->m_vertices->at(i).xyzw[2]);
verts.push_back(vtx*scaling);
}
int colIndex = m_data->m_np->registerConcaveMesh(&verts,shape->m_indices,b3Vector3(1,1,1));
{
int strideInBytes = 9*sizeof(float);
int numVertices = sizeof(cube_vertices)/strideInBytes;
int numIndices = sizeof(cube_indices)/sizeof(int);
//int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
//int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int shapeId = ci.m_instancingRenderer->registerShape(&shape->m_vertices->at(0).xyzw[0], shape->m_numvertices, &shape->m_indices->at(0), shape->m_numIndices);
b3Quaternion orn(0,0,0,1);
b3Vector4 color(0.3,0.3,1,1.f);//0.5);//1.f
{
float mass = 0.f;
b3Vector3 position(0,0,0);
int id = ci.m_instancingRenderer->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(mass,position,orn,colIndex,index,false);
index++;
}
}
}
delete objData;
}
void ConcaveScene::setupScene(const ConstructionInfo& ci)
{
if (1)
{
//char* fileName = "data/slopedPlane100.obj";
//char* fileName = "data/plane100.obj";
char* fileName = "data/plane100.obj";
//char* fileName = "data/teddy.obj";//"plane.obj";
// char* fileName = "data/sponza_closed.obj";//"plane.obj";
//char* fileName = "data/leoTest1.obj";
// char* fileName = "data/samurai_monastry.obj";
// char* fileName = "data/teddy2_VHACD_CHs.obj";
b3Vector3 shift1(0,-50,0);//0,230,80);//150,-100,-120);
b3Vector4 scaling(4,4,4,1);
// createConcaveMesh(ci,"data/plane100.obj",shift1,scaling);
//createConcaveMesh(ci,"data/plane100.obj",shift,scaling);
b3Vector3 shift2(0,0,0);//0,230,80);//150,-100,-120);
createConcaveMesh(ci,"data/teddy.obj",shift2,scaling);
b3Vector3 shift3(130,-150,-75);//0,230,80);//150,-100,-120);
createConcaveMesh(ci,"data/leoTest1.obj",shift3,scaling);
} else
{
int strideInBytes = 9*sizeof(float);
int numVertices = sizeof(cube_vertices)/strideInBytes;
int numIndices = sizeof(cube_indices)/sizeof(int);
int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int group=1;
int mask=1;
int index=0;
{
b3Vector4 scaling(400,0.001,400,1);
int colIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
b3Vector3 position(0,-2,0);
b3Quaternion orn(0,0,0,1);
b3Vector4 color(0,0,1,1);
int id = ci.m_instancingRenderer->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(0.f,position,orn,colIndex,index,false);
}
}
createDynamicObjects(ci);
m_data->m_rigidBodyPipeline->writeAllInstancesToGpu();
float camPos[4]={0,0,0,0};//65.5,4.5,65.5,0};
//float camPos[4]={1,12.5,1.5,0};
m_instancingRenderer->setCameraPitch(45);
m_instancingRenderer->setCameraTargetPosition(camPos);
m_instancingRenderer->setCameraDistance(25);
}
void ConcaveScene::createDynamicObjects(const ConstructionInfo& ci)
{
int strideInBytes = 9*sizeof(float);
int numVertices = sizeof(cube_vertices)/strideInBytes;
int numIndices = sizeof(cube_indices)/sizeof(int);
//int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int group=1;
int mask=1;
int index=0;
if (1)
{
int curColor = 0;
b3Vector4 colors[4] =
{
b3Vector4(1,1,1,1),
b3Vector4(1,1,0.3,1),
b3Vector4(0.3,1,1,1),
b3Vector4(0.3,0.3,1,1),
};
b3Vector4 scaling(1,1,1,1);
int colIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
for (int i=0;i<ci.arraySizeX;i++)
{
for (int j=0;j<ci.arraySizeY;j++)
{
for (int k=0;k<ci.arraySizeZ;k++)
{
float mass = 1;
//b3Vector3 position(-2*ci.gapX+i*ci.gapX,25+j*ci.gapY,-2*ci.gapZ+k*ci.gapZ);
b3Vector3 position(-(ci.arraySizeX/2)*CONCAVE_GAPX+i*CONCAVE_GAPX,150+j*CONCAVE_GAPY,-(ci.arraySizeZ/2)*CONCAVE_GAPZ+k*CONCAVE_GAPZ);
b3Quaternion orn(0,0,0,1);
b3Vector4 color = colors[curColor];
curColor++;
curColor&=3;
int id = ci.m_instancingRenderer->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(mass,position,orn,colIndex,index,false);
index++;
}
}
}
}
}
void ConcaveCompoundScene::setupScene(const ConstructionInfo& ci)
{
ConcaveScene::setupScene(ci);
float camPos[4]={0,50,0,0};//65.5,4.5,65.5,0};
//float camPos[4]={1,12.5,1.5,0};
m_instancingRenderer->setCameraPitch(45);
m_instancingRenderer->setCameraTargetPosition(camPos);
m_instancingRenderer->setCameraDistance(40);
}
void ConcaveCompound2Scene::createDynamicObjects(const ConstructionInfo& ci)
{
objLoader* objData = new objLoader();
char* fileName = "data/teddy2_VHACD_CHs.obj";
//char* fileName = "data/cube_offset.obj";
b3Vector3 shift(0,0,0);//0,230,80);//150,-100,-120);
b3Vector4 scaling(1,1,1,1);
FILE* f = 0;
char relativeFileName[1024];
{
const char* prefix[]={"./","../","../../","../../../","../../../../"};
int numPrefixes = sizeof(prefix)/sizeof(char*);
for (int i=0;i<numPrefixes;i++)
{
sprintf(relativeFileName,"%s%s",prefix[i],fileName);
f = fopen(relativeFileName,"r");
if (f)
{
fclose(f);
break;
}
}
}
if (f)
fclose(f);
else
return;
objData->load(relativeFileName);
if (objData->objectCount>0)
{
int strideInBytes = 9*sizeof(float);
b3AlignedObjectArray<GLInstanceVertex> vertexArray;
b3AlignedObjectArray<int> indexArray;
//int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int group=1;
int mask=1;
int index=0;
int colIndex = 0;
b3AlignedObjectArray<GLInstanceVertex> vertices;
int stride2 = sizeof(GLInstanceVertex);
b3Assert(stride2 == strideInBytes);
{
b3AlignedObjectArray<b3GpuChildShape> childShapes;
int numChildShapes = objData->objectCount;
for (int i=0;i<numChildShapes;i++)
// int i=4;
{
obj_object* object = objData->objectList[i];
int numVertices = i==numChildShapes-1? objData->vertexCount-object->vertex_offset : objData->objectList[i+1]->vertex_offset - object->vertex_offset;
int numFaces = i==numChildShapes-1? objData->faceCount - object->face_offset : objData->objectList[i+1]->face_offset-object->face_offset;
//for now, only support polyhedral child shapes
b3GpuChildShape child;
b3Vector3 pos(0,0,0);
b3Quaternion orn(0,0,0,1);
for (int v=0;v<4;v++)
{
child.m_childPosition[v] = pos[v];
child.m_childOrientation[v] = orn[v];
}
b3Transform tr;
tr.setIdentity();
tr.setOrigin(pos);
tr.setRotation(orn);
int baseIndex = vertexArray.size();
for (int f=0;f<numFaces;f++)
{
obj_face* face = objData->faceList[object->face_offset+f];
if (face->vertex_count==3)
{
for (int i=0;i<3;i++)
{
indexArray.push_back(face->vertex_index[i]);//-object->vertex_offset);
}
} else
{
b3Assert(0);
}
}
b3Vector3 center(0,0,0);
b3AlignedObjectArray<GLInstanceVertex> tmpVertices;
//add transformed graphics vertices and indices
b3Vector3 myScaling(1,1,1);//50,50,50);//300,300,300);
for (int v=0;v<numVertices;v++)
{
GLInstanceVertex vert;
obj_vector* orgVert = objData->vertexList[object->vertex_offset+v];
vert.uv[0] = 0.5f;
vert.uv[1] = 0.5f;
vert.normal[0]=0.f;
vert.normal[1]=1.f;
vert.normal[2]=0.f;
b3Vector3 vertPos;
vertPos[0] = orgVert->e[0]*myScaling[0];
vertPos[1] = orgVert->e[1]*myScaling[1];
vertPos[2] = orgVert->e[2]*myScaling[2];
vertPos[3] =0.f;
center+=vertPos;
}
center/=numVertices;
for (int v=0;v<numVertices;v++)
{
GLInstanceVertex vert;
obj_vector* orgVert = objData->vertexList[object->vertex_offset+v];
vert.uv[0] = 0.5f;
vert.uv[1] = 0.5f;
vert.normal[0]=0.f;
vert.normal[1]=1.f;
vert.normal[2]=0.f;
b3Vector3 vertPos;
vertPos[0] = orgVert->e[0]*myScaling[0];
vertPos[1] = orgVert->e[1]*myScaling[1];
vertPos[2] = orgVert->e[2]*myScaling[2];
vertPos[3] =0.f;
// vertPos-=center;
vert.xyzw[0] = vertPos[0];
vert.xyzw[1] = vertPos[1];
vert.xyzw[2] = vertPos[2];
tmpVertices.push_back(vert);
b3Vector3 newPos = tr*vertPos;
vert.xyzw[0] = newPos[0];
vert.xyzw[1] = newPos[1];
vert.xyzw[2] = newPos[2];
vert.xyzw[3] = 0.f;
vertexArray.push_back(vert);
}
int childColIndex = m_data->m_np->registerConvexHullShape(&tmpVertices[0].xyzw[0],strideInBytes,numVertices, scaling);
child.m_shapeIndex = childColIndex;
childShapes.push_back(child);
colIndex = childColIndex;
}
colIndex= m_data->m_np->registerCompoundShape(&childShapes);
}
//int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int shapeId = ci.m_instancingRenderer->registerShape(&vertexArray[0].xyzw[0],vertexArray.size(),&indexArray[0],indexArray.size());
b3Vector4 colors[4] =
{
b3Vector4(1,0,0,1),
b3Vector4(0,1,0,1),
b3Vector4(0,0,1,1),
b3Vector4(0,1,1,1),
};
int curColor = 0;
for (int i=0;i<ci.arraySizeX;i++)
{
for (int j=0;j<ci.arraySizeY;j++)
{
for (int k=0;k<ci.arraySizeZ;k++)
{
float mass = 1;//j==0? 0.f : 1.f;
//b3Vector3 position(i*10*ci.gapX,j*ci.gapY,k*10*ci.gapZ);
b3Vector3 position(i*10*ci.gapX,10+j*ci.gapY,k*10*ci.gapZ);
// b3Quaternion orn(0,0,0,1);
b3Quaternion orn(b3Vector3(0,0,1),1.8);
b3Vector4 color = colors[curColor];
curColor++;
curColor&=3;
b3Vector4 scaling(1,1,1,1);
int id = ci.m_instancingRenderer->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(mass,position,orn,colIndex,index,false);
index++;
}
}
}
}
delete objData;
}
void ConcaveCompoundScene::createDynamicObjects(const ConstructionInfo& ci)
{
int strideInBytes = 9*sizeof(float);
int numVertices = sizeof(cube_vertices)/strideInBytes;
int numIndices = sizeof(cube_indices)/sizeof(int);
b3AlignedObjectArray<GLInstanceVertex> vertexArray;
b3AlignedObjectArray<int> indexArray;
//int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int group=1;
int mask=1;
int index=0;
float scaling[4] = {1,1,1,1};
int colIndex = 0;
GLInstanceVertex* cubeVerts = (GLInstanceVertex*)&cube_vertices[0];
int stride2 = sizeof(GLInstanceVertex);
b3Assert(stride2 == strideInBytes);
{
int childColIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
b3Vector3 childPositions[3] = {
b3Vector3(0,-2,0),
b3Vector3(0,0,0),
b3Vector3(0,0,2)
};
b3AlignedObjectArray<b3GpuChildShape> childShapes;
int numChildShapes = 3;
for (int i=0;i<numChildShapes;i++)
{
//for now, only support polyhedral child shapes
b3GpuChildShape child;
child.m_shapeIndex = childColIndex;
b3Vector3 pos = childPositions[i];
b3Quaternion orn(0,0,0,1);
for (int v=0;v<4;v++)
{
child.m_childPosition[v] = pos[v];
child.m_childOrientation[v] = orn[v];
}
childShapes.push_back(child);
b3Transform tr;
tr.setIdentity();
tr.setOrigin(pos);
tr.setRotation(orn);
int baseIndex = vertexArray.size();
for (int j=0;j<numIndices;j++)
indexArray.push_back(cube_indices[j]+baseIndex);
//add transformed graphics vertices and indices
for (int v=0;v<numVertices;v++)
{
GLInstanceVertex vert = cubeVerts[v];
b3Vector3 vertPos(vert.xyzw[0],vert.xyzw[1],vert.xyzw[2]);
b3Vector3 newPos = tr*vertPos;
vert.xyzw[0] = newPos[0];
vert.xyzw[1] = newPos[1];
vert.xyzw[2] = newPos[2];
vert.xyzw[3] = 0.f;
vertexArray.push_back(vert);
}
}
colIndex= m_data->m_np->registerCompoundShape(&childShapes);
}
//int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int shapeId = ci.m_instancingRenderer->registerShape(&vertexArray[0].xyzw[0],vertexArray.size(),&indexArray[0],indexArray.size());
b3Vector4 colors[4] =
{
b3Vector4(1,0,0,1),
b3Vector4(0,1,0,1),
b3Vector4(0,0,1,1),
b3Vector4(0,1,1,1),
};
int curColor = 0;
for (int i=0;i<ci.arraySizeX;i++)
{
for (int j=0;j<ci.arraySizeY;j++)
{
for (int k=0;k<ci.arraySizeZ;k++)
{
float mass = 1;//j==0? 0.f : 1.f;
b3Vector3 position(i*ci.gapX,50+j*ci.gapY,k*ci.gapZ);
//b3Quaternion orn(0,0,0,1);
b3Quaternion orn(b3Vector3(1,0,0),0.7);
b3Vector4 color = colors[curColor];
curColor++;
curColor&=3;
b3Vector4 scaling(1,1,1,1);
int id = ci.m_instancingRenderer->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(mass,position,orn,colIndex,index,false);
index++;
}
}
}
}
void ConcaveSphereScene::setupScene(const ConstructionInfo& ci)
{
ConcaveScene::setupScene(ci);
float camPos[4]={0,50,0,0};//65.5,4.5,65.5,0};
//float camPos[4]={1,12.5,1.5,0};
m_instancingRenderer->setCameraPitch(45);
m_instancingRenderer->setCameraTargetPosition(camPos);
m_instancingRenderer->setCameraDistance(40);
}
void ConcaveSphereScene::createDynamicObjects(const ConstructionInfo& ci)
{
b3Vector4 colors[4] =
{
b3Vector4(1,0,0,1),
b3Vector4(0,1,0,1),
b3Vector4(0,1,1,1),
b3Vector4(1,1,0,1),
};
int index=0;
int curColor = 0;
float radius = 1;
//int colIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
int colIndex = m_data->m_np->registerSphereShape(radius);//>registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
int prevGraphicsShapeIndex = registerGraphicsSphereShape(ci,radius,false);
for (int i=0;i<ci.arraySizeX;i++)
{
for (int j=0;j<ci.arraySizeY;j++)
{
for (int k=0;k<ci.arraySizeZ;k++)
{
float mass = 1.f;
b3Vector3 position(-(ci.arraySizeX/2)*8+i*8,50+j*8,-(ci.arraySizeZ/2)*8+k*8);
//b3Vector3 position(0,-41,0);//0,0,0);//i*radius*3,-41+j*radius*3,k*radius*3);
b3Quaternion orn(0,0,0,1);
b3Vector4 color = colors[curColor];
curColor++;
curColor&=3;
b3Vector4 scaling(radius,radius,radius,1);
int id = ci.m_instancingRenderer->registerGraphicsInstance(prevGraphicsShapeIndex,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(mass,position,orn,colIndex,index,false);
index++;
}
}
}
}

View File

@@ -0,0 +1,101 @@
#ifndef CONCAVE_SCENE_H
#define CONCAVE_SCENE_H
#include "GpuRigidBodyDemo.h"
#include "Bullet3Common/b3Vector3.h"
class ConcaveScene : public GpuRigidBodyDemo
{
public:
ConcaveScene(){}
virtual ~ConcaveScene(){}
virtual const char* getName()
{
return "GRBConcave";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new ConcaveScene;
return demo;
}
virtual void setupScene(const ConstructionInfo& ci);
virtual void createDynamicObjects(const ConstructionInfo& ci);
virtual void createConcaveMesh(const ConstructionInfo& ci, const char* fileName, const b3Vector3& shift, const b3Vector3& scaling);
};
class ConcaveSphereScene : public ConcaveScene
{
public:
ConcaveSphereScene(){}
virtual ~ConcaveSphereScene(){}
virtual const char* getName()
{
return "ConcaveSphere";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new ConcaveSphereScene;
return demo;
}
virtual void setupScene(const ConstructionInfo& ci);
virtual void createDynamicObjects(const ConstructionInfo& ci);
};
class ConcaveCompoundScene : public ConcaveScene
{
public:
ConcaveCompoundScene(){}
virtual ~ConcaveCompoundScene(){}
virtual const char* getName()
{
return "GRBConcaveCompound";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new ConcaveCompoundScene;
return demo;
}
virtual void setupScene(const ConstructionInfo& ci);
virtual void createDynamicObjects(const ConstructionInfo& ci);
};
class ConcaveCompound2Scene : public ConcaveCompoundScene
{
public:
ConcaveCompound2Scene(){}
virtual ~ConcaveCompound2Scene(){}
virtual const char* getName()
{
return "GRBConcave2Compound";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new ConcaveCompound2Scene;
return demo;
}
virtual void createDynamicObjects(const ConstructionInfo& ci);
};
#endif //CONCAVE_SCENE_H

View File

@@ -0,0 +1,254 @@
#include "GpuCompoundScene.h"
#include "GpuRigidBodyDemo.h"
#include "Bullet3Common/b3Quickprof.h"
#include "OpenGLWindow/ShapeData.h"
#include "OpenGLWindow/GLInstancingRenderer.h"
#include "Bullet3Common/b3Quaternion.h"
#include "OpenGLWindow/b3gWindowInterface.h"
#include "Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.h"
#include "../GpuDemoInternalData.h"
#include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
#include "OpenGLWindow/OpenGLInclude.h"
#include "OpenGLWindow/GLInstanceRendererInternalData.h"
#include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h"
#include "Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipeline.h"
#include "Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.h"
#include "Bullet3OpenCL/RigidBody/b3Config.h"
#include "GpuRigidBodyDemoInternalData.h"
#include "Bullet3Common/b3Transform.h"
#include "OpenGLWindow/GLInstanceGraphicsShape.h"
void GpuCompoundScene::setupScene(const ConstructionInfo& ci)
{
createStaticEnvironment(ci);
int strideInBytes = 9*sizeof(float);
int numVertices = sizeof(cube_vertices)/strideInBytes;
int numIndices = sizeof(cube_indices)/sizeof(int);
float scaling[4] = {1,1,1,1};
GLInstanceVertex* cubeVerts = (GLInstanceVertex*)&cube_vertices[0];
int stride2 = sizeof(GLInstanceVertex);
b3Assert(stride2 == strideInBytes);
int index=0;
int colIndex = -1;
b3AlignedObjectArray<GLInstanceVertex> vertexArray;
b3AlignedObjectArray<int> indexArray;
{
int childColIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
b3Vector3 childPositions[3] = {
b3Vector3(0,-2,0),
b3Vector3(0,0,0),
b3Vector3(0,0,2)
};
b3AlignedObjectArray<b3GpuChildShape> childShapes;
int numChildShapes = 3;
for (int i=0;i<numChildShapes;i++)
{
//for now, only support polyhedral child shapes
b3GpuChildShape child;
child.m_shapeIndex = childColIndex;
b3Vector3 pos = childPositions[i];
b3Quaternion orn(0,0,0,1);
for (int v=0;v<4;v++)
{
child.m_childPosition[v] = pos[v];
child.m_childOrientation[v] = orn[v];
}
childShapes.push_back(child);
b3Transform tr;
tr.setIdentity();
tr.setOrigin(pos);
tr.setRotation(orn);
int baseIndex = vertexArray.size();
for (int j=0;j<numIndices;j++)
indexArray.push_back(cube_indices[j]+baseIndex);
//add transformed graphics vertices and indices
for (int v=0;v<numVertices;v++)
{
GLInstanceVertex vert = cubeVerts[v];
b3Vector3 vertPos(vert.xyzw[0],vert.xyzw[1],vert.xyzw[2]);
b3Vector3 newPos = tr*vertPos;
vert.xyzw[0] = newPos[0];
vert.xyzw[1] = newPos[1];
vert.xyzw[2] = newPos[2];
vert.xyzw[3] = 0.f;
vertexArray.push_back(vert);
}
}
colIndex= m_data->m_np->registerCompoundShape(&childShapes);
}
//int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int shapeId = ci.m_instancingRenderer->registerShape(&vertexArray[0].xyzw[0],vertexArray.size(),&indexArray[0],indexArray.size());
b3Vector4 colors[4] =
{
b3Vector4(1,0,0,1),
b3Vector4(0,1,0,1),
b3Vector4(0,0,1,1),
b3Vector4(0,1,1,1),
};
int curColor = 0;
for (int i=0;i<ci.arraySizeX;i++)
{
for (int j=0;j<ci.arraySizeY;j++)
{
for (int k=0;k<ci.arraySizeZ;k++)
{
float mass = 1;//j==0? 0.f : 1.f;
b3Vector3 position(i*ci.gapX,10+j*ci.gapY,k*ci.gapZ);
//b3Quaternion orn(0,0,0,1);
b3Quaternion orn(b3Vector3(1,0,0),0.7);
b3Vector4 color = colors[curColor];
curColor++;
curColor&=3;
b3Vector4 scaling(1,1,1,1);
int id = ci.m_instancingRenderer->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(mass,position,orn,colIndex,index,false);
index++;
}
}
}
m_data->m_rigidBodyPipeline->writeAllInstancesToGpu();
float camPos[4]={0,0,0};//65.5,4.5,65.5,0};
//float camPos[4]={1,12.5,1.5,0};
m_instancingRenderer->setCameraTargetPosition(camPos);
m_instancingRenderer->setCameraDistance(20);
}
void GpuCompoundScene::createStaticEnvironment(const ConstructionInfo& ci)
{
int strideInBytes = 9*sizeof(float);
//int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int group=1;
int mask=1;
int index=0;
int colIndex = 0;
{
if (1)
{
float radius = 41;
int prevGraphicsShapeIndex = -1;
{
if (radius>=100)
{
int numVertices = sizeof(detailed_sphere_vertices)/strideInBytes;
int numIndices = sizeof(detailed_sphere_indices)/sizeof(int);
prevGraphicsShapeIndex = ci.m_instancingRenderer->registerShape(&detailed_sphere_vertices[0],numVertices,detailed_sphere_indices,numIndices);
} else
{
bool usePointSprites = false;
if (usePointSprites)
{
int numVertices = sizeof(point_sphere_vertices)/strideInBytes;
int numIndices = sizeof(point_sphere_indices)/sizeof(int);
prevGraphicsShapeIndex = ci.m_instancingRenderer->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 = ci.m_instancingRenderer->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 = ci.m_instancingRenderer->registerShape(&low_sphere_vertices[0],numVertices,low_sphere_indices,numIndices);
}
}
}
}
b3Vector4 colors[4] =
{
b3Vector4(1,0,0,1),
b3Vector4(0,1,0,1),
b3Vector4(0,1,1,1),
b3Vector4(1,1,0,1),
};
int curColor = 1;
//int colIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
int colIndex = m_data->m_np->registerSphereShape(radius);//>registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
float mass = 0.f;
//b3Vector3 position((j&1)+i*2.2,1+j*2.,(j&1)+k*2.2);
b3Vector3 position(0,-41,0);
b3Quaternion orn(0,0,0,1);
b3Vector4 color = colors[curColor];
curColor++;
curColor&=3;
b3Vector4 scaling(radius,radius,radius,1);
int id = ci.m_instancingRenderer->registerGraphicsInstance(prevGraphicsShapeIndex,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(mass,position,orn,colIndex,index,false);
index++;
}
}
}
void GpuCompoundPlaneScene::createStaticEnvironment(const ConstructionInfo& ci)
{
int index=0;
b3Vector3 normal(0,1,0);
float constant=0.f;
int colIndex = m_data->m_np->registerPlaneShape(normal,constant);//>registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
b3Vector3 position(0,0,0);
b3Quaternion orn(0,0,0,1);
// b3Quaternion orn(b3Vector3(1,0,0),0.3);
b3Vector4 color(0,0,1,1);
b3Vector4 scaling(100,0.01,100,1);
int strideInBytes = 9*sizeof(float);
int numVertices = sizeof(cube_vertices)/strideInBytes;
int numIndices = sizeof(cube_indices)/sizeof(int);
int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int id = ci.m_instancingRenderer->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(0.f,position,orn,colIndex,index,false);
}

View File

@@ -0,0 +1,50 @@
#ifndef GPU_COMPOUND_SCENE_H
#define GPU_COMPOUND_SCENE_H
#include "GpuRigidBodyDemo.h"
class GpuCompoundScene : public GpuRigidBodyDemo
{
public:
GpuCompoundScene(){}
virtual ~GpuCompoundScene(){}
virtual const char* getName()
{
return "GpuCompound";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new GpuCompoundScene;
return demo;
}
virtual void setupScene(const ConstructionInfo& ci);
virtual void createStaticEnvironment(const ConstructionInfo& ci);
};
class GpuCompoundPlaneScene : public GpuCompoundScene
{
public:
GpuCompoundPlaneScene(){}
virtual ~GpuCompoundPlaneScene(){}
virtual const char* getName()
{
return "GpuCompoundPlane";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new GpuCompoundPlaneScene;
return demo;
}
virtual void createStaticEnvironment(const ConstructionInfo& ci);
};
#endif //GPU_COMPOUND_SCENE_H

View File

@@ -0,0 +1,176 @@
#include "GpuConvexScene.h"
#include "GpuRigidBodyDemo.h"
#include "Bullet3Common/b3Quickprof.h"
#include "OpenGLWindow/ShapeData.h"
#include "OpenGLWindow/GLInstancingRenderer.h"
#include "Bullet3Common/b3Quaternion.h"
#include "OpenGLWindow/b3gWindowInterface.h"
#include "Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.h"
#include "../GpuDemoInternalData.h"
#include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
#include "OpenGLWindow/OpenGLInclude.h"
#include "OpenGLWindow/GLInstanceRendererInternalData.h"
#include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h"
#include "Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipeline.h"
#include "Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.h"
#include "Bullet3OpenCL/RigidBody/b3Config.h"
#include "GpuRigidBodyDemoInternalData.h"
#include "../gwenUserInterface.h"
#include "Bullet3Dynamics/ConstraintSolver/b3Point2PointConstraint.h"
void GpuConvexScene::setupScene(const ConstructionInfo& ci)
{
int index=0;
createStaticEnvironment(ci);
index+=createDynamicsObjects(ci);
m_data->m_rigidBodyPipeline->writeAllInstancesToGpu();
float camPos[4]={ci.arraySizeX,ci.arraySizeY/2,ci.arraySizeZ,0};
//float camPos[4]={1,12.5,1.5,0};
m_instancingRenderer->setCameraTargetPosition(camPos);
m_instancingRenderer->setCameraDistance(40);
char msg[1024];
int numInstances = index;
sprintf(msg,"Num objects = %d",numInstances);
ci.m_gui->setStatusBarMessage(msg,true);
}
int GpuConvexScene::createDynamicsObjects(const ConstructionInfo& ci)
{
int strideInBytes = 9*sizeof(float);
int numVertices = sizeof(barrel_vertices)/strideInBytes;
int numIndices = sizeof(barrel_indices)/sizeof(int);
return createDynamicsObjects2(ci,barrel_vertices,numVertices,barrel_indices,numIndices);
}
int GpuBoxPlaneScene::createDynamicsObjects(const ConstructionInfo& ci)
{
int strideInBytes = 9*sizeof(float);
int numVertices = sizeof(cube_vertices)/strideInBytes;
int numIndices = sizeof(cube_indices)/sizeof(int);
return createDynamicsObjects2(ci,cube_vertices,numVertices,cube_indices,numIndices);
}
int GpuConvexScene::createDynamicsObjects2(const ConstructionInfo& ci, const float* vertices, int numVertices, const int* indices, int numIndices)
{
int strideInBytes = 9*sizeof(float);
int shapeId = ci.m_instancingRenderer->registerShape(&vertices[0],numVertices,indices,numIndices);
int group=1;
int mask=1;
int index=0;
{
b3Vector4 colors[4] =
{
b3Vector4(1,0,0,1),
b3Vector4(0,1,0,1),
b3Vector4(0,1,1,1),
b3Vector4(1,1,0,1),
};
int curColor = 0;
float scaling[4] = {1,1,1,1};
int prevBody = -1;
int insta = 0;
int colIndex = m_data->m_np->registerConvexHullShape(&vertices[0],strideInBytes,numVertices, scaling);
//int colIndex = m_data->m_np->registerSphereShape(1);
for (int i=0;i<ci.arraySizeX;i++)
{
for (int j=0;j<ci.arraySizeY;j++)
{
for (int k=0;k<ci.arraySizeZ;k++)
{
float mass = 1.f;
if (j==0)//ci.arraySizeY-1)
{
//mass=0.f;
}
//b3Vector3 position((j&1)+i*2.2,1+j*2.,(j&1)+k*2.2);
b3Vector3 position(i*2.2,10+j*2.2,k*2.2);
b3Quaternion orn(0,0,0,1);
b3Vector4 color = colors[curColor];
curColor++;
curColor&=3;
b3Vector4 scaling(1,1,1,1);
int id = ci.m_instancingRenderer->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(mass,position,orn,colIndex,index,false);
if (prevBody>=0)
{
b3Point2PointConstraint* p2p = new b3Point2PointConstraint(pid,prevBody,b3Vector3(0,-1.1,0),b3Vector3(0,1.1,0));
// m_data->m_rigidBodyPipeline->addConstraint(p2p);//,false);
}
prevBody = pid;
index++;
}
}
}
}
return index;
}
void GpuConvexScene::createStaticEnvironment(const ConstructionInfo& ci)
{
int strideInBytes = 9*sizeof(float);
int numVertices = sizeof(cube_vertices)/strideInBytes;
int numIndices = sizeof(cube_indices)/sizeof(int);
int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int group=1;
int mask=1;
int index=0;
{
b3Vector4 scaling(400,1,400,1);
int colIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
b3Vector3 position(0,0,0);
b3Quaternion orn(0,0,0,1);
b3Vector4 color(0,0,1,1);
int id = ci.m_instancingRenderer->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(0.f,position,orn,colIndex,index,false);
}
}
void GpuConvexPlaneScene::createStaticEnvironment(const ConstructionInfo& ci)
{
int index=0;
b3Vector3 normal(0,1,0);
float constant=0.f;
int colIndex = m_data->m_np->registerPlaneShape(normal,constant);//>registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
b3Vector3 position(0,0,0);
b3Quaternion orn(0,0,0,1);
// b3Quaternion orn(b3Vector3(1,0,0),0.3);
b3Vector4 color(0,0,1,1);
b3Vector4 scaling(100,0.001,100,1);
int strideInBytes = 9*sizeof(float);
int numVertices = sizeof(cube_vertices)/strideInBytes;
int numIndices = sizeof(cube_indices)/sizeof(int);
int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int id = ci.m_instancingRenderer->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(0.f,position,orn,colIndex,index,false);
}

View File

@@ -0,0 +1,78 @@
#ifndef GPU_CONVEX_SCENE_H
#define GPU_CONVEX_SCENE_H
#include "GpuRigidBodyDemo.h"
class GpuConvexScene : public GpuRigidBodyDemo
{
public:
GpuConvexScene(){}
virtual ~GpuConvexScene(){}
virtual const char* getName()
{
return "GRBConvex";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new GpuConvexScene;
return demo;
}
virtual void setupScene(const ConstructionInfo& ci);
virtual int createDynamicsObjects(const ConstructionInfo& ci);
virtual int createDynamicsObjects2(const ConstructionInfo& ci,const float* vertices, int numVertices, const int* indices,int numIndices);
virtual void createStaticEnvironment(const ConstructionInfo& ci);
};
class GpuConvexPlaneScene : public GpuConvexScene
{
public:
GpuConvexPlaneScene(){}
virtual ~GpuConvexPlaneScene(){}
virtual const char* getName()
{
return "GRBConvexPlane";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new GpuConvexPlaneScene;
return demo;
}
virtual void createStaticEnvironment(const ConstructionInfo& ci);
};
class GpuBoxPlaneScene : public GpuConvexPlaneScene
{
public:
GpuBoxPlaneScene(){}
virtual ~GpuBoxPlaneScene(){}
virtual const char* getName()
{
return "GRBBoxPlane";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new GpuBoxPlaneScene;
return demo;
}
virtual int createDynamicsObjects(const ConstructionInfo& ci);
};
#endif //GPU_CONVEX_SCENE_H

View File

@@ -0,0 +1,218 @@
#include "GpuRigidBodyDemo.h"
#include "Bullet3Common/b3Quickprof.h"
#include "OpenGLWindow/ShapeData.h"
#include "OpenGLWindow/GLInstancingRenderer.h"
#include "Bullet3Common/b3Quaternion.h"
#include "OpenGLWindow/b3gWindowInterface.h"
#include "Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.h"
#include "../GpuDemoInternalData.h"
#include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
#include "OpenGLWindow/OpenGLInclude.h"
#include "OpenGLWindow/GLInstanceRendererInternalData.h"
#include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h"
#include "Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipeline.h"
#include "Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.h"
#include "Bullet3OpenCL/RigidBody/b3Config.h"
#include "GpuRigidBodyDemoInternalData.h"
#include "Bullet3Collision/BroadPhaseCollision/b3DynamicBvhBroadphase.h"
static b3KeyboardCallback oldCallback = 0;
extern bool gReset;
#define MSTRINGIFY(A) #A
static const char* s_rigidBodyKernelString = MSTRINGIFY(
typedef struct
{
float4 m_pos;
float4 m_quat;
float4 m_linVel;
float4 m_angVel;
unsigned int m_collidableIdx;
float m_invMass;
float m_restituitionCoeff;
float m_frictionCoeff;
} Body;
__kernel void
copyTransformsToVBOKernel( __global Body* gBodies, __global float4* posOrnColor, const int numNodes)
{
int nodeID = get_global_id(0);
if( nodeID < numNodes )
{
posOrnColor[nodeID] = (float4) (gBodies[nodeID].m_pos.xyz,1.0);
posOrnColor[nodeID + numNodes] = gBodies[nodeID].m_quat;
}
}
);
GpuRigidBodyDemo::GpuRigidBodyDemo()
:m_instancingRenderer(0),
m_window(0)
{
m_data = new GpuRigidBodyDemoInternalData;
}
GpuRigidBodyDemo::~GpuRigidBodyDemo()
{
delete m_data;
}
static void PairKeyboardCallback(int key, int state)
{
if (key=='R' && state)
{
gReset = true;
}
//b3DefaultKeyboardCallback(key,state);
oldCallback(key,state);
}
void GpuRigidBodyDemo::setupScene(const ConstructionInfo& ci)
{
}
void GpuRigidBodyDemo::initPhysics(const ConstructionInfo& ci)
{
if (ci.m_window)
{
m_window = ci.m_window;
oldCallback = ci.m_window->getKeyboardCallback();
ci.m_window->setKeyboardCallback(PairKeyboardCallback);
}
m_instancingRenderer = ci.m_instancingRenderer;
initCL(ci.preferredOpenCLDeviceIndex,ci.preferredOpenCLPlatformIndex);
if (m_clData->m_clContext)
{
int errNum=0;
cl_program rbProg=0;
m_data->m_copyTransformsToVBOKernel = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext,m_clData->m_clDevice,s_rigidBodyKernelString,"copyTransformsToVBOKernel",&errNum,rbProg);
b3Config config;
b3GpuNarrowPhase* np = new b3GpuNarrowPhase(m_clData->m_clContext,m_clData->m_clDevice,m_clData->m_clQueue,config);
b3GpuSapBroadphase* bp = new b3GpuSapBroadphase(m_clData->m_clContext,m_clData->m_clDevice,m_clData->m_clQueue);
m_data->m_np = np;
m_data->m_bp = bp;
b3DynamicBvhBroadphase* broadphaseDbvt = new b3DynamicBvhBroadphase(config.m_maxConvexBodies);
m_data->m_rigidBodyPipeline = new b3GpuRigidBodyPipeline(m_clData->m_clContext,m_clData->m_clDevice,m_clData->m_clQueue, np, bp,broadphaseDbvt);
setupScene(ci);
np->writeAllBodiesToGpu();
bp->writeAabbsToGpu();
}
m_instancingRenderer->writeTransforms();
}
void GpuRigidBodyDemo::exitPhysics()
{
delete m_data->m_instancePosOrnColor;
delete m_data->m_rigidBodyPipeline;
m_window->setKeyboardCallback(oldCallback);
delete m_data->m_np;
m_data->m_np = 0;
delete m_data->m_bp;
m_data->m_bp = 0;
exitCL();
}
void GpuRigidBodyDemo::renderScene()
{
m_instancingRenderer->RenderScene();
}
void GpuRigidBodyDemo::clientMoveAndDisplay()
{
bool animate=true;
int numObjects= m_data->m_rigidBodyPipeline->getNumBodies();
//m_instancingRenderer->getInternalData()->m_totalNumInstances;
b3Vector4* positions = 0;
if (animate && numObjects)
{
B3_PROFILE("gl2cl");
if (!m_data->m_instancePosOrnColor)
{
GLuint vbo = m_instancingRenderer->getInternalData()->m_vbo;
int arraySizeInBytes = numObjects * (3)*sizeof(b3Vector4);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
cl_bool blocking= CL_TRUE;
positions= (b3Vector4*)glMapBufferRange( GL_ARRAY_BUFFER,m_instancingRenderer->getMaxShapeCapacity(),arraySizeInBytes, GL_MAP_READ_BIT );//GL_READ_WRITE);//GL_WRITE_ONLY
GLint err = glGetError();
assert(err==GL_NO_ERROR);
m_data->m_instancePosOrnColor = new b3OpenCLArray<b3Vector4>(m_clData->m_clContext,m_clData->m_clQueue);
m_data->m_instancePosOrnColor->resize(3*numObjects);
m_data->m_instancePosOrnColor->copyFromHostPointer(positions,3*numObjects,0);
glUnmapBuffer( GL_ARRAY_BUFFER);
err = glGetError();
assert(err==GL_NO_ERROR);
}
}
{
B3_PROFILE("stepSimulation");
m_data->m_rigidBodyPipeline->stepSimulation(1./60.f);
}
if (numObjects)
{
B3_PROFILE("cl2gl_convert");
int ciErrNum = 0;
cl_mem bodies = m_data->m_rigidBodyPipeline->getBodyBuffer();
b3LauncherCL launch(m_clData->m_clQueue,m_data->m_copyTransformsToVBOKernel);
launch.setBuffer(bodies);
launch.setBuffer(m_data->m_instancePosOrnColor->getBufferCL());
launch.setConst(numObjects);
launch.launch1D(numObjects);
oclCHECKERROR(ciErrNum, CL_SUCCESS);
}
if (animate && numObjects)
{
B3_PROFILE("cl2gl_upload");
GLint err = glGetError();
assert(err==GL_NO_ERROR);
GLuint vbo = m_instancingRenderer->getInternalData()->m_vbo;
int arraySizeInBytes = numObjects * (3)*sizeof(b3Vector4);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
cl_bool blocking= CL_TRUE;
positions= (b3Vector4*)glMapBufferRange( GL_ARRAY_BUFFER,m_instancingRenderer->getMaxShapeCapacity(),arraySizeInBytes, GL_MAP_WRITE_BIT );//GL_READ_WRITE);//GL_WRITE_ONLY
err = glGetError();
assert(err==GL_NO_ERROR);
m_data->m_instancePosOrnColor->copyToHostPointer(positions,3*numObjects,0);
glUnmapBuffer( GL_ARRAY_BUFFER);
err = glGetError();
assert(err==GL_NO_ERROR);
}
}

View File

@@ -0,0 +1,45 @@
#ifndef GPU_RIGID_BODY_DEMO_H
#define GPU_RIGID_BODY_DEMO_H
#include "../GpuDemo.h"
class GpuRigidBodyDemo : public GpuDemo
{
protected:
class GLInstancingRenderer* m_instancingRenderer;
class b3gWindowInterface* m_window;
struct GpuRigidBodyDemoInternalData* m_data;
public:
GpuRigidBodyDemo();
virtual ~GpuRigidBodyDemo();
virtual void initPhysics(const ConstructionInfo& ci);
virtual void setupScene(const ConstructionInfo& ci);
virtual void destroyScene(){};
virtual void exitPhysics();
virtual const char* getName()
{
return "GRBD";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new GpuRigidBodyDemo;
return demo;
}
virtual void renderScene();
virtual void clientMoveAndDisplay();
};
#endif //GPU_RIGID_BODY_DEMO_H

View File

@@ -0,0 +1,30 @@
#ifndef GPU_RIGIDBODY_INTERNAL_DATA_H
#define GPU_RIGIDBODY_INTERNAL_DATA_H
#include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
#include "Bullet3OpenCL/ParallelPrimitives/b3OpenCLArray.h"
#include "Bullet3Common/b3Vector3.h"
struct GpuRigidBodyDemoInternalData
{
cl_kernel m_copyTransformsToVBOKernel;
b3OpenCLArray<b3Vector4>* m_instancePosOrnColor;
class b3GpuRigidBodyPipeline* m_rigidBodyPipeline;
class b3GpuNarrowPhase* m_np;
class b3GpuSapBroadphase* m_bp;
GpuRigidBodyDemoInternalData()
:m_instancePosOrnColor(0),
m_copyTransformsToVBOKernel(0), m_rigidBodyPipeline(0),
m_np(0),
m_bp(0)
{
}
};
#endif//GPU_RIGIDBODY_INTERNAL_DATA_H

View File

@@ -0,0 +1,205 @@
#include "GpuSphereScene.h"
#include "GpuRigidBodyDemo.h"
#include "Bullet3Common/b3Quickprof.h"
#include "OpenGLWindow/ShapeData.h"
#include "OpenGLWindow/GLInstancingRenderer.h"
#include "Bullet3Common/b3Quaternion.h"
#include "OpenGLWindow/b3gWindowInterface.h"
#include "Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.h"
#include "../GpuDemoInternalData.h"
#include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
#include "OpenGLWindow/OpenGLInclude.h"
#include "OpenGLWindow/GLInstanceRendererInternalData.h"
#include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h"
#include "Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipeline.h"
#include "Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.h"
#include "Bullet3OpenCL/RigidBody/b3Config.h"
#include "GpuRigidBodyDemoInternalData.h"
#include "../gwenUserInterface.h"
void GpuSphereScene::setupScene(const ConstructionInfo& ci)
{
int strideInBytes = 9*sizeof(float);
int numVertices = sizeof(cube_vertices)/strideInBytes;
int numIndices = sizeof(cube_indices)/sizeof(int);
//int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int group=1;
int mask=1;
int index=0;
bool writeInstanceToGpu = false;
if (0)
{
float radius = 60;
int prevGraphicsShapeIndex = -1;
{
if (1)//radius>=100)
{
int numVertices = sizeof(detailed_sphere_vertices)/strideInBytes;
int numIndices = sizeof(detailed_sphere_indices)/sizeof(int);
prevGraphicsShapeIndex = ci.m_instancingRenderer->registerShape(&detailed_sphere_vertices[0],numVertices,detailed_sphere_indices,numIndices);
} else
{
bool usePointSprites = false;
if (usePointSprites)
{
int numVertices = sizeof(point_sphere_vertices)/strideInBytes;
int numIndices = sizeof(point_sphere_indices)/sizeof(int);
prevGraphicsShapeIndex = ci.m_instancingRenderer->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 = ci.m_instancingRenderer->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 = ci.m_instancingRenderer->registerShape(&low_sphere_vertices[0],numVertices,low_sphere_indices,numIndices);
}
}
}
}
b3Vector4 colors[4] =
{
b3Vector4(1,0,0,1),
b3Vector4(0,1,0,1),
b3Vector4(0,1,1,1),
b3Vector4(1,1,0,1),
};
int curColor = 0;
//int colIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
int colIndex = m_data->m_np->registerSphereShape(radius);//>registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
float mass = 0.f;
//b3Vector3 position((j&1)+i*2.2,1+j*2.,(j&1)+k*2.2);
b3Vector3 position(0,0,0);
b3Quaternion orn(0,0,0,1);
b3Vector4 color = colors[curColor];
curColor++;
curColor&=3;
b3Vector4 scaling(radius,radius,radius,1);
int id = ci.m_instancingRenderer->registerGraphicsInstance(prevGraphicsShapeIndex,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(mass,position,orn,colIndex,index, writeInstanceToGpu);
index++;
}
b3Vector4 colors[4] =
{
b3Vector4(1,0,0,1),
b3Vector4(0,1,0,1),
b3Vector4(0,1,1,1),
b3Vector4(1,1,0,1),
};
int curColor = 0;
float radius = 61;
//int colIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
int colIndex = m_data->m_np->registerSphereShape(radius);//>registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
int prevGraphicsShapeIndex = registerGraphicsSphereShape(ci,radius,false);
//for (int i=0;i<ci.arraySizeX;i++)
{
// for (int j=0;j<ci.arraySizeY;j++)
{
// for (int k=0;k<ci.arraySizeZ;k++)
{
int i=0,j=0,k=0;
float mass = 0.f;
b3Vector3 position(0,0,0);
//b3Vector3 position((j&1)+i*142.2,-51+j*142.,(j&1)+k*142.2);
//b3Vector3 position(0,-41,0);//0,0,0);//i*radius*3,-41+j*radius*3,k*radius*3);
b3Quaternion orn(0,0,0,1);
b3Vector4 color = colors[curColor];
curColor++;
curColor&=3;
b3Vector4 scaling(radius,radius,radius,1);
int id = ci.m_instancingRenderer->registerGraphicsInstance(prevGraphicsShapeIndex,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(mass,position,orn,colIndex,index, writeInstanceToGpu);
index++;
}
}
}
if (1)
{
int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
b3Vector4 scaling(0.5,0.5,0.5,1);//1,1,1,1);//0.1,0.1,0.1,1);
int colIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
b3Vector3 normal(0,-1,0);
float constant=2;
for (int j=-10;j<10;j++)
for (int i=-10;i<10;i++)
for (int k=0;k<30;k++)
//int i=0;int j=0;
{
//int colIndex = m_data->m_np->registerPlaneShape(normal,constant);//>registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
b3Vector4 position(2*i,70+k*2,2*j+8,0);
//b3Quaternion orn(0,0,0,1);
b3Quaternion orn(b3Vector3(1,0,0),0.3);
b3Vector4 color(0,0,1,1);
int id = ci.m_instancingRenderer->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(1.f,position,orn,colIndex,index,false);
index++;
}
}
if (!writeInstanceToGpu)
{
m_data->m_rigidBodyPipeline->writeAllInstancesToGpu();
}
float camPos[4]={ci.arraySizeX,ci.arraySizeY/2,ci.arraySizeZ,0};
//float camPos[4]={1,12.5,1.5,0};
m_instancingRenderer->setCameraTargetPosition(camPos);
m_instancingRenderer->setCameraDistance(130);
char msg[1024];
int numInstances = index;
sprintf(msg,"Num objects = %d",numInstances);
ci.m_gui->setStatusBarMessage(msg,true);
}

View File

@@ -0,0 +1,27 @@
#ifndef GPU_SPHERE_SCENE_H
#define GPU_SPHERE_SCENE_H
#include "GpuRigidBodyDemo.h"
class GpuSphereScene : public GpuRigidBodyDemo
{
public:
GpuSphereScene(){}
virtual ~GpuSphereScene(){}
virtual const char* getName()
{
return "GRBSphere";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new GpuSphereScene;
return demo;
}
virtual void setupScene(const ConstructionInfo& ci);
};
#endif //GPU_SPHERE_SCENE_H

View File

@@ -0,0 +1,547 @@
#ifdef __APPLE__
#include "OpenGLWindow/MacOpenGLWindow.h"
#elif defined _WIN32
#include "OpenGLWindow/Win32OpenGLWindow.h"
#elif defined __linux
#include "OpenGLWindow/X11OpenGLWindow.h"
#endif
#include "OpenGLWindow/GLPrimitiveRenderer.h"
#include "OpenGLWindow/GLInstancingRenderer.h"
//#include "OpenGL3CoreRenderer.h"
#include "Bullet3Common/b3Quickprof.h"
//#include "b3GpuDynamicsWorld.h"
#include <assert.h>
#include <string.h>
#include "OpenGLTrueTypeFont/fontstash.h"
#include "OpenGLTrueTypeFont/opengl_fontstashcallbacks.h"
#include "OpenGLWindow/GwenOpenGL3CoreRenderer.h"
#include "Gwen/Gwen.h"
#include "Gwen/Controls/Button.h"
#include "Gwen/Skins/Simple.h"
#include "Gwen/Renderers/OpenGL_DebugFont.h"
#include "Gwen/Controls/MenuStrip.h"
#include "Gwen/Controls/WindowControl.h"
#include "Gwen/Controls/ListBox.h"
#include "Gwen/Controls/VerticalSlider.h"
#include "Gwen/Controls/HorizontalSlider.h"
#include "Gwen/Controls/GroupBox.h"
#include "Gwen/Controls/CheckBox.h"
#include "Gwen/Controls/TreeControl.h"
b3gDefaultOpenGLWindow* window=0;
GLPrimitiveRenderer* primRenderer = 0;
GwenOpenGL3CoreRenderer* pRenderer = 0;
Gwen::Skin::Simple skin;
Gwen::Controls::Canvas* pCanvas =0;
class MyProfileWindow* prof = 0;
int sGlutScreenWidth = 640;
int sGlutScreenHeight = 480;
int sLastmousepos[2] = {0,0};
#include "basic_initialize/b3OpenCLUtils.h"
cl_context g_cxMainContext;
cl_command_queue g_cqCommandQue;
int droidRegular=0;//, droidItalic, droidBold, droidJapanese, dejavu;
extern char OpenSansData[];
sth_stash* stash=0;
sth_stash* initFont(GLPrimitiveRenderer* primRender)
{
GLint err;
struct sth_stash* stash = 0;
int datasize;
float sx,sy,dx,dy,lh;
GLuint texture;
OpenGL2RenderCallbacks* renderCallbacks = new OpenGL2RenderCallbacks(primRender);
stash = sth_create(512,512,renderCallbacks);//256,256);//,1024);//512,512);
err = glGetError();
assert(err==GL_NO_ERROR);
if (!stash)
{
fprintf(stderr, "Could not create stash.\n");
return 0;
}
char* data2 = OpenSansData;
unsigned char* data = (unsigned char*) data2;
if (!(droidRegular = sth_add_font_from_memory(stash, data)))
{
printf("error!\n");
}
err = glGetError();
assert(err==GL_NO_ERROR);
return stash;
}
class MyProfileWindow : public Gwen::Controls::WindowControl
{
// Gwen::Controls::TabControl* m_TabControl;
Gwen::Controls::ListBox* m_TextOutput;
unsigned int m_iFrames;
float m_fLastSecond;
Gwen::Controls::TreeNode* m_node;
Gwen::Controls::TreeControl* m_ctrl;
protected:
void onButtonA( Gwen::Controls::Base* pControl )
{
// OpenTissue::glut::toggleIdle();
}
void SliderMoved(Gwen::Controls::Base* pControl )
{
Gwen::Controls::Slider* pSlider = (Gwen::Controls::Slider*)pControl;
//this->m_app->scaleYoungModulus(pSlider->GetValue());
// printf("Slider Value: %.2f", pSlider->GetValue() );
}
void OnCheckChangedStiffnessWarping (Gwen::Controls::Base* pControl)
{
Gwen::Controls::CheckBox* labeled = (Gwen::Controls::CheckBox* )pControl;
bool checked = labeled->IsChecked();
//m_app->m_stiffness_warp_on = checked;
}
public:
void MenuItemSelect(Gwen::Controls::Base* pControl)
{
if (Hidden())
{
SetHidden(false);
} else
{
SetHidden(true);
}
}
MyProfileWindow ( Gwen::Controls::Base* pParent)
: Gwen::Controls::WindowControl( pParent )
{
SetTitle( L"OpenCL info" );
SetSize( 550, 350 );
this->SetPos(0,40);
// this->Dock( Gwen::Pos::Bottom);
{
m_ctrl = new Gwen::Controls::TreeControl( this );
int numPlatforms = b3OpenCLUtils::getNumPlatforms();
for (int i=0;i<numPlatforms;i++)
{
cl_platform_id platform = b3OpenCLUtils::getPlatform(i);
b3OpenCLPlatformInfo platformInfo;
b3OpenCLUtils::getPlatformInfo(platform, &platformInfo);
cl_device_type deviceType = CL_DEVICE_TYPE_ALL;
cl_int errNum;
cl_context context = b3OpenCLUtils::createContextFromPlatform(platform,deviceType,&errNum);
Gwen::UnicodeString strIn = Gwen::Utility::StringToUnicode(platformInfo.m_platformName);
Gwen::UnicodeString txt = Gwen::Utility::Format( L"Platform %d (",i)+strIn + Gwen::Utility::Format(L")");
m_node = m_ctrl->AddNode(txt);
int numDev = b3OpenCLUtils::getNumDevices(context);
for (int j=0;j<numDev;j++)
{
Gwen::UnicodeString txt = Gwen::Utility::Format( L"Device %d", j);
Gwen::Controls::TreeNode* deviceNode = m_node->AddNode( txt );
cl_device_id device = b3OpenCLUtils::getDevice(context,j);
b3OpenCLDeviceInfo info;
b3OpenCLUtils::getDeviceInfo(device,&info);
Gwen::Controls::TreeNode* node;
Gwen::UnicodeString strIn;
switch (info.m_deviceType)
{
case CL_DEVICE_TYPE_CPU:
{
txt = Gwen::Utility::Format( L"CL_DEVICE_TYPE_CPU");
node = deviceNode->AddNode( txt );
break;
}
case CL_DEVICE_TYPE_GPU:
{
txt = Gwen::Utility::Format( L"CL_DEVICE_TYPE_GPU");
node = deviceNode->AddNode( txt );
break;
}
case CL_DEVICE_TYPE_ACCELERATOR:
{
txt = Gwen::Utility::Format( L"CL_DEVICE_TYPE_ACCELERATOR");
node = deviceNode->AddNode( txt );
break;
}
default:
{
txt = Gwen::Utility::Format( L"Unknown device type");
node = deviceNode->AddNode( txt );
}
}
strIn = Gwen::Utility::StringToUnicode(info.m_deviceName);
txt = Gwen::Utility::Format( L"CL_DEVICE_NAME: ")+strIn;
node = deviceNode->AddNode( txt );
strIn = Gwen::Utility::StringToUnicode(info.m_deviceVendor);
txt = Gwen::Utility::Format( L"CL_DEVICE_VENDOR: ")+strIn;
node = deviceNode->AddNode( txt );
strIn = Gwen::Utility::StringToUnicode(info.m_driverVersion);
txt = Gwen::Utility::Format( L"CL_DRIVER_VERSION: ")+strIn;
node = deviceNode->AddNode( txt );
txt = Gwen::Utility::Format( L"CL_DEVICE_MAX_COMPUTE_UNITS:%u",info.m_computeUnits);
node = deviceNode->AddNode( txt );
txt = Gwen::Utility::Format( L"CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:%u",info.m_workitemDims);
node = deviceNode->AddNode( txt );
txt = Gwen::Utility::Format( L"CL_DEVICE_MAX_WORK_ITEM_SIZES:%u / %u / %u",info.m_workItemSize[0], info.m_workItemSize[1], info.m_workItemSize[2]);
node = deviceNode->AddNode( txt );
txt = Gwen::Utility::Format( L"CL_DEVICE_MAX_WORK_GROUP_SIZE:%u",info.m_workgroupSize);
node = deviceNode->AddNode( txt );
txt = Gwen::Utility::Format( L"CL_DEVICE_MAX_CLOCK_FREQUENCY:%u MHz",info.m_clockFrequency);
node = deviceNode->AddNode( txt );
txt = Gwen::Utility::Format( L"CL_DEVICE_ADDRESS_BITS:%u",info.m_addressBits);
node = deviceNode->AddNode( txt );
txt = Gwen::Utility::Format( L"CL_DEVICE_MAX_MEM_ALLOC_SIZE:%u MByte",(unsigned int)(info.m_maxMemAllocSize/ (1024 * 1024)));
node = deviceNode->AddNode( txt );
txt = Gwen::Utility::Format( L"CL_DEVICE_GLOBAL_MEM_SIZE:%u MByte",(unsigned int)(info.m_globalMemSize/ (1024 * 1024)));
node = deviceNode->AddNode( txt );
txt = Gwen::Utility::Format( L"CL_DEVICE_ERROR_CORRECTION_SUPPORT:%s",info.m_errorCorrectionSupport== CL_TRUE ? L"yes" : L"no");
node = deviceNode->AddNode( txt );
txt = Gwen::Utility::Format( L"CL_DEVICE_LOCAL_MEM_TYPE:%s",info.m_localMemType == 1 ? L"local" : L"global");
node = deviceNode->AddNode( txt );
txt = Gwen::Utility::Format( L"CL_DEVICE_LOCAL_MEM_SIZE:%u KByte",(unsigned int)(info.m_localMemSize / 1024));
node = deviceNode->AddNode( txt );
txt = Gwen::Utility::Format( L"CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:%u KByte",(unsigned int)(info.m_constantBufferSize / 1024));
node = deviceNode->AddNode( txt );
if( info.m_queueProperties & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE )
{
txt = Gwen::Utility::Format( L"CL_DEVICE_QUEUE_PROPERTIES:\tCL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE");
node = deviceNode->AddNode( txt );
}
if( info.m_queueProperties & CL_QUEUE_PROFILING_ENABLE )
{
txt = Gwen::Utility::Format( L"CL_DEVICE_QUEUE_PROPERTIES:\tCL_QUEUE_PROFILING_ENABLE");
node = deviceNode->AddNode( txt );
}
txt = Gwen::Utility::Format( L"CL_DEVICE_IMAGE_SUPPORT:%u",info.m_imageSupport);
node = deviceNode->AddNode( txt );
txt = Gwen::Utility::Format( L"CL_DEVICE_MAX_READ_IMAGE_ARGS:%u",info.m_maxReadImageArgs);
node = deviceNode->AddNode( txt );
txt = Gwen::Utility::Format( L"CL_DEVICE_MAX_WRITE_IMAGE_ARGS:%u",info.m_maxWriteImageArgs);
node = deviceNode->AddNode( txt );
txt = Gwen::Utility::Format( L"CL_DEVICE_EXTENSIONS");
Gwen::Controls::TreeNode* extensionNode = deviceNode->AddNode( txt );
if (info.m_deviceExtensions)
{
Gwen::Utility::Strings::List outbits;
Gwen::String str(info.m_deviceExtensions);
Gwen::String sep(" ");
Gwen::Utility::Strings::Split(str,sep, outbits);
for (int k=0;k<outbits.size();k++)
{
if (outbits.at(k).size())
{
txt = Gwen::Utility::StringToUnicode(outbits.at(k));
node = extensionNode->AddNode( txt );
}
}
}
/*
printf("\n CL_DEVICE_IMAGE <dim>");
printf("\t2D_MAX_WIDTH %u\n", info.m_image2dMaxWidth);
printf("\t2D_MAX_HEIGHT %u\n", info.m_image2dMaxHeight);
printf("\t3D_MAX_WIDTH %u\n", info.m_image3dMaxWidth);
printf("\t3D_MAX_HEIGHT %u\n", info.m_image3dMaxHeight);
printf("\t3D_MAX_DEPTH %u\n", info.m_image3dMaxDepth);
printf(" CL_DEVICE_PREFERRED_VECTOR_WIDTH_<t>");
printf("CHAR %u, SHORT %u, INT %u,LONG %u, FLOAT %u, DOUBLE %u\n\n\n",
info.m_vecWidthChar, info.m_vecWidthShort, info.m_vecWidthInt, info.m_vecWidthLong,info.m_vecWidthFloat, info.m_vecWidthDouble);
*/
}
}
m_ctrl->ExpandAll();
m_ctrl->SetBounds( this->GetInnerBounds().x,this->GetInnerBounds().y,this->GetInnerBounds().w,this->GetInnerBounds().h);
}
}
void UpdateText()
{
static bool update=true;
m_ctrl->SetBounds(0,0,this->GetInnerBounds().w,this->GetInnerBounds().h);
}
};
struct MyTestMenuBar : public Gwen::Controls::MenuStrip
{
MyProfileWindow* m_profileWindow;
void MenuItemSelect(Gwen::Controls::Base* pControl)
{
}
MyTestMenuBar(Gwen::Controls::Base* pParent, MyProfileWindow* prof)
:Gwen::Controls::MenuStrip(pParent),
m_profileWindow(prof)
{
{
Gwen::Controls::MenuItem* pRoot = AddItem( L"File" );
pRoot = AddItem( L"View" );
pRoot->GetMenu()->AddItem( L"Platforms",prof,(Gwen::Event::Handler::Function)&MyProfileWindow::MenuItemSelect);
}
}
};
float retinaScale = 1.f;
void setupGUI(int width, int height)
{
primRenderer = new GLPrimitiveRenderer(width,height);
stash = initFont(primRenderer);
pRenderer = new GwenOpenGL3CoreRenderer(primRenderer,stash,width,height,retinaScale);
skin.SetRender( pRenderer );
pCanvas = new Gwen::Controls::Canvas( &skin );
pCanvas->SetSize( width,height);
pCanvas->SetDrawBackground( false);
pCanvas->SetBackgroundColor( Gwen::Color( 150, 170, 170, 255 ) );
//MyWindow* window = new MyWindow(pCanvas);
prof = new MyProfileWindow(pCanvas);
prof->UpdateText();
MyTestMenuBar* menubar = new MyTestMenuBar(pCanvas, prof);
}
static void MyResizeCallback(float w, float h)
{
sGlutScreenWidth = w;
sGlutScreenHeight = h;
if (pRenderer)
pRenderer->resize(w,h);
if (primRenderer)
primRenderer->setScreenSize(w,h);
if (pCanvas)
{
pCanvas->SetSize(w,h);
}
}
static void MouseButtonCallback(int button, int state, float x, float y)
{
if (pCanvas)
{
bool handled = false;
if (pCanvas)
{
handled = pCanvas->InputMouseMoved(x,y,x, y);
if (button>=0)
{
handled = pCanvas->InputMouseButton(button,state);
if (handled)
{
//if (!state)
// return false;
}
}
}
if (handled)
{
sLastmousepos[0] = x;
sLastmousepos[1] = y;
} else
{
b3DefaultMouseButtonCallback(button,state,x,y);
}
}
}
static void MouseMoveCallback(float x,float y)
{
bool handled = false;
static int m_lastmousepos[2] = {0,0};
static bool isInitialized = false;
if (pCanvas)
{
if (!isInitialized)
{
isInitialized = true;
m_lastmousepos[0] = x+1;
m_lastmousepos[1] = y+1;
}
handled = pCanvas->InputMouseMoved(x,y,m_lastmousepos[0],m_lastmousepos[1]);
}
}
int main(int argc, char* argv[])
{
window = new b3gDefaultOpenGLWindow();
b3gWindowConstructionInfo wci(sGlutScreenWidth,sGlutScreenHeight);
window->createWindow(wci);
window->setResizeCallback(MyResizeCallback);
window->setMouseMoveCallback(MouseMoveCallback);
window->setMouseButtonCallback(MouseButtonCallback);
//window->setKeyboardCallback(MyKeyboardCallback);
window->setWindowTitle("Bullet 3.x GPU Rigid Body http://bulletphysics.org");
printf("-----------------------------------------------------\n");
#ifndef __APPLE__
glewInit();
#endif
setupGUI(sGlutScreenWidth,sGlutScreenHeight);
do
{
b3ProfileManager::Reset();
b3ProfileManager::Increment_Frame_Counter();
window->startRendering();
glClearColor(0.6,0.6,0.6,1);
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
// demo->clientMoveAndDisplay();
//saveOpenGLState(sGlutScreenWidth,sGlutScreenHeight);
{
B3_PROFILE("gui->draw");
//gui->draw(g_OpenGLWidth,g_OpenGLHeight);
{
B3_PROFILE("UpdateText");
if (prof)
prof->UpdateText();
}
{
B3_PROFILE("RenderCanvas");
pCanvas->RenderCanvas();
}
//restoreOpenGLState();
}
{
B3_PROFILE("window->endRendering");
window->endRendering();
}
b3ProfileManager::dumpAll();
} while (!window->requestedExit());
return 0;
}

View File

@@ -0,0 +1,84 @@
function createProject(vendor)
hasCL = findOpenCL(vendor)
if (hasCL) then
project ("OpenCL_GUI_Intialize_" .. vendor)
initOpenCL(vendor)
language "C++"
kind "ConsoleApp"
targetdir "../../bin"
includedirs {
"..",
"../../opencl",
"../../btgui",
"../../src",
}
links {
"gwen"
}
initOpenGL()
initGlew()
files {
"main.cpp",
"../../opencl/basic_initialize/b3OpenCLUtils.cpp",
"../../opencl/basic_initialize/b3OpenCLUtils.h",
"../../btgui/OpenGLWindow/GLInstancingRenderer.cpp",
"../../btgui/OpenGLWindow/GLInstancingRenderer.h",
"../../btgui/OpenGLWindow/GLPrimitiveRenderer.h",
"../../btgui/OpenGLWindow/GLPrimitiveRenderer.cpp",
"../../btgui/OpenGLWindow/LoadShader.cpp",
"../../btgui/OpenGLWindow/LoadShader.h",
"../../btgui/OpenGLWindow/TwFonts.cpp",
"../../btgui/OpenGLWindow/TwFonts.h",
"../../btgui/OpenGLWindow/GwenOpenGL3CoreRenderer.h",
"../../btgui/FontFiles/OpenSans.cpp",
"../../btgui/OpenGLTrueTypeFont/fontstash.cpp",
"../../btgui/OpenGLTrueTypeFont/fontstash.h",
"../../btgui/OpenGLTrueTypeFont/opengl_fontstashcallbacks.cpp",
"../../btgui/OpenGLTrueTypeFont/opengl_fontstashcallbacks.h",
"../../src/Bullet3Geometry/b3ConvexHullComputer.cpp",
"../../src/Bullet3Geometry/b3ConvexHullComputer.h",
"../../src/Bullet3Common/b3AlignedAllocator.cpp",
"../../src/Bullet3Common/b3Quickprof.cpp",
"../../src/Bullet3Common/b3Quickprof.h"
}
if os.is("Windows") then
files{
"../../btgui/OpenGLWindow/Win32OpenGLWindow.cpp",
"../../btgui/OpenGLWindow/Win32OpenGLWindow.h",
"../../btgui/OpenGLWindow/Win32Window.cpp",
"../../btgui/OpenGLWindow/Win32Window.h",
}
end
if os.is("Linux") then
files {
"../../btgui/OpenGLWindow/X11OpenGLWindow.cpp",
"../../btgui/OpenGLWindow/X11OpenGLWindows.h"
}
end
if os.is("MacOSX") then
links {"Cocoa.framework"}
files {
"../../btgui/OpenGLWindow/MacOpenGLWindow.h",
"../../btgui/OpenGLWindow/MacOpenGLWindow.mm",
}
end
end
end
createProject("Apple")
createProject("AMD")
createProject("Intel")
createProject("NVIDIA")

205
Demos3/Wavefront/list.cpp Normal file
View File

@@ -0,0 +1,205 @@
#include "list.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
// internal helper functions
char list_is_full(list *listo)
{
return(listo->item_count == listo->current_max_size);
}
void list_grow(list *old_listo)
{
int i;
list new_listo;
list_make(&new_listo, old_listo->current_max_size*2, old_listo->growable++);
for(i=0; i<old_listo->current_max_size; i++)
list_add_item(&new_listo, old_listo->items[i] , old_listo->names[i]);
list_free(old_listo);
//copy new structure to old list
old_listo->names = new_listo.names;
old_listo->items = new_listo.items;
old_listo->item_count = new_listo.item_count;
old_listo->current_max_size = new_listo.current_max_size;
old_listo->growable = new_listo.growable;
}
//end helpers
void list_make(list *listo, int start_size, char growable)
{
listo->names = (char**) malloc(sizeof(char*) * start_size);
listo->items = (void**) malloc(sizeof(void*) * start_size);
listo->item_count = 0;
listo->current_max_size = start_size;
listo->growable = growable;
}
int list_add_item(list *listo, void *item, char *name)
{
int name_length;
char *new_name;
if( list_is_full(listo) )
{
if( listo->growable )
list_grow(listo);
else
return -1;
}
listo->names[listo->item_count] = NULL;
if(name != NULL)
{
name_length = strlen(name);
new_name = (char*) malloc(sizeof(char) * name_length + 1);
strncpy(new_name, name, name_length);
listo->names[listo->item_count] = new_name;
}
listo->items[listo->item_count] = item;
listo->item_count++;
return listo->item_count-1;
}
char* list_print_items(list *listo)
{
int i;
for(i=0; i < listo->item_count; i++)
{
printf("%s\n", listo->names[i]);
}
return NULL;
}
void* list_get_index(list *listo, int indx)
{
if(indx < listo->item_count)
return listo->items[indx];
return NULL;
}
void* list_get_item(list *listo, void *item_to_find)
{
int i = 0;
for(i=0; i < listo->item_count; i++)
{
if(listo->items[i] == item_to_find)
return listo->items[i];
}
return NULL;
}
void* list_get_name(list *listo, char *name_to_find)
{
int i = 0;
for(i=0; i < listo->item_count; i++)
{
if(strncmp(listo->names[i], name_to_find, strlen(name_to_find)) == 0)
return listo->items[i];
}
return NULL;
}
int list_find(list *listo, char *name_to_find)
{
int i = 0;
for(i=0; i < listo->item_count; i++)
{
if(strncmp(listo->names[i], name_to_find, strlen(name_to_find)) == 0)
return i;
}
return -1;
}
void list_delete_item(list *listo, void *item)
{
int i;
for(i=0; i < listo->item_count; i++)
{
if( listo->items[i] == item )
list_delete_index(listo, i);
}
}
void list_delete_name(list *listo, char *name)
{
int i;
//int j;
//char remove = 0;
// int length_name = strlen(name);
int item_name;
if(name == NULL)
return;
for(i=0; i < listo->item_count; i++)
{
item_name = strlen(name);
if( name != NULL && (strncmp(listo->names[i], name, strlen(name)) == 0) )
list_delete_index(listo, i);
}
}
void list_delete_index(list *listo, int indx)
{
int j;
//remove item
if(listo->names[indx] != NULL)
free(listo->names[indx]);
//restructure
for(j=indx; j < listo->item_count-1; j++)
{
listo->names[j] = listo->names[j+1];
listo->items[j] = listo->items[j+1];
}
listo->item_count--;
return;
}
void list_delete_all(list *listo)
{
int i;
for(i=listo->item_count-1; i>=0; i--)
list_delete_index(listo, i);
}
void list_free(list *listo)
{
list_delete_all(listo);
free(listo->names);
free(listo->items);
}
void list_print_list(list *listo)
{
int i;
printf("count: %i/%i\n", listo->item_count, listo->current_max_size);
for(i=0; i < listo->item_count; i++)
{
printf("list[%i]: %s\n", i, listo->names[i]);
}
}

29
Demos3/Wavefront/list.h Normal file
View File

@@ -0,0 +1,29 @@
#ifndef __LIST_H
#define __LIST_H
typedef struct
{
int item_count;
int current_max_size;
char growable;
void **items;
char **names;
} list;
void list_make(list *listo, int size, char growable);
int list_add_item(list *listo, void *item, char *name);
char* list_print_items(list *listo);
void* list_get_name(list *listo, char *name);
void* list_get_index(list *listo, int indx);
void* list_get_item(list *listo, void *item_to_find);
int list_find(list *listo, char *name_to_find);
void list_delete_index(list *listo, int indx);
void list_delete_name(list *listo, char *name);
void list_delete_item(list *listo, void *item);
void list_delete_all(list *listo);
void list_print_list(list *listo);
void list_free(list *listo);
void test_list();
#endif

View File

@@ -0,0 +1,46 @@
#include "objLoader.h"
#include "obj_parser.h"
int objLoader::load(char *filename)
{
int no_error = 1;
no_error = parse_obj_scene(&data, filename);
if(no_error)
{
this->vertexCount = data.vertex_count;
this->normalCount = data.vertex_normal_count;
this->textureCount = data.vertex_texture_count;
this->faceCount = data.face_count;
this->sphereCount = data.sphere_count;
this->planeCount = data.plane_count;
this->lightPointCount = data.light_point_count;
this->lightDiscCount = data.light_disc_count;
this->lightQuadCount = data.light_quad_count;
this->materialCount = data.material_count;
this->vertexList = data.vertex_list;
this->normalList = data.vertex_normal_list;
this->textureList = data.vertex_texture_list;
this->faceList = data.face_list;
this->sphereList = data.sphere_list;
this->planeList = data.plane_list;
this->lightPointList = data.light_point_list;
this->lightDiscList = data.light_disc_list;
this->lightQuadList = data.light_quad_list;
this->objectList = data.object_list;
this->objectCount = data.object_count;
this->materialList = data.material_list;
this->camera = data.camera;
}
return no_error;
}

View File

@@ -0,0 +1,52 @@
#ifndef OBJ_LOADER_H
#define OBJ_LOADER_H
#include "obj_parser.h"
class objLoader
{
public:
objLoader() {}
~objLoader()
{
delete_obj_data(&data);
}
int load(char *filename);
obj_vector **vertexList;
obj_vector **normalList;
obj_vector **textureList;
obj_face **faceList;
obj_sphere **sphereList;
obj_plane **planeList;
obj_light_point **lightPointList;
obj_light_quad **lightQuadList;
obj_light_disc **lightDiscList;
obj_object** objectList;
obj_material **materialList;
int vertexCount;
int normalCount;
int textureCount;
int faceCount;
int sphereCount;
int planeCount;
int lightPointCount;
int lightQuadCount;
int lightDiscCount;
int objectCount;
int materialCount;
obj_camera *camera;
private:
obj_scene_data data;
};
#endif

View File

@@ -0,0 +1,167 @@
// Obj_loader.cpp : Defines the entry point for the console application.
//
#include <stdio.h>
#include "objLoader.h"
void printVector(obj_vector *v)
{
printf("%.2f,", v->e[0] );
printf("%.2f,", v->e[1] );
printf("%.2f ", v->e[2] );
}
int main(int argc, char **argv)
{
objLoader *objData = new objLoader();
objData->load("test.obj");
printf("Number of vertices: %i\n", objData->vertexCount);
printf("Number of vertex normals: %i\n", objData->normalCount);
printf("Number of texture coordinates: %i\n", objData->textureCount);
printf("\n");
printf("Number of faces: %i\n", objData->faceCount);
for(int i=0; i<objData->faceCount; i++)
{
obj_face *o = objData->faceList[i];
printf(" face ");
for(int j=0; j<3; j++)
{
printVector(objData->vertexList[ o->vertex_index[j] ]);
}
printf("\n");
}
printf("\n");
printf("Number of spheres: %i\n", objData->sphereCount);
for(int i=0; i<objData->sphereCount; i++)
{
obj_sphere *o = objData->sphereList[i];
printf(" sphere ");
printVector(objData->vertexList[ o->pos_index ]);
printVector(objData->normalList[ o->up_normal_index ]);
printVector(objData->normalList[ o->equator_normal_index ]);
printf("\n");
}
printf("\n");
printf("Number of planes: %i\n", objData->planeCount);
for(int i=0; i<objData->planeCount; i++)
{
obj_plane *o = objData->planeList[i];
printf(" plane ");
printVector(objData->vertexList[ o->pos_index ]);
printVector(objData->normalList[ o->normal_index]);
printVector(objData->normalList[ o->rotation_normal_index]);
printf("\n");
}
printf("\n");
printf("Number of point lights: %i\n", objData->lightPointCount);
for(int i=0; i<objData->lightPointCount; i++)
{
obj_light_point *o = objData->lightPointList[i];
printf(" plight ");
printVector(objData->vertexList[ o->pos_index ]);
printf("\n");
}
printf("\n");
printf("Number of disc lights: %i\n", objData->lightDiscCount);
for(int i=0; i<objData->lightDiscCount; i++)
{
obj_light_disc *o = objData->lightDiscList[i];
printf(" dlight ");
printVector(objData->vertexList[ o->pos_index ]);
printVector(objData->normalList[ o->normal_index ]);
printf("\n");
}
printf("\n");
printf("Number of quad lights: %i\n", objData->lightQuadCount);
for(int i=0; i<objData->lightQuadCount; i++)
{
obj_light_quad *o = objData->lightQuadList[i];
printf(" qlight ");
printVector(objData->vertexList[ o->vertex_index[0] ]);
printVector(objData->vertexList[ o->vertex_index[1] ]);
printVector(objData->vertexList[ o->vertex_index[2] ]);
printVector(objData->vertexList[ o->vertex_index[3] ]);
printf("\n");
}
printf("\n");
if(objData->camera != NULL)
{
printf("Found a camera\n");
printf(" position: ");
printVector(objData->vertexList[ objData->camera->camera_pos_index ]);
printf("\n looking at: ");
printVector(objData->vertexList[ objData->camera->camera_look_point_index ]);
printf("\n up normal: ");
printVector(objData->normalList[ objData->camera->camera_up_norm_index ]);
printf("\n");
}
printf("\n");
printf("Number of materials: %i\n", objData->materialCount);
for(int i=0; i<objData->materialCount; i++)
{
obj_material *mtl = objData->materialList[i];
printf(" name: %s", mtl->name);
printf(" amb: %.2f ", mtl->amb[0]);
printf("%.2f ", mtl->amb[1]);
printf("%.2f\n", mtl->amb[2]);
printf(" diff: %.2f ", mtl->diff[0]);
printf("%.2f ", mtl->diff[1]);
printf("%.2f\n", mtl->diff[2]);
printf(" spec: %.2f ", mtl->spec[0]);
printf("%.2f ", mtl->spec[1]);
printf("%.2f\n", mtl->spec[2]);
printf(" reflect: %.2f\n", mtl->reflect);
printf(" trans: %.2f\n", mtl->trans);
printf(" glossy: %i\n", mtl->glossy);
printf(" shiny: %i\n", mtl->shiny);
printf(" refact: %.2f\n", mtl->refract_index);
printf(" texture: %s\n", mtl->texture_filename);
printf("\n");
}
printf("\n");
//vertex, normal, and texture test
if(objData->textureCount > 2 && objData->normalCount > 2 && objData->faceCount > 2)
{
printf("Detailed face data:\n");
for(int i=0; i<3; i++)
{
obj_face *o = objData->faceList[i];
printf(" face ");
for(int j=0; j<3; j++)
{
printf("%i/", o->vertex_index[j] );
printf("%i/", o->texture_index[j] );
printf("%i ", o->normal_index[j] );
}
printf("\n");
}
}
return 0;
}

View File

@@ -0,0 +1,591 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "obj_parser.h"
#include "list.h"
#include "string_extra.h"
#define WHITESPACE " \t\n\r"
void obj_free_half_list(list *listo)
{
list_delete_all(listo);
free(listo->names);
}
int obj_convert_to_list_index(int current_max, int index)
{
if(index == 0) //no index
return -1;
if(index < 0) //relative to current list position
return current_max + index;
return index - 1; //normal counting index
}
void obj_convert_to_list_index_v(int current_max, int *indices)
{
for(int i=0; i<MAX_VERTEX_COUNT; i++)
indices[i] = obj_convert_to_list_index(current_max, indices[i]);
}
void obj_set_material_defaults(obj_material *mtl)
{
mtl->amb[0] = 0.2;
mtl->amb[1] = 0.2;
mtl->amb[2] = 0.2;
mtl->diff[0] = 0.8;
mtl->diff[1] = 0.8;
mtl->diff[2] = 0.8;
mtl->spec[0] = 1.0;
mtl->spec[1] = 1.0;
mtl->spec[2] = 1.0;
mtl->reflect = 0.0;
mtl->trans = 1;
mtl->glossy = 98;
mtl->shiny = 0;
mtl->refract_index = 1;
mtl->texture_filename[0] = '\0';
}
int obj_parse_vertex_index(int *vertex_index, int *texture_index, int *normal_index)
{
char *temp_str;
char *token;
int vertex_count = 0;
while( (token = strtok(NULL, WHITESPACE)) != NULL)
{
if(texture_index != NULL)
texture_index[vertex_count] = 0;
if(normal_index != NULL)
normal_index[vertex_count] = 0;
vertex_index[vertex_count] = atoi( token );
if(contains(token, "//")) //normal only
{
temp_str = strchr(token, '/');
temp_str++;
normal_index[vertex_count] = atoi( ++temp_str );
}
else if(contains(token, "/"))
{
temp_str = strchr(token, '/');
texture_index[vertex_count] = atoi( ++temp_str );
if(contains(temp_str, "/"))
{
temp_str = strchr(temp_str, '/');
normal_index[vertex_count] = atoi( ++temp_str );
}
}
vertex_count++;
}
return vertex_count;
}
obj_object* obj_parse_object(obj_growable_scene_data *scene)
{
obj_object* obj= (obj_object*)malloc(sizeof(obj_object));
obj->vertex_offset = scene->vertex_list.item_count;
obj->face_offset = scene->face_list.item_count;
// get the name
strncpy(obj->name, strtok(NULL, " \t"), OBJECT_NAME_SIZE);
return obj;
}
obj_face* obj_parse_face(obj_growable_scene_data *scene)
{
int vertex_count;
obj_face *face = (obj_face*)malloc(sizeof(obj_face));
vertex_count = obj_parse_vertex_index(face->vertex_index, face->texture_index, face->normal_index);
obj_convert_to_list_index_v(scene->vertex_list.item_count, face->vertex_index);
obj_convert_to_list_index_v(scene->vertex_texture_list.item_count, face->texture_index);
obj_convert_to_list_index_v(scene->vertex_normal_list.item_count, face->normal_index);
face->vertex_count = vertex_count;
return face;
}
obj_sphere* obj_parse_sphere(obj_growable_scene_data *scene)
{
int temp_indices[MAX_VERTEX_COUNT];
obj_sphere *obj = (obj_sphere*)malloc(sizeof(obj_sphere));
obj_parse_vertex_index(temp_indices, obj->texture_index, NULL);
obj_convert_to_list_index_v(scene->vertex_texture_list.item_count, obj->texture_index);
obj->pos_index = obj_convert_to_list_index(scene->vertex_list.item_count, temp_indices[0]);
obj->up_normal_index = obj_convert_to_list_index(scene->vertex_normal_list.item_count, temp_indices[1]);
obj->equator_normal_index = obj_convert_to_list_index(scene->vertex_normal_list.item_count, temp_indices[2]);
return obj;
}
obj_plane* obj_parse_plane(obj_growable_scene_data *scene)
{
int temp_indices[MAX_VERTEX_COUNT];
obj_plane *obj = (obj_plane*)malloc(sizeof(obj_plane));
obj_parse_vertex_index(temp_indices, obj->texture_index, NULL);
obj_convert_to_list_index_v(scene->vertex_texture_list.item_count, obj->texture_index);
obj->pos_index = obj_convert_to_list_index(scene->vertex_list.item_count, temp_indices[0]);
obj->normal_index = obj_convert_to_list_index(scene->vertex_normal_list.item_count, temp_indices[1]);
obj->rotation_normal_index = obj_convert_to_list_index(scene->vertex_normal_list.item_count, temp_indices[2]);
return obj;
}
obj_light_point* obj_parse_light_point(obj_growable_scene_data *scene)
{
obj_light_point *o= (obj_light_point*)malloc(sizeof(obj_light_point));
o->pos_index = obj_convert_to_list_index(scene->vertex_list.item_count, atoi( strtok(NULL, WHITESPACE)) );
return o;
}
obj_light_quad* obj_parse_light_quad(obj_growable_scene_data *scene)
{
obj_light_quad *o = (obj_light_quad*)malloc(sizeof(obj_light_quad));
obj_parse_vertex_index(o->vertex_index, NULL, NULL);
obj_convert_to_list_index_v(scene->vertex_list.item_count, o->vertex_index);
return o;
}
obj_light_disc* obj_parse_light_disc(obj_growable_scene_data *scene)
{
int temp_indices[MAX_VERTEX_COUNT];
obj_light_disc *obj = (obj_light_disc*)malloc(sizeof(obj_light_disc));
obj_parse_vertex_index(temp_indices, NULL, NULL);
obj->pos_index = obj_convert_to_list_index(scene->vertex_list.item_count, temp_indices[0]);
obj->normal_index = obj_convert_to_list_index(scene->vertex_normal_list.item_count, temp_indices[1]);
return obj;
}
obj_vector* obj_parse_vector()
{
obj_vector *v = (obj_vector*)malloc(sizeof(obj_vector));
v->e[0] = atof( strtok(NULL, WHITESPACE));
v->e[1] = atof( strtok(NULL, WHITESPACE));
v->e[2] = atof( strtok(NULL, WHITESPACE));
return v;
}
obj_vector* obj_parse_vector2()
{
obj_vector *v = (obj_vector*)malloc(sizeof(obj_vector));
v->e[0] = atof( strtok(NULL, WHITESPACE));
v->e[1] = atof( strtok(NULL, WHITESPACE));
v->e[2] = 0.f;
return v;
}
void obj_parse_camera(obj_growable_scene_data *scene, obj_camera *camera)
{
int indices[3];
obj_parse_vertex_index(indices, NULL, NULL);
camera->camera_pos_index = obj_convert_to_list_index(scene->vertex_list.item_count, indices[0]);
camera->camera_look_point_index = obj_convert_to_list_index(scene->vertex_list.item_count, indices[1]);
camera->camera_up_norm_index = obj_convert_to_list_index(scene->vertex_normal_list.item_count, indices[2]);
}
int obj_parse_mtl_file(char *filename, list *material_list)
{
int line_number = 0;
char *current_token;
char current_line[OBJ_LINE_SIZE];
char material_open = 0;
obj_material *current_mtl = NULL;
FILE *mtl_file_stream;
// open scene
mtl_file_stream = fopen( filename, "r");
if(mtl_file_stream == 0)
{
fprintf(stderr, "Warning: cannot find material file: %s (skipping)\n", filename);
return 0;
}
list_make(material_list, 10, 1);
while( fgets(current_line, OBJ_LINE_SIZE, mtl_file_stream) )
{
current_token = strtok( current_line, " \t\n\r");
line_number++;
//skip comments
if( current_token == NULL || strequal(current_token, "//") || strequal(current_token, "#"))
continue;
//start material
else if( strequal(current_token, "newmtl"))
{
material_open = 1;
current_mtl = (obj_material*) malloc(sizeof(obj_material));
obj_set_material_defaults(current_mtl);
// get the name
strncpy(current_mtl->name, strtok(NULL, " \t"), MATERIAL_NAME_SIZE);
list_add_item(material_list, current_mtl, current_mtl->name);
}
//ambient
else if( strequal(current_token, "Ka") && material_open)
{
current_mtl->amb[0] = atof( strtok(NULL, " \t"));
current_mtl->amb[1] = atof( strtok(NULL, " \t"));
current_mtl->amb[2] = atof( strtok(NULL, " \t"));
}
//diff
else if( strequal(current_token, "Kd") && material_open)
{
current_mtl->diff[0] = atof( strtok(NULL, " \t"));
current_mtl->diff[1] = atof( strtok(NULL, " \t"));
current_mtl->diff[2] = atof( strtok(NULL, " \t"));
}
//specular
else if( strequal(current_token, "Ks") && material_open)
{
current_mtl->spec[0] = atof( strtok(NULL, " \t"));
current_mtl->spec[1] = atof( strtok(NULL, " \t"));
current_mtl->spec[2] = atof( strtok(NULL, " \t"));
}
//shiny
else if( strequal(current_token, "Ns") && material_open)
{
current_mtl->shiny = atof( strtok(NULL, " \t"));
}
//transparent
else if( strequal(current_token, "d") && material_open)
{
current_mtl->trans = atof( strtok(NULL, " \t"));
}
//reflection
else if( strequal(current_token, "r") && material_open)
{
current_mtl->reflect = atof( strtok(NULL, " \t"));
}
//glossy
else if( strequal(current_token, "sharpness") && material_open)
{
current_mtl->glossy = atof( strtok(NULL, " \t"));
}
//refract index
else if( strequal(current_token, "Ni") && material_open)
{
current_mtl->refract_index = atof( strtok(NULL, " \t"));
}
// illumination type
else if( strequal(current_token, "illum") && material_open)
{
}
// texture map
else if( strequal(current_token, "map_Ka") && material_open)
{
strncpy(current_mtl->texture_filename, strtok(NULL, " \t"), OBJ_FILENAME_LENGTH);
}
else
{
fprintf(stderr, "Unknown command '%s' in material file %s at line %i:\n\t%s\n",
current_token, filename, line_number, current_line);
//return 0;
}
}
fclose(mtl_file_stream);
return 1;
}
int obj_parse_obj_file(obj_growable_scene_data *growable_data, char *filename)
{
FILE* obj_file_stream;
int current_material = -1;
char *current_token = NULL;
char current_line[OBJ_LINE_SIZE];
int line_number = 0;
// open scene
obj_file_stream = fopen( filename, "r");
if(obj_file_stream == 0)
{
fprintf(stderr, "Error reading file: %s\n", filename);
return 0;
}
/*
extreme_dimensions[0].x = INFINITY; extreme_dimensions[0].y = INFINITY; extreme_dimensions[0].z = INFINITY;
extreme_dimensions[1].x = -INFINITY; extreme_dimensions[1].y = -INFINITY; extreme_dimensions[1].z = -INFINITY;
if(v->x < extreme_dimensions[0].x) extreme_dimensions[0].x = v->x;
if(v->x > extreme_dimensions[1].x) extreme_dimensions[1].x = v->x;
if(v->y < extreme_dimensions[0].y) extreme_dimensions[0].y = v->y;
if(v->y > extreme_dimensions[1].y) extreme_dimensions[1].y = v->y;
if(v->z < extreme_dimensions[0].z) extreme_dimensions[0].z = v->z;
if(v->z > extreme_dimensions[1].z) extreme_dimensions[1].z = v->z;*/
//parser loop
while( fgets(current_line, OBJ_LINE_SIZE, obj_file_stream) )
{
current_token = strtok( current_line, " \t\n\r");
line_number++;
//skip comments
if( current_token == NULL || current_token[0] == '#')
continue;
//parse objects
else if( strequal(current_token, "v") ) //process vertex
{
list_add_item(&growable_data->vertex_list, obj_parse_vector(), NULL);
}
else if( strequal(current_token, "vn") ) //process vertex normal
{
list_add_item(&growable_data->vertex_normal_list, obj_parse_vector(), NULL);
}
else if( strequal(current_token, "vt") ) //process vertex texture
{
list_add_item(&growable_data->vertex_texture_list, obj_parse_vector2(), NULL);
}
else if( strequal(current_token, "f") ) //process face
{
obj_face *face = obj_parse_face(growable_data);
face->material_index = current_material;
list_add_item(&growable_data->face_list, face, NULL);
}
else if( strequal(current_token, "sp") ) //process sphere
{
obj_sphere *sphr = obj_parse_sphere(growable_data);
sphr->material_index = current_material;
list_add_item(&growable_data->sphere_list, sphr, NULL);
}
else if( strequal(current_token, "pl") ) //process plane
{
obj_plane *pl = obj_parse_plane(growable_data);
pl->material_index = current_material;
list_add_item(&growable_data->plane_list, pl, NULL);
}
else if( strequal(current_token, "p") ) //process point
{
//make a small sphere to represent the point?
}
else if( strequal(current_token, "lp") ) //light point source
{
obj_light_point *o = obj_parse_light_point(growable_data);
o->material_index = current_material;
list_add_item(&growable_data->light_point_list, o, NULL);
}
else if( strequal(current_token, "ld") ) //process light disc
{
obj_light_disc *o = obj_parse_light_disc(growable_data);
o->material_index = current_material;
list_add_item(&growable_data->light_disc_list, o, NULL);
}
else if( strequal(current_token, "lq") ) //process light quad
{
obj_light_quad *o = obj_parse_light_quad(growable_data);
o->material_index = current_material;
list_add_item(&growable_data->light_quad_list, o, NULL);
}
else if( strequal(current_token, "c") ) //camera
{
growable_data->camera = (obj_camera*) malloc(sizeof(obj_camera));
obj_parse_camera(growable_data, growable_data->camera);
}
else if( strequal(current_token, "usemtl") ) // usemtl
{
current_material = list_find(&growable_data->material_list, strtok(NULL, WHITESPACE));
}
else if( strequal(current_token, "mtllib") ) // mtllib
{
strncpy(growable_data->material_filename, strtok(NULL, WHITESPACE), OBJ_FILENAME_LENGTH);
obj_parse_mtl_file(growable_data->material_filename, &growable_data->material_list);
continue;
}
else if( strequal(current_token, "o") ) //object name
{
obj_object* obj = obj_parse_object(growable_data);
list_add_item(&growable_data->object_list, obj, NULL);
}
else if( strequal(current_token, "s") ) //smoothing
{ }
else if( strequal(current_token, "g") ) // group
{ }
else
{
printf("Unknown command '%s' in scene code at line %i: \"%s\".\n",
current_token, line_number, current_line);
}
}
fclose(obj_file_stream);
return 1;
}
void obj_init_temp_storage(obj_growable_scene_data *growable_data)
{
list_make(&growable_data->vertex_list, 10, 1);
list_make(&growable_data->vertex_normal_list, 10, 1);
list_make(&growable_data->vertex_texture_list, 10, 1);
list_make(&growable_data->face_list, 10, 1);
list_make(&growable_data->sphere_list, 10, 1);
list_make(&growable_data->plane_list, 10, 1);
list_make(&growable_data->light_point_list, 10, 1);
list_make(&growable_data->light_quad_list, 10, 1);
list_make(&growable_data->light_disc_list, 10, 1);
list_make(&growable_data->object_list,10,1);
list_make(&growable_data->material_list, 10, 1);
growable_data->camera = NULL;
}
void obj_free_temp_storage(obj_growable_scene_data *growable_data)
{
obj_free_half_list(&growable_data->vertex_list);
obj_free_half_list(&growable_data->vertex_normal_list);
obj_free_half_list(&growable_data->vertex_texture_list);
obj_free_half_list(&growable_data->face_list);
obj_free_half_list(&growable_data->sphere_list);
obj_free_half_list(&growable_data->plane_list);
obj_free_half_list(&growable_data->light_point_list);
obj_free_half_list(&growable_data->light_quad_list);
obj_free_half_list(&growable_data->light_disc_list);
obj_free_half_list(&growable_data->object_list);
obj_free_half_list(&growable_data->material_list);
}
void delete_obj_data(obj_scene_data *data_out)
{
int i;
for(i=0; i<data_out->vertex_count; i++)
free(data_out->vertex_list[i]);
free(data_out->vertex_list);
for(i=0; i<data_out->vertex_normal_count; i++)
free(data_out->vertex_normal_list[i]);
free(data_out->vertex_normal_list);
for(i=0; i<data_out->vertex_texture_count; i++)
free(data_out->vertex_texture_list[i]);
free(data_out->vertex_texture_list);
for(i=0; i<data_out->face_count; i++)
free(data_out->face_list[i]);
free(data_out->face_list);
for(i=0; i<data_out->sphere_count; i++)
free(data_out->sphere_list[i]);
free(data_out->sphere_list);
for(i=0; i<data_out->plane_count; i++)
free(data_out->plane_list[i]);
free(data_out->plane_list);
for(i=0; i<data_out->light_point_count; i++)
free(data_out->light_point_list[i]);
free(data_out->light_point_list);
for(i=0; i<data_out->light_disc_count; i++)
free(data_out->light_disc_list[i]);
free(data_out->light_disc_list);
for(i=0; i<data_out->light_quad_count; i++)
free(data_out->light_quad_list[i]);
free(data_out->light_quad_list);
for(i=0; i<data_out->object_count; i++)
free(data_out->object_list[i]);
free(data_out->object_list);
for(i=0; i<data_out->material_count; i++)
free(data_out->material_list[i]);
free(data_out->material_list);
free(data_out->camera);
}
void obj_copy_to_out_storage(obj_scene_data *data_out, obj_growable_scene_data *growable_data)
{
data_out->vertex_count = growable_data->vertex_list.item_count;
data_out->vertex_normal_count = growable_data->vertex_normal_list.item_count;
data_out->vertex_texture_count = growable_data->vertex_texture_list.item_count;
data_out->face_count = growable_data->face_list.item_count;
data_out->sphere_count = growable_data->sphere_list.item_count;
data_out->plane_count = growable_data->plane_list.item_count;
data_out->light_point_count = growable_data->light_point_list.item_count;
data_out->light_disc_count = growable_data->light_disc_list.item_count;
data_out->light_quad_count = growable_data->light_quad_list.item_count;
data_out->material_count = growable_data->material_list.item_count;
data_out->vertex_list = (obj_vector**)growable_data->vertex_list.items;
data_out->vertex_normal_list = (obj_vector**)growable_data->vertex_normal_list.items;
data_out->vertex_texture_list = (obj_vector**)growable_data->vertex_texture_list.items;
data_out->face_list = (obj_face**)growable_data->face_list.items;
data_out->sphere_list = (obj_sphere**)growable_data->sphere_list.items;
data_out->plane_list = (obj_plane**)growable_data->plane_list.items;
data_out->light_point_list = (obj_light_point**)growable_data->light_point_list.items;
data_out->light_disc_list = (obj_light_disc**)growable_data->light_disc_list.items;
data_out->light_quad_list = (obj_light_quad**)growable_data->light_quad_list.items;
data_out->object_list = (obj_object**)growable_data->object_list.items;
data_out->object_count = growable_data->object_list.item_count;
data_out->material_list = (obj_material**)growable_data->material_list.items;
data_out->camera = growable_data->camera;
}
int parse_obj_scene(obj_scene_data *data_out, char *filename)
{
obj_growable_scene_data growable_data;
obj_init_temp_storage(&growable_data);
if( obj_parse_obj_file(&growable_data, filename) == 0)
return 0;
//print_vector(NORMAL, "Max bounds are: ", &growable_data->extreme_dimensions[1]);
//print_vector(NORMAL, "Min bounds are: ", &growable_data->extreme_dimensions[0]);
obj_copy_to_out_storage(data_out, &growable_data);
obj_free_temp_storage(&growable_data);
return 1;
}

View File

@@ -0,0 +1,159 @@
#ifndef OBJ_PARSER_H
#define OBJ_PARSER_H
#include "list.h"
#define OBJ_FILENAME_LENGTH 500
#define MATERIAL_NAME_SIZE 255
#define OBJECT_NAME_SIZE 255
#define OBJ_LINE_SIZE 500
#define MAX_VERTEX_COUNT 4 //can only handle quads or triangles
typedef struct obj_face
{
int vertex_index[MAX_VERTEX_COUNT];
int normal_index[MAX_VERTEX_COUNT];
int texture_index[MAX_VERTEX_COUNT];
int vertex_count;
int material_index;
};
typedef struct obj_sphere
{
int pos_index;
int up_normal_index;
int equator_normal_index;
int texture_index[MAX_VERTEX_COUNT];
int material_index;
};
typedef struct obj_plane
{
int pos_index;
int normal_index;
int rotation_normal_index;
int texture_index[MAX_VERTEX_COUNT];
int material_index;
};
typedef struct obj_vector
{
double e[3];
};
typedef struct obj_material
{
char name[MATERIAL_NAME_SIZE];
char texture_filename[OBJ_FILENAME_LENGTH];
double amb[3];
double diff[3];
double spec[3];
double reflect;
double refract;
double trans;
double shiny;
double glossy;
double refract_index;
};
typedef struct obj_camera
{
int camera_pos_index;
int camera_look_point_index;
int camera_up_norm_index;
};
typedef struct obj_light_point
{
int pos_index;
int material_index;
};
typedef struct obj_light_disc
{
int pos_index;
int normal_index;
int material_index;
};
typedef struct obj_light_quad
{
int vertex_index[MAX_VERTEX_COUNT];
int material_index;
};
typedef struct obj_object
{
int vertex_offset;
int face_offset;
char name[OBJECT_NAME_SIZE];
};
typedef struct obj_growable_scene_data
{
// vector extreme_dimensions[2];
char scene_filename[OBJ_FILENAME_LENGTH];
char material_filename[OBJ_FILENAME_LENGTH];
list vertex_list;
list vertex_normal_list;
list vertex_texture_list;
list face_list;
list sphere_list;
list plane_list;
list light_point_list;
list light_quad_list;
list light_disc_list;
list material_list;
list object_list;
obj_camera *camera;
};
typedef struct obj_scene_data
{
obj_vector **vertex_list;
obj_vector **vertex_normal_list;
obj_vector **vertex_texture_list;
obj_face **face_list;
obj_sphere **sphere_list;
obj_plane **plane_list;
obj_light_point **light_point_list;
obj_light_quad **light_quad_list;
obj_light_disc **light_disc_list;
obj_material **material_list;
obj_object** object_list;
int object_count;
int vertex_count;
int vertex_normal_count;
int vertex_texture_count;
int face_count;
int sphere_count;
int plane_count;
int light_point_count;
int light_quad_count;
int light_disc_count;
int material_count;
obj_camera *camera;
};
int parse_obj_scene(obj_scene_data *data_out, char *filename);
void delete_obj_data(obj_scene_data *data_out);
#endif

View File

@@ -0,0 +1,24 @@
project "wavefrontObjLoader"
language "C++"
kind "ConsoleApp"
targetdir "../../bin"
includedirs {
".",
}
files {
"objTester.cpp",
"string_extra.cpp",
"string_extra.h",
"objLoader.cpp",
"objLoader.h",
"obj_parser.cpp",
"obj_parser.h",
"list.cpp",
"list.h"
}

View File

@@ -0,0 +1,16 @@
#include "string_extra.h"
#include <string.h>
char strequal(const char *s1, const char *s2)
{
if(strcmp(s1, s2) == 0)
return 1;
return 0;
}
char contains(const char *haystack, const char *needle)
{
if(strstr(haystack, needle) == NULL)
return 0;
return 1;
}

View File

@@ -0,0 +1,8 @@
#ifndef STRING_EXTRA_H
#define STRING_EXTRA_H
char strequal(const char *s1, const char *s2);
char contains(const char *haystack, const char *needle);
#endif

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