reorder files, in preparation for Bullet 3 -> Bullet 2 merge
This commit is contained in:
118
Demos3/GpuDemos/GpuDemo.cpp
Normal file
118
Demos3/GpuDemos/GpuDemo.cpp
Normal 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
73
Demos3/GpuDemos/GpuDemo.h
Normal 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
|
||||
|
||||
22
Demos3/GpuDemos/GpuDemoInternalData.h
Normal file
22
Demos3/GpuDemos/GpuDemoInternalData.h
Normal 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
|
||||
479
Demos3/GpuDemos/ParticleDemo.cpp
Normal file
479
Demos3/GpuDemos/ParticleDemo.cpp
Normal 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;
|
||||
49
Demos3/GpuDemos/ParticleDemo.h
Normal file
49
Demos3/GpuDemos/ParticleDemo.h
Normal 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
|
||||
149
Demos3/GpuDemos/ParticleKernels.cl
Normal file
149
Demos3/GpuDemos/ParticleKernels.cl
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
);
|
||||
351
Demos3/GpuDemos/broadphase/PairBench.cpp
Normal file
351
Demos3/GpuDemos/broadphase/PairBench.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
43
Demos3/GpuDemos/broadphase/PairBench.h
Normal file
43
Demos3/GpuDemos/broadphase/PairBench.h
Normal 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
|
||||
|
||||
346
Demos3/GpuDemos/gwenUserInterface.cpp
Normal file
346
Demos3/GpuDemos/gwenUserInterface.cpp
Normal 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;
|
||||
}
|
||||
38
Demos3/GpuDemos/gwenUserInterface.h
Normal file
38
Demos3/GpuDemos/gwenUserInterface.h
Normal 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
|
||||
|
||||
738
Demos3/GpuDemos/main_opengl3core.cpp
Normal file
738
Demos3/GpuDemos/main_opengl3core.cpp
Normal 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;
|
||||
}
|
||||
94
Demos3/GpuDemos/premake4.lua
Normal file
94
Demos3/GpuDemos/premake4.lua
Normal 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")
|
||||
44
Demos3/GpuDemos/rigidbody/Bullet2FileDemo.cpp
Normal file
44
Demos3/GpuDemos/rigidbody/Bullet2FileDemo.cpp
Normal 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);
|
||||
}
|
||||
32
Demos3/GpuDemos/rigidbody/Bullet2FileDemo.h
Normal file
32
Demos3/GpuDemos/rigidbody/Bullet2FileDemo.h
Normal 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
|
||||
|
||||
768
Demos3/GpuDemos/rigidbody/BulletDataExtractor.cpp
Normal file
768
Demos3/GpuDemos/rigidbody/BulletDataExtractor.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
53
Demos3/GpuDemos/rigidbody/BulletDataExtractor.h
Normal file
53
Demos3/GpuDemos/rigidbody/BulletDataExtractor.h
Normal 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
|
||||
757
Demos3/GpuDemos/rigidbody/ConcaveScene.cpp
Normal file
757
Demos3/GpuDemos/rigidbody/ConcaveScene.cpp
Normal 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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
101
Demos3/GpuDemos/rigidbody/ConcaveScene.h
Normal file
101
Demos3/GpuDemos/rigidbody/ConcaveScene.h
Normal 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
|
||||
254
Demos3/GpuDemos/rigidbody/GpuCompoundScene.cpp
Normal file
254
Demos3/GpuDemos/rigidbody/GpuCompoundScene.cpp
Normal 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);
|
||||
}
|
||||
50
Demos3/GpuDemos/rigidbody/GpuCompoundScene.h
Normal file
50
Demos3/GpuDemos/rigidbody/GpuCompoundScene.h
Normal 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
|
||||
176
Demos3/GpuDemos/rigidbody/GpuConvexScene.cpp
Normal file
176
Demos3/GpuDemos/rigidbody/GpuConvexScene.cpp
Normal 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);
|
||||
|
||||
}
|
||||
78
Demos3/GpuDemos/rigidbody/GpuConvexScene.h
Normal file
78
Demos3/GpuDemos/rigidbody/GpuConvexScene.h
Normal 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
|
||||
218
Demos3/GpuDemos/rigidbody/GpuRigidBodyDemo.cpp
Normal file
218
Demos3/GpuDemos/rigidbody/GpuRigidBodyDemo.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
45
Demos3/GpuDemos/rigidbody/GpuRigidBodyDemo.h
Normal file
45
Demos3/GpuDemos/rigidbody/GpuRigidBodyDemo.h
Normal 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
|
||||
|
||||
30
Demos3/GpuDemos/rigidbody/GpuRigidBodyDemoInternalData.h
Normal file
30
Demos3/GpuDemos/rigidbody/GpuRigidBodyDemoInternalData.h
Normal 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
|
||||
|
||||
205
Demos3/GpuDemos/rigidbody/GpuSphereScene.cpp
Normal file
205
Demos3/GpuDemos/rigidbody/GpuSphereScene.cpp
Normal 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);
|
||||
}
|
||||
27
Demos3/GpuDemos/rigidbody/GpuSphereScene.h
Normal file
27
Demos3/GpuDemos/rigidbody/GpuSphereScene.h
Normal 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
|
||||
547
Demos3/GpuGuiInitialize/main.cpp
Normal file
547
Demos3/GpuGuiInitialize/main.cpp
Normal 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;
|
||||
}
|
||||
84
Demos3/GpuGuiInitialize/premake4.lua
Normal file
84
Demos3/GpuGuiInitialize/premake4.lua
Normal 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
205
Demos3/Wavefront/list.cpp
Normal 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
29
Demos3/Wavefront/list.h
Normal 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
|
||||
46
Demos3/Wavefront/objLoader.cpp
Normal file
46
Demos3/Wavefront/objLoader.cpp
Normal 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;
|
||||
}
|
||||
52
Demos3/Wavefront/objLoader.h
Normal file
52
Demos3/Wavefront/objLoader.h
Normal 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
|
||||
167
Demos3/Wavefront/objTester.cpp
Normal file
167
Demos3/Wavefront/objTester.cpp
Normal 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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
591
Demos3/Wavefront/obj_parser.cpp
Normal file
591
Demos3/Wavefront/obj_parser.cpp
Normal 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;
|
||||
}
|
||||
|
||||
159
Demos3/Wavefront/obj_parser.h
Normal file
159
Demos3/Wavefront/obj_parser.h
Normal 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
|
||||
24
Demos3/Wavefront/premake4.lua
Normal file
24
Demos3/Wavefront/premake4.lua
Normal 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"
|
||||
}
|
||||
16
Demos3/Wavefront/string_extra.cpp
Normal file
16
Demos3/Wavefront/string_extra.cpp
Normal 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;
|
||||
}
|
||||
8
Demos3/Wavefront/string_extra.h
Normal file
8
Demos3/Wavefront/string_extra.h
Normal 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
|
||||
28
Demos3/donttouch/Bullet2GpuDemo.cpp
Normal file
28
Demos3/donttouch/Bullet2GpuDemo.cpp
Normal 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;
|
||||
}
|
||||
31
Demos3/donttouch/Bullet2GpuDemo.h
Normal file
31
Demos3/donttouch/Bullet2GpuDemo.h
Normal 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
|
||||
|
||||
611
Demos3/donttouch/GpuDemo.cpp
Normal file
611
Demos3/donttouch/GpuDemo.cpp
Normal 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
184
Demos3/donttouch/GpuDemo.h
Normal 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
|
||||
678
Demos3/donttouch/OpenGL3CoreRenderer.cpp
Normal file
678
Demos3/donttouch/OpenGL3CoreRenderer.cpp
Normal 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();
|
||||
}
|
||||
|
||||
26
Demos3/donttouch/OpenGL3CoreRenderer.h
Normal file
26
Demos3/donttouch/OpenGL3CoreRenderer.h
Normal 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
|
||||
|
||||
17
Demos3/donttouch/b3CpuDynamicsWorld.cpp
Normal file
17
Demos3/donttouch/b3CpuDynamicsWorld.cpp
Normal 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()
|
||||
{
|
||||
|
||||
}
|
||||
24
Demos3/donttouch/b3CpuDynamicsWorld.h
Normal file
24
Demos3/donttouch/b3CpuDynamicsWorld.h
Normal 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
|
||||
300
Demos3/donttouch/b3GpuDynamicsWorld.cpp
Normal file
300
Demos3/donttouch/b3GpuDynamicsWorld.cpp
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
109
Demos3/donttouch/b3GpuDynamicsWorld.h
Normal file
109
Demos3/donttouch/b3GpuDynamicsWorld.h
Normal 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
|
||||
Reference in New Issue
Block a user