* Adjustment: Update Bullet version to 3.24.

This commit is contained in:
Robert MacGregor 2022-06-27 10:01:08 -04:00
parent 35de012ee7
commit 4a3f31df2a
6148 changed files with 2112532 additions and 56873 deletions

View file

@ -0,0 +1,145 @@
#ifndef COMMON_MULTI_BODY_SETUP_H
#define COMMON_MULTI_BODY_SETUP_H
#include "../CommonInterfaces/CommonExampleInterface.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "../CommonInterfaces/CommonRenderInterface.h"
#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
#include "../CommonInterfaces/CommonWindowInterface.h"
#include "../CommonInterfaces/CommonCameraInterface.h"
#include "GpuDemoInternalData.h"
#include "Bullet3Common/b3Scalar.h"
#include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
struct CommonOpenCLBase : public CommonExampleInterface
{
struct GUIHelperInterface* m_guiHelper;
struct GpuDemoInternalData* m_clData;
CommonOpenCLBase(GUIHelperInterface* helper)
: m_guiHelper(helper),
m_clData(0)
{
m_clData = new GpuDemoInternalData();
}
virtual ~CommonOpenCLBase()
{
delete m_clData;
m_clData = 0;
}
virtual void stepSimulation(float deltaTime)
{
}
virtual void initCL(int preferredDeviceIndex, int preferredPlatformIndex)
{
// void* glCtx=0;
// void* glDC = 0;
int ciErrNum = 0;
cl_device_type deviceType = CL_DEVICE_TYPE_GPU;
//if (gAllowCpuOpenCL)
// deviceType = CL_DEVICE_TYPE_ALL;
// 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, &m_clData->m_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);
b3OpenCLDeviceInfo info;
b3OpenCLUtils::getDeviceInfo(m_clData->m_clDevice, &info);
m_clData->m_clDeviceName = info.m_deviceName;
m_clData->m_clInitialized = true;
}
}
virtual void exitCL()
{
if (m_clData && m_clData->m_clInitialized)
{
clReleaseCommandQueue(m_clData->m_clQueue);
clReleaseContext(m_clData->m_clContext);
m_clData->m_clInitialized = false;
}
}
virtual void renderScene()
{
if (m_guiHelper->getRenderInterface())
{
m_guiHelper->getRenderInterface()->renderScene();
}
}
virtual void physicsDebugDraw(int debugDrawFlags)
{
}
virtual bool keyboardCallback(int key, int state)
{
return false; //don't handle this key
}
virtual bool mouseMoveCallback(float x, float y)
{
return false;
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
if (!renderer)
{
b3Assert(0);
return false;
}
CommonWindowInterface* window = m_guiHelper->getAppInterface()->m_window;
if (state == 1)
{
if (button == 0 && (!window->isModifierKeyPressed(B3G_ALT) && !window->isModifierKeyPressed(B3G_CONTROL)))
{
/*btVector3 camPos;
renderer->getActiveCamera()->getCameraPosition(camPos);
btVector3 rayFrom = camPos;
btVector3 rayTo = getRayTo(int(x),int(y));
pickBody(rayFrom, rayTo);
*/
}
}
else
{
if (button == 0)
{
// removePickingConstraint();
//remove p2p
}
}
//printf("button=%d, state=%d\n",button,state);
return false;
}
};
#endif //COMMON_MULTI_BODY_SETUP_H

View file

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

View file

@ -0,0 +1,721 @@
//those header files need to be at the top, because of conflict __global and STL
#include "PairBench.h"
#include "Bullet3Common/b3Quaternion.h"
#include "Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.h"
#include "Bullet3OpenCL/BroadphaseCollision/b3GpuGridBroadphase.h"
#include "Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvhBroadphase.h"
#include "../Utils/b3Clock.h"
//#include "../GpuDemoInternalData.h"
#include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
#include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h"
#include "../OpenGLWindow/OpenGLInclude.h"
#include "../OpenGLWindow/ShapeData.h"
#include <string.h>
#include "pairsKernel.h"
extern int gPreferredOpenCLDeviceIndex;
extern int gPreferredOpenCLPlatformIndex;
#include "../CommonInterfaces/CommonExampleInterface.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "../CommonInterfaces/CommonRenderInterface.h"
#include "../CommonInterfaces/CommonCameraInterface.h"
#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
#include "../CommonInterfaces/CommonWindowInterface.h"
#include "../CommonOpenCL/CommonOpenCLBase.h"
#include "../OpenGLWindow/GLInstancingRenderer.h"
#include "../OpenGLWindow/GLInstanceRendererInternalData.h"
char* gPairBenchFileName = 0;
class PairBench : public CommonOpenCLBase
{
struct PairBenchInternalData* m_data;
public:
PairBench(GUIHelperInterface* helper);
virtual ~PairBench();
virtual void initPhysics();
virtual void exitPhysics();
void createBroadphase(int xdim, int ydim, int zdim);
void deleteBroadphase();
virtual void stepSimulation(float deltaTime);
virtual void renderScene();
virtual void resetCamera()
{
float dist = 10;
if (gPairBenchFileName)
{
dist = 830;
}
else
{
dist = 130;
}
float pitch = -33;
float yaw = 62;
float targetPos[4] = {15.5, 12.5, 15.5, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
};
//we use an offset, just for testing to make sure there is no assumption in the broadphase that 'index' starts at 0
#define TEST_INDEX_OFFSET 1024
extern bool useShadowMap;
float maxExtents = -1e30f;
int largeCount = 0;
float timeStepPos = 0.000166666;
float mAmplitude = 251.f;
int dimensions[3] = {10, 10, 10}; //initialized with x_dim/y_dim/z_dim
const char* axisNames[3] = {"# x-axis", "# y-axis", "# z-axis"};
extern bool gReset;
static int curUseLargeAabbOption = 0;
const char* useLargeAabbOptions[] =
{
"NoLargeAabb",
"UseLargeAabb",
};
struct BroadphaseEntry
{
const char* m_name;
b3GpuBroadphaseInterface::CreateFunc* m_createFunc;
};
static PairBench* sPairDemo = 0;
#define BP_COMBO_INDEX 123
static int curSelectedBroadphase = 0;
static BroadphaseEntry allBroadphases[] =
{
{"Gpu Grid", b3GpuGridBroadphase::CreateFunc},
{"Parallel Linear BVH", b3GpuParallelLinearBvhBroadphase::CreateFunc},
{"CPU Brute Force", b3GpuSapBroadphase::CreateFuncBruteForceCpu},
{"GPU Brute Force", b3GpuSapBroadphase::CreateFuncBruteForceGpu},
{"GPU 1-SAP Original", b3GpuSapBroadphase::CreateFuncOriginal},
{"GPU 1-SAP Barrier", b3GpuSapBroadphase::CreateFuncBarrier},
{"GPU 1-SAP LDS", b3GpuSapBroadphase::CreateFuncLocalMemory}};
struct PairBenchInternalData
{
b3GpuBroadphaseInterface* m_broadphaseGPU;
b3GpuBroadphaseInterface* m_validationBroadphase;
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)
{
}
int m_oldYposition;
};
PairBench::PairBench(GUIHelperInterface* helper)
: CommonOpenCLBase(helper)
{
m_data = new PairBenchInternalData;
m_data->m_validationBroadphase = 0;
}
PairBench::~PairBench()
{
delete m_data;
}
static inline float parseFloat(const char*& token)
{
token += strspn(token, " \t");
float f = (float)atof(token);
token += strcspn(token, " \t\r");
return f;
}
enum PairToggleButtons
{
MY_RESET = 1024,
};
#define PAIRS_CL_PROGRAM_PATH "Demos3/GpuDemos/broadphase/pairsKernel.cl"
void PairBench::initPhysics()
{
dimensions[0] = 10;
dimensions[1] = 10;
dimensions[2] = 10;
//m_guiHelper->getRenderInterface() = ci.m_guiHelper->getRenderInterface();
sPairDemo = this;
useShadowMap = false;
initCL(gPreferredOpenCLDeviceIndex, gPreferredOpenCLPlatformIndex);
if (m_clData->m_clContext)
{
cl_int err;
cl_program pairBenchProg = b3OpenCLUtils::compileCLProgramFromString(m_clData->m_clContext, m_clData->m_clDevice, pairsKernelsCL, &err, "", PAIRS_CL_PROGRAM_PATH);
int errNum = 0;
m_data->m_moveObjectsKernel = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext, m_clData->m_clDevice, pairsKernelsCL, "moveObjectsKernel", &errNum, pairBenchProg);
m_data->m_sineWaveKernel = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext, m_clData->m_clDevice, pairsKernelsCL, "sineWaveKernel", &errNum, pairBenchProg);
m_data->m_colorPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext, m_clData->m_clDevice, pairsKernelsCL, "colorPairsKernel2", &errNum, pairBenchProg);
m_data->m_updateAabbSimple = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext, m_clData->m_clDevice, pairsKernelsCL, "updateAabbSimple", &errNum, pairBenchProg);
//Method for validating the overlapping pairs requires that the
//reference broadphase does not maintain internal state aside from AABB data.
//That is, overwriting the AABB state in the broadphase using
// b3GpuBroadphaseInterface::getAllAabbsGPU(),
// b3GpuBroadphaseInterface::getSmallAabbIndicesGPU(), and
// b3GpuBroadphaseInterface::getLargeAabbIndicesGPU()
//and then calling b3GpuBroadphaseInterface::calculateOverlappingPairs() should
//always produce the same result regardless of the current state of the broadphase.
m_data->m_validationBroadphase = b3GpuParallelLinearBvhBroadphase::CreateFunc(m_clData->m_clContext, m_clData->m_clDevice, m_clData->m_clQueue);
}
createBroadphase(dimensions[0], dimensions[1], dimensions[2]);
}
void PairBench::createBroadphase(int arraySizeX, int arraySizeY, int arraySizeZ)
{
m_data->m_broadphaseGPU = (allBroadphases[curSelectedBroadphase].m_createFunc)(m_clData->m_clContext, m_clData->m_clDevice, m_clData->m_clQueue);
int strideInBytes = 9 * sizeof(float);
int numVertices = sizeof(cube_vertices) / strideInBytes;
int numIndices = sizeof(cube_vertices) / sizeof(int);
int shapeId = m_guiHelper->getRenderInterface()->registerShape(&cube_vertices[0], numVertices, cube_indices, numIndices);
int group = 1;
int mask = 1;
int index = TEST_INDEX_OFFSET;
if (gPairBenchFileName)
{
//char* fileName = "32006GPUAABBs.txt";
char relativeFileName[1024];
const char* prefix[] = {"./data/", "../data/", "../../data/", "../../../data/", "../../../../data/"};
int prefixIndex = -1;
{
int numPrefixes = sizeof(prefix) / sizeof(char*);
for (int i = 0; i < numPrefixes; i++)
{
FILE* f = 0;
sprintf(relativeFileName, "%s%s", prefix[i], gPairBenchFileName);
f = fopen(relativeFileName, "rb");
if (f)
{
fseek(f, 0L, SEEK_END);
int size = ftell(f);
rewind(f);
char* buf = (char*)malloc(size);
int actualReadBytes = 0;
while (actualReadBytes < size)
{
int left = size - actualReadBytes;
int chunk = 8192;
int numPlannedRead = left < chunk ? left : chunk;
actualReadBytes += fread(&buf[actualReadBytes], 1, numPlannedRead, f);
}
fclose(f);
char pattern[1024];
pattern[0] = 0x0a;
pattern[1] = 0;
size_t const patlen = strlen(pattern);
size_t patcnt = 0;
char* oriptr;
char* patloc;
for (oriptr = buf; (patloc = strstr(oriptr, pattern)); oriptr = patloc + patlen)
{
if (patloc)
{
*patloc = 0;
const char* token = oriptr;
b3Vector3 aabbMin;
b3Vector3 aabbMax;
aabbMin.x = parseFloat(token);
aabbMin.y = parseFloat(token);
aabbMin.z = parseFloat(token);
aabbMin.w = 0.f;
aabbMax.x = parseFloat(token);
aabbMax.y = parseFloat(token);
aabbMax.z = parseFloat(token);
aabbMax.w = 0.f;
aabbMin *= 0.1;
aabbMax *= 0.1;
b3Vector3 extents = aabbMax - aabbMin;
//printf("%s\n", oriptr);
b3Vector3 position = 0.5 * (aabbMax + aabbMin);
b3Quaternion orn(0, 0, 0, 1);
b3Vector4 scaling = b3MakeVector4(0.5 * extents.x, 0.5 * extents.y, 0.5 * extents.z, 1); //b3MakeVector4(1,1,1,1);
float l = extents.length();
if (l > 500)
{
b3Vector4 color = b3MakeVector4(0, 1, 0, 0.1);
int id;
id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId, position, orn, color, scaling);
m_data->m_broadphaseGPU->createLargeProxy(aabbMin, aabbMax, index, group, mask);
}
else
{
b3Vector4 color = b3MakeVector4(1, 0, 0, 1);
int id;
id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId, position, orn, color, scaling);
m_data->m_broadphaseGPU->createProxy(aabbMin, aabbMax, index, group, mask);
index++;
}
patcnt++;
}
}
prefixIndex = i;
break;
}
}
if (prefixIndex < 0)
{
b3Printf("Cannot find %s\n", gPairBenchFileName);
}
}
}
else
{
for (int i = 0; i < arraySizeX; i++)
{
for (int j = 0; j < arraySizeY; j++)
{
for (int k = 0; k < arraySizeZ; k++)
{
b3Vector3 position = b3MakeVector3(k * 3, i * 3, j * 3);
b3Quaternion orn(0, 0, 0, 1);
b3Vector4 color = b3MakeVector4(0, 1, 0, 1);
b3Vector4 scaling = b3MakeVector4(1, 1, 1, 1);
bool large = false;
if (curUseLargeAabbOption)
{
if (i == 0 && j == 0 && k == 0)
{
large = true;
scaling[0] = 1000;
scaling[1] = 1000;
scaling[2] = 1000;
}
}
/*if (j==0)
{
large=true;
scaling[1] = 10000;
}
if (k==0)
{
large=true;
scaling[2] = 10000;
}*/
int id;
id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId, position, orn, color, scaling);
b3Vector3 aabbMin = position - scaling;
b3Vector3 aabbMax = position + scaling;
if (large)
{
m_data->m_broadphaseGPU->createLargeProxy(aabbMin, aabbMax, index, group, mask);
}
else
{
m_data->m_broadphaseGPU->createProxy(aabbMin, aabbMax, index, group, mask);
}
index++;
}
}
}
}
m_guiHelper->getRenderInterface()->writeTransforms();
m_data->m_broadphaseGPU->writeAabbsToGpu();
}
void PairBench::deleteBroadphase()
{
delete m_data->m_broadphaseGPU;
m_data->m_broadphaseGPU = 0;
delete m_data->m_instancePosOrnColor;
m_data->m_instancePosOrnColor = 0;
delete m_data->m_bodyTimes;
m_data->m_bodyTimes = 0;
m_data->m_broadphaseGPU = 0;
m_guiHelper->getRenderInterface()->removeAllInstances();
}
void PairBench::exitPhysics()
{
//reset the state to 'on'
useShadowMap = true;
if (m_data->m_validationBroadphase)
{
delete m_data->m_validationBroadphase;
m_data->m_validationBroadphase = 0;
}
sPairDemo = 0;
exitCL();
}
void PairBench::renderScene()
{
m_guiHelper->getRenderInterface()->renderScene();
}
struct OverlappingPairSortPredicate
{
inline bool operator()(const b3Int4& a, const b3Int4& b) const
{
if (a.x != b.x) return (a.x < b.x);
if (a.y != b.y) return (a.y < b.y);
if (a.z != b.z) return (a.z < b.z);
return (a.w < b.w);
}
};
void PairBench::stepSimulation(float deltaTime)
{
//color all objects blue
GLInstanceRendererInternalData* internalData = m_guiHelper->getRenderInterface()->getInternalData();
if (internalData == 0)
return;
//bool animate=true;
int numObjects = 0;
{
B3_PROFILE("Num Objects");
numObjects = internalData->m_totalNumInstances;
}
b3Vector4* positions = 0;
if (numObjects)
{
B3_PROFILE("Sync");
GLuint vbo = internalData->m_vbo;
int arraySizeInBytes = numObjects * (3) * sizeof(b3Vector4);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// cl_bool blocking= CL_TRUE;
char* hostPtr = 0;
{
B3_PROFILE("glMapBufferRange");
hostPtr = (char*)glMapBufferRange(GL_ARRAY_BUFFER, internalData->m_maxShapeCapacityInBytes, 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 (!gPairBenchFileName)
{
if (1)
{
if (1)
{
b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_sineWaveKernel, "m_sineWaveKernel");
launcher.setBuffer(m_data->m_instancePosOrnColor->getBufferCL());
launcher.setBuffer(m_data->m_bodyTimes->getBufferCL());
launcher.setConst(timeStepPos);
launcher.setConst(mAmplitude);
launcher.setConst(numObjects);
launcher.launch1D(numObjects);
clFinish(m_clData->m_clQueue);
}
else
{
b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_moveObjectsKernel, "m_moveObjectsKernel");
launcher.setBuffer(m_data->m_instancePosOrnColor->getBufferCL());
launcher.setConst(numObjects);
launcher.launch1D(numObjects);
clFinish(m_clData->m_clQueue);
}
}
}
}
bool updateOnGpu = true;
if (1)
{
if (updateOnGpu)
{
B3_PROFILE("updateOnGpu");
b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_updateAabbSimple, "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);
}
else
{
B3_PROFILE("updateOnCpu");
if (!gPairBenchFileName)
{
// int allAabbs = m_data->m_broadphaseGPU->getAllAabbsCPU().size();
b3AlignedObjectArray<b3Vector4> posOrnColorsCpu;
if (m_data->m_instancePosOrnColor)
m_data->m_instancePosOrnColor->copyToHost(posOrnColorsCpu);
for (int nodeId = 0; nodeId < numObjects; nodeId++)
{
{
b3Vector3 position = posOrnColorsCpu[nodeId];
b3SapAabb orgAabb = m_data->m_broadphaseGPU->getAllAabbsCPU()[nodeId];
b3Vector3 halfExtents = 0.5f * (orgAabb.m_maxVec - orgAabb.m_minVec);
int orgNodeIndex = orgAabb.m_minIndices[3];
int orgBroadphaseIndex = orgAabb.m_signedMaxIndices[3];
m_data->m_broadphaseGPU->getAllAabbsCPU()[nodeId].m_minVec = position - halfExtents;
m_data->m_broadphaseGPU->getAllAabbsCPU()[nodeId].m_minIndices[3] = orgNodeIndex;
m_data->m_broadphaseGPU->getAllAabbsCPU()[nodeId].m_maxVec = position + halfExtents;
m_data->m_broadphaseGPU->getAllAabbsCPU()[nodeId].m_signedMaxIndices[3] = orgBroadphaseIndex;
}
}
m_data->m_broadphaseGPU->writeAabbsToGpu();
}
}
}
int prealloc = 3 * 1024 * 1024;
int maxOverlap = b3Min(prealloc, 16 * numObjects);
unsigned long dt = 0;
if (numObjects)
{
b3Clock cl;
dt = cl.getTimeMicroseconds();
B3_PROFILE("calculateOverlappingPairs");
//int sz = sizeof(b3Int4)*64*numObjects;
m_data->m_broadphaseGPU->calculateOverlappingPairs(maxOverlap);
int numPairs;
numPairs = m_data->m_broadphaseGPU->getNumOverlap();
//printf("numPairs = %d\n", numPairs);
dt = cl.getTimeMicroseconds() - dt;
}
const bool VALIDATE_BROADPHASE = false; //Check that overlapping pairs of 2 broadphases are the same
if (numObjects && VALIDATE_BROADPHASE)
{
B3_PROFILE("validate broadphases");
{
B3_PROFILE("calculateOverlappingPairs m_validationBroadphase");
//m_data->m_validationBroadphase->getAllAabbsCPU() = m_data->m_broadphaseGPU->getAllAabbsCPU();
m_data->m_validationBroadphase->getAllAabbsGPU().copyFromOpenCLArray(m_data->m_broadphaseGPU->getAllAabbsGPU());
m_data->m_validationBroadphase->getSmallAabbIndicesGPU().copyFromOpenCLArray(m_data->m_broadphaseGPU->getSmallAabbIndicesGPU());
m_data->m_validationBroadphase->getLargeAabbIndicesGPU().copyFromOpenCLArray(m_data->m_broadphaseGPU->getLargeAabbIndicesGPU());
m_data->m_validationBroadphase->calculateOverlappingPairs(maxOverlap);
}
static b3AlignedObjectArray<b3Int4> overlappingPairs;
static b3AlignedObjectArray<b3Int4> overlappingPairsReference;
m_data->m_broadphaseGPU->getOverlappingPairsGPU().copyToHost(overlappingPairs);
m_data->m_validationBroadphase->getOverlappingPairsGPU().copyToHost(overlappingPairsReference);
//Reorder pairs so that (pair.x < pair.y) is always true
{
B3_PROFILE("reorder pairs");
for (int i = 0; i < overlappingPairs.size(); ++i)
{
b3Int4 pair = overlappingPairs[i];
if (pair.x > pair.y)
{
b3Swap(pair.x, pair.y);
b3Swap(pair.z, pair.w);
overlappingPairs[i] = pair;
}
}
for (int i = 0; i < overlappingPairsReference.size(); ++i)
{
b3Int4 pair = overlappingPairsReference[i];
if (pair.x > pair.y)
{
b3Swap(pair.x, pair.y);
b3Swap(pair.z, pair.w);
overlappingPairsReference[i] = pair;
}
}
}
//
{
B3_PROFILE("Sort overlapping pairs from most to least significant bit");
overlappingPairs.quickSort(OverlappingPairSortPredicate());
overlappingPairsReference.quickSort(OverlappingPairSortPredicate());
}
//Compare
{
B3_PROFILE("compare pairs");
int numPairs = overlappingPairs.size();
int numPairsReference = overlappingPairsReference.size();
bool success = true;
if (numPairs == numPairsReference)
{
for (int i = 0; i < numPairsReference; ++i)
{
const b3Int4& pairA = overlappingPairs[i];
const b3Int4& pairB = overlappingPairsReference[i];
if (pairA.x != pairB.x || pairA.y != pairB.y || pairA.z != pairB.z || pairA.w != pairB.w)
{
b3Error("Error: one or more overlappingPairs differs from reference.\n");
success = false;
break;
}
}
}
else
{
b3Error("Error: numPairs %d != numPairsReference %d \n", numPairs, numPairsReference);
success = false;
}
printf("Broadphase validation: %d \n", success);
}
}
/*
if (m_data->m_gui)
{
B3_PROFILE("update Gui");
int allAabbs = m_data->m_broadphaseGPU->getAllAabbsCPU().size();
int numOverlap = m_data->m_broadphaseGPU->getNumOverlap();
float time = dt/1000.f;
//printf("time = %f\n", time);
char msg[1024];
sprintf(msg,"#objects = %d, #overlapping pairs = %d, time = %f ms", allAabbs,numOverlap,time );
//printf("msg=%s\n",msg);
m_data->m_gui->setStatusBarMessage(msg,true);
}
*/
if (numObjects)
{
B3_PROFILE("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, "m_colorPairsKernel");
launcher.setBuffer(m_data->m_instancePosOrnColor->getBufferCL());
launcher.setConst(numObjects);
launcher.setBuffer(pairBuf);
int indexOffset = TEST_INDEX_OFFSET;
launcher.setConst(indexOffset);
launcher.setConst(numPairs);
launcher.launch1D(numPairs);
clFinish(m_clData->m_clQueue);
}
}
if (numObjects)
{
m_data->m_instancePosOrnColor->copyToHostPointer(positions, 3 * numObjects, 0);
}
glUnmapBuffer(GL_ARRAY_BUFFER);
err = glGetError();
assert(err == GL_NO_ERROR);
}
}
class CommonExampleInterface* PairBenchOpenCLCreateFunc(struct CommonExampleOptions& options)
{
return new PairBench(options.m_guiHelper);
}

View file

@ -0,0 +1,6 @@
#ifndef PAIR_BENCH_H
#define PAIR_BENCH_H
class CommonExampleInterface* PairBenchOpenCLCreateFunc(struct CommonExampleOptions& options);
#endif

View file

@ -0,0 +1,79 @@
__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 colorPairsKernel2(__global float4* posOrnColors, int numObjects, __global const int4* pairs, int indexOffset, int numPairs)
{
int iPairId = get_global_id(0);
if (iPairId>=numPairs)
return;
__global float4* colors = &posOrnColors[numObjects*2];
int iObjectA = pairs[iPairId].x-indexOffset;
int iObjectB = pairs[iPairId].y-indexOffset;
colors[iObjectA] = (float4)(1,0,0,1);
colors[iObjectB] = (float4)(1,0,0,1);
}
__kernel void
sineWaveKernel( __global float4* posOrnColors, __global float* pBodyTimes,float timeStepPos, float mAmplitude,const int numNodes)
{
int nodeID = get_global_id(0);
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 )
{
b3AABBCL orgAabbMin = pAABB[nodeId*2];
b3AABBCL orgAabbMax = pAABB[nodeId*2+1];
int orgNodeId = orgAabbMin.uw;
int orgBroadphaseIndex = orgAabbMax.uw;
float4 position = posOrnColors[nodeId];
float4 argAabbMinVec = (float4)(orgAabbMin.fx,orgAabbMin.fy,orgAabbMin.fz,0.f);
float4 argAabbMaxVec = (float4)(orgAabbMax.fx,orgAabbMax.fy,orgAabbMax.fz,0.f);
float4 halfExtents = 0.5f*(argAabbMaxVec-argAabbMinVec);
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 = orgNodeId;
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 = orgBroadphaseIndex;
}
}

View file

@ -0,0 +1,76 @@
//this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project
static const char* pairsKernelsCL =
"__kernel void moveObjectsKernel(__global float4* posOrnColors, int numObjects)\n"
"{\n"
" int iGID = get_global_id(0);\n"
" if (iGID>=numObjects)\n"
" return;\n"
" __global float4* positions = &posOrnColors[0];\n"
" if (iGID<0.5*numObjects)\n"
" {\n"
" positions[iGID].y +=0.01f;\n"
" }\n"
" __global float4* colors = &posOrnColors[numObjects*2];\n"
" colors[iGID] = (float4)(0,0,1,1);\n"
"}\n"
"__kernel void colorPairsKernel2(__global float4* posOrnColors, int numObjects, __global const int4* pairs, int indexOffset, int numPairs)\n"
"{\n"
" int iPairId = get_global_id(0);\n"
" if (iPairId>=numPairs)\n"
" return;\n"
" __global float4* colors = &posOrnColors[numObjects*2];\n"
" int iObjectA = pairs[iPairId].x-indexOffset;\n"
" int iObjectB = pairs[iPairId].y-indexOffset;\n"
" colors[iObjectA] = (float4)(1,0,0,1);\n"
" colors[iObjectB] = (float4)(1,0,0,1);\n"
"}\n"
"__kernel void \n"
" sineWaveKernel( __global float4* posOrnColors, __global float* pBodyTimes,float timeStepPos, float mAmplitude,const int numNodes)\n"
"{\n"
" int nodeID = get_global_id(0);\n"
" if( nodeID < numNodes )\n"
" {\n"
" pBodyTimes[nodeID] += timeStepPos;\n"
" float4 position = posOrnColors[nodeID];\n"
" position.x = native_cos(pBodyTimes[nodeID]*2.17f)*mAmplitude + native_sin(pBodyTimes[nodeID])*mAmplitude*0.5f;\n"
" position.y = native_cos(pBodyTimes[nodeID]*1.38f)*mAmplitude + native_sin(pBodyTimes[nodeID]*mAmplitude);\n"
" position.z = native_cos(pBodyTimes[nodeID]*2.17f)*mAmplitude + native_sin(pBodyTimes[nodeID]*0.777f)*mAmplitude;\n"
" \n"
" posOrnColors[nodeID] = position;\n"
" __global float4* colors = &posOrnColors[numNodes*2];\n"
" colors[nodeID] = (float4)(0,0,1,1);\n"
" }\n"
"}\n"
"typedef struct \n"
"{\n"
" float fx;\n"
" float fy;\n"
" float fz;\n"
" int uw;\n"
"} b3AABBCL;\n"
"__kernel void updateAabbSimple( __global float4* posOrnColors, const int numNodes, __global b3AABBCL* pAABB)\n"
"{\n"
" int nodeId = get_global_id(0);\n"
" if( nodeId < numNodes )\n"
" {\n"
" \n"
" b3AABBCL orgAabbMin = pAABB[nodeId*2];\n"
" b3AABBCL orgAabbMax = pAABB[nodeId*2+1];\n"
" int orgNodeId = orgAabbMin.uw;\n"
" int orgBroadphaseIndex = orgAabbMax.uw;\n"
" \n"
" float4 position = posOrnColors[nodeId];\n"
" float4 argAabbMinVec = (float4)(orgAabbMin.fx,orgAabbMin.fy,orgAabbMin.fz,0.f);\n"
" float4 argAabbMaxVec = (float4)(orgAabbMax.fx,orgAabbMax.fy,orgAabbMax.fz,0.f);\n"
" float4 halfExtents = 0.5f*(argAabbMaxVec-argAabbMinVec);\n"
" \n"
" pAABB[nodeId*2].fx = position.x-halfExtents.x;\n"
" pAABB[nodeId*2].fy = position.y-halfExtents.y;\n"
" pAABB[nodeId*2].fz = position.z-halfExtents.z;\n"
" pAABB[nodeId*2].uw = orgNodeId;\n"
" pAABB[nodeId*2+1].fx = position.x+halfExtents.x;\n"
" pAABB[nodeId*2+1].fy = position.y+halfExtents.y;\n"
" pAABB[nodeId*2+1].fz = position.z+halfExtents.z;\n"
" pAABB[nodeId*2+1].uw = orgBroadphaseIndex; \n"
" }\n"
"}\n";

View file

@ -0,0 +1,691 @@
#include "ConcaveScene.h"
#include "GpuRigidBodyDemo.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 "Bullet3Collision/NarrowPhaseCollision/b3Config.h"
#include "GpuRigidBodyDemoInternalData.h"
#include "../../Wavefront/tiny_obj_loader.h"
#include "Bullet3Common/b3Transform.h"
#include "Bullet3Collision/NarrowPhaseCollision/b3ConvexUtility.h"
#include "Bullet3AppSupport/gwenUserInterface.h"
#include "OpenGLWindow/GLInstanceGraphicsShape.h"
#define CONCAVE_GAPX 14
#define CONCAVE_GAPY 5
#define CONCAVE_GAPZ 14
GLInstanceGraphicsShape* createGraphicsShapeFromWavefrontObj(std::vector<tinyobj::shape_t>& shapes)
{
b3AlignedObjectArray<GLInstanceVertex>* vertices = new b3AlignedObjectArray<GLInstanceVertex>;
{
// int numVertices = obj->vertexCount;
// int numIndices = 0;
b3AlignedObjectArray<int>* indicesPtr = new b3AlignedObjectArray<int>;
for (int s = 0; s < shapes.size(); s++)
{
tinyobj::shape_t& shape = shapes[s];
int faceCount = shape.mesh.indices.size();
for (int f = 0; f < faceCount; f += 3)
{
//b3Vector3 normal(face.m_plane[0],face.m_plane[1],face.m_plane[2]);
if (1)
{
b3Vector3 normal = b3MakeVector3(0, 1, 0);
int vtxBaseIndex = vertices->size();
indicesPtr->push_back(vtxBaseIndex);
indicesPtr->push_back(vtxBaseIndex + 1);
indicesPtr->push_back(vtxBaseIndex + 2);
GLInstanceVertex vtx0;
vtx0.xyzw[0] = shape.mesh.positions[shape.mesh.indices[f] * 3 + 0];
vtx0.xyzw[1] = shape.mesh.positions[shape.mesh.indices[f] * 3 + 1];
vtx0.xyzw[2] = shape.mesh.positions[shape.mesh.indices[f] * 3 + 2];
vtx0.xyzw[3] = 0.f;
vtx0.uv[0] = 0.5f; //shape.mesh.positions[shape.mesh.indices[f]*3+2];?
vtx0.uv[1] = 0.5f;
GLInstanceVertex vtx1;
vtx1.xyzw[0] = shape.mesh.positions[shape.mesh.indices[f + 1] * 3 + 0];
vtx1.xyzw[1] = shape.mesh.positions[shape.mesh.indices[f + 1] * 3 + 1];
vtx1.xyzw[2] = shape.mesh.positions[shape.mesh.indices[f + 1] * 3 + 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] = shape.mesh.positions[shape.mesh.indices[f + 2] * 3 + 0];
vtx2.xyzw[1] = shape.mesh.positions[shape.mesh.indices[f + 2] * 3 + 1];
vtx2.xyzw[2] = shape.mesh.positions[shape.mesh.indices[f + 2] * 3 + 2];
vtx2.xyzw[3] = 0.f;
vtx2.uv[0] = 0.5f;
vtx2.uv[1] = 0.5f;
b3Vector3 v0 = b3MakeVector3(vtx0.xyzw[0], vtx0.xyzw[1], vtx0.xyzw[2]);
b3Vector3 v1 = b3MakeVector3(vtx1.xyzw[0], vtx1.xyzw[1], vtx1.xyzw[2]);
b3Vector3 v2 = b3MakeVector3(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);
}
}
}
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)
{
char relativeFileName[1024];
const char* prefix[] = {"./data/", "../data/", "../../data/", "../../../data/", "../../../../data/"};
int prefixIndex = -1;
{
int numPrefixes = sizeof(prefix) / sizeof(char*);
for (int i = 0; i < numPrefixes; i++)
{
FILE* f = 0;
sprintf(relativeFileName, "%s%s", prefix[i], fileName);
f = fopen(relativeFileName, "r");
if (f)
{
fclose(f);
prefixIndex = i;
break;
}
}
}
if (prefixIndex < 0)
return;
int index = 10;
{
std::vector<tinyobj::shape_t> shapes;
std::string err = tinyobj::LoadObj(shapes, relativeFileName, prefix[prefixIndex]);
GLInstanceGraphicsShape* shape = createGraphicsShapeFromWavefrontObj(shapes);
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 = b3MakeVector3(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, b3MakeVector3(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 = b3MakeVector4(0.3, 0.3, 1, 1.f); //0.5);//1.f
{
float mass = 0.f;
b3Vector3 position = b3MakeVector3(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 shape->m_indices;
delete shape->m_vertices;
delete shape;
}
}
}
void ConcaveScene::setupScene(const ConstructionInfo& ci)
{
if (1)
{
//char* fileName = "slopedPlane100.obj";
//char* fileName = "plane100.obj";
// char* fileName = "plane100.obj";
//char* fileName = "teddy.obj";//"plane.obj";
// char* fileName = "sponza_closed.obj";//"plane.obj";
//char* fileName = "leoTest1.obj";
const char* fileName = "samurai_monastry.obj";
// char* fileName = "teddy2_VHACD_CHs.obj";
b3Vector3 shift1 = b3MakeVector3(0, 0, 0); //0,230,80);//150,-100,-120);
b3Vector4 scaling = b3MakeVector4(10, 10, 10, 1);
// createConcaveMesh(ci,"plane100.obj",shift1,scaling);
//createConcaveMesh(ci,"plane100.obj",shift,scaling);
// b3Vector3 shift2(0,0,0);//0,230,80);//150,-100,-120);
// createConcaveMesh(ci,"teddy.obj",shift2,scaling);
// b3Vector3 shift3(130,-150,-75);//0,230,80);//150,-100,-120);
// createConcaveMesh(ci,"leoTest1.obj",shift3,scaling);
createConcaveMesh(ci, fileName, shift1, 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 = b3MakeVector4(400, 1., 400, 1);
int colIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0], strideInBytes, numVertices, scaling);
b3Vector3 position = b3MakeVector3(0, -2, 0);
b3Quaternion orn(0, 0, 0, 1);
b3Vector4 color = b3MakeVector4(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(355);
char msg[1024];
int numInstances = m_data->m_rigidBodyPipeline->getNumBodies();
sprintf(msg, "Num objects = %d", numInstances);
if (ci.m_gui)
ci.m_gui->setStatusBarMessage(msg, true);
}
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] =
{
b3MakeVector4(1, 1, 1, 1),
b3MakeVector4(1, 1, 0.3, 1),
b3MakeVector4(0.3, 1, 1, 1),
b3MakeVector4(0.3, 0.3, 1, 1),
};
b3ConvexUtility* utilPtr = new b3ConvexUtility();
b3Vector4 scaling = b3MakeVector4(1, 1, 1, 1);
{
b3AlignedObjectArray<b3Vector3> verts;
unsigned char* vts = (unsigned char*)cube_vertices;
for (int i = 0; i < numVertices; i++)
{
float* vertex = (float*)&vts[i * strideInBytes];
verts.push_back(b3MakeVector3(vertex[0] * scaling[0], vertex[1] * scaling[1], vertex[2] * scaling[2]));
}
bool merge = true;
if (numVertices)
{
utilPtr->initializePolyhedralFeatures(&verts[0], verts.size(), merge);
}
}
// int colIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
int colIndex = -1;
if (ci.m_useInstancedCollisionShapes)
colIndex = m_data->m_np->registerConvexHullShape(utilPtr);
for (int i = 0; i < ci.arraySizeX; i++)
{
for (int j = 0; j < ci.arraySizeY; j++)
{
for (int k = 0; k < ci.arraySizeZ; k++)
{
if (!ci.m_useInstancedCollisionShapes)
colIndex = m_data->m_np->registerConvexHullShape(utilPtr);
float mass = 1;
//b3Vector3 position(-2*ci.gapX+i*ci.gapX,25+j*ci.gapY,-2*ci.gapZ+k*ci.gapZ);
b3Vector3 position = b3MakeVector3(-(ci.arraySizeX / 2) * CONCAVE_GAPX + i * CONCAVE_GAPX,
23 + 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)
{
const char* fileName = "teddy2_VHACD_CHs.obj";
//char* fileName = "cube_offset.obj";
b3Vector3 shift = b3MakeVector3(0, 0, 0); //0,230,80);//150,-100,-120);
b3Vector4 scaling = b3MakeVector4(1, 1, 1, 1);
const char* prefix[] = {"./data/", "../data/", "../../data/", "../../../data/", "../../../../data/"};
int prefixIndex = -1;
char relativeFileName[1024];
{
int numPrefixes = sizeof(prefix) / sizeof(char*);
for (int i = 0; i < numPrefixes; i++)
{
sprintf(relativeFileName, "%s%s", prefix[i], fileName);
FILE* f = 0;
f = fopen(relativeFileName, "r");
if (f)
{
prefixIndex = i;
fclose(f);
break;
}
}
}
if (prefixIndex < 0)
return;
std::vector<tinyobj::shape_t> shapes;
std::string err = tinyobj::LoadObj(shapes, relativeFileName, prefix[prefixIndex]);
if (shapes.size() > 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 = shapes.size();
for (int i = 0; i < numChildShapes; i++)
// int i=4;
{
tinyobj::shape_t& shape = shapes[i];
int numVertices = shape.mesh.positions.size() / 3;
int numFaces = shape.mesh.indices.size() / 3;
//for now, only support polyhedral child shapes
b3GpuChildShape child;
b3Vector3 pos = b3MakeVector3(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++)
{
for (int i = 0; i < 3; i++)
{
indexArray.push_back(baseIndex + shape.mesh.indices[f * 3 + i]);
}
}
b3Vector3 center = b3MakeVector3(0, 0, 0);
b3AlignedObjectArray<GLInstanceVertex> tmpVertices;
//add transformed graphics vertices and indices
b3Vector3 myScaling = b3MakeVector3(50, 50, 50); //300,300,300);
for (int v = 0; v < numVertices; v++)
{
GLInstanceVertex vert;
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] = shape.mesh.positions[v * 3 + 0] * myScaling[0];
vertPos[1] = shape.mesh.positions[v * 3 + 1] * myScaling[1];
vertPos[2] = shape.mesh.positions[v * 3 + 2] * myScaling[2];
vertPos[3] = 0.f;
center += vertPos;
}
center /= numVertices;
for (int v = 0; v < numVertices; v++)
{
GLInstanceVertex vert;
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] = shape.mesh.positions[v * 3 + 0] * myScaling[0];
vertPos[1] = shape.mesh.positions[v * 3 + 1] * myScaling[1];
vertPos[2] = shape.mesh.positions[v * 3 + 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] =
{
b3MakeVector4(1, 0, 0, 1),
b3MakeVector4(0, 1, 0, 1),
b3MakeVector4(0, 0, 1, 1),
b3MakeVector4(0, 1, 1, 1),
};
int curColor = 0;
for (int i = 0; i < 1; i++) //ci.arraySizeX;i++)
{
for (int j = 0; j < 4; j++)
{
// for (int k=0;k<ci.arraySizeZ;k++)
int k = 0;
{
float mass = 1; //j==0? 0.f : 1.f;
//b3Vector3 position(i*10*ci.gapX,j*ci.gapY,k*10*ci.gapZ);
b3Vector3 position = b3MakeVector3(i * 10 * ci.gapX, 10 + j * 10 * ci.gapY, k * 10 * ci.gapZ);
// b3Quaternion orn(0,0,0,1);
b3Quaternion orn(b3MakeVector3(0, 0, 1), 1.8);
b3Vector4 color = colors[curColor];
curColor++;
curColor &= 3;
b3Vector4 scaling = b3MakeVector4(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 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] = {
b3MakeVector3(0, -2, 0),
b3MakeVector3(0, 0, 0),
b3MakeVector3(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 = b3MakeVector3(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] =
{
b3MakeVector4(1, 0, 0, 1),
b3MakeVector4(0, 1, 0, 1),
b3MakeVector4(0, 0, 1, 1),
b3MakeVector4(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 = b3MakeVector3((-ci.arraySizeX / 2 + i) * ci.gapX, 50 + j * ci.gapY, (-ci.arraySizeZ / 2 + k) * ci.gapZ);
//b3Quaternion orn(0,0,0,1);
b3Quaternion orn(b3MakeVector3(1, 0, 0), 0.7);
b3Vector4 color = colors[curColor];
curColor++;
curColor &= 3;
b3Vector4 scaling = b3MakeVector4(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] =
{
b3MakeVector4(1, 0, 0, 1),
b3MakeVector4(0, 1, 0, 1),
b3MakeVector4(0, 1, 1, 1),
b3MakeVector4(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 = b3MakeVector3(-(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 = b3MakeVector4(radius, radius, radius, 1);
int id = ci.m_instancingRenderer->registerGraphicsInstance(prevGraphicsShapeIndex, position, orn, color, scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(mass, position, orn, colIndex, index, false);
index++;
}
}
}
}

View file

@ -0,0 +1,90 @@
#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 "BoxTrimesh";
}
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 "SphereTrimesh";
}
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 "CompoundConcave";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new ConcaveCompoundScene;
return demo;
}
virtual void setupScene(const ConstructionInfo& ci);
virtual void createDynamicObjects(const ConstructionInfo& ci);
};
class ConcaveCompound2Scene : public ConcaveCompoundScene
{
public:
ConcaveCompound2Scene() {}
virtual ~ConcaveCompound2Scene() {}
virtual const char* getName()
{
return "GRBConcave2Compound";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new ConcaveCompound2Scene;
return demo;
}
virtual void createDynamicObjects(const ConstructionInfo& ci);
};
#endif //CONCAVE_SCENE_H

View file

@ -0,0 +1,246 @@
#include "GpuCompoundScene.h"
#include "GpuRigidBodyDemo.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 "Bullet3Collision/NarrowPhaseCollision/b3Config.h"
#include "GpuRigidBodyDemoInternalData.h"
#include "Bullet3Common/b3Transform.h"
#include "OpenGLWindow/GLInstanceGraphicsShape.h"
#define NUM_COMPOUND_CHILDREN_X 4
#define NUM_COMPOUND_CHILDREN_Y 4
#define NUM_COMPOUND_CHILDREN_Z 4
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;
for (int x = 0; x < NUM_COMPOUND_CHILDREN_X; x++)
for (int y = 0; y < NUM_COMPOUND_CHILDREN_Y; y++)
for (int z = 0; z < NUM_COMPOUND_CHILDREN_Z; z++)
{
int blax = x != 0 ? 1 : 0;
int blay = y != 0 ? 1 : 0;
int blaz = z != 0 ? 1 : 0;
int bla = blax + blay + blaz;
if (bla != 1)
continue;
//for now, only support polyhedral child shapes
b3GpuChildShape child;
child.m_shapeIndex = childColIndex;
b3Vector3 pos = b3MakeVector3((x - NUM_COMPOUND_CHILDREN_X / 2.f) * 2, (y - NUM_COMPOUND_CHILDREN_X / 2.f) * 2, (z - NUM_COMPOUND_CHILDREN_X / 2.f) * 2); //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 = b3MakeVector3(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] =
{
b3MakeVector4(1, 0, 0, 1),
b3MakeVector4(0, 1, 0, 1),
b3MakeVector4(0, 0, 1, 1),
b3MakeVector4(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 = b3MakeVector3((i - ci.arraySizeX / 2.) * ci.gapX, 35 + j * 3 * ci.gapY, (k - ci.arraySizeZ / 2.f) * ci.gapZ);
//b3Quaternion orn(0,0,0,1);
b3Quaternion orn(b3MakeVector3(1, 0, 0), 0.7);
b3Vector4 color = colors[curColor];
curColor++;
curColor &= 3;
b3Vector4 scaling = b3MakeVector4(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(320);
}
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] =
{
b3MakeVector4(1, 0, 0, 1),
b3MakeVector4(0, 1, 0, 1),
b3MakeVector4(0, 1, 1, 1),
b3MakeVector4(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 = b3MakeVector3(0, -41, 0);
b3Quaternion orn(0, 0, 0, 1);
b3Vector4 color = colors[curColor];
curColor++;
curColor &= 3;
b3Vector4 scaling = b3MakeVector4(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 = b3MakeVector3(0, 1, 0);
float constant = 0.f;
int strideInBytes = 9 * sizeof(float);
int numVertices = sizeof(cube_vertices) / strideInBytes;
int numIndices = sizeof(cube_indices) / sizeof(int);
b3Vector4 scaling = b3MakeVector4(400, 1., 400, 1);
//int colIndex = m_data->m_np->registerPlaneShape(normal,constant);//>registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
int colIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0], strideInBytes, numVertices, scaling);
b3Vector3 position = b3MakeVector3(0, 0, 0);
b3Quaternion orn(0, 0, 0, 1);
// b3Quaternion orn(b3Vector3(1,0,0),0.3);
b3Vector4 color = b3MakeVector4(0, 0, 1, 1);
int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0], numVertices, cube_indices, numIndices);
int id = ci.m_instancingRenderer->registerGraphicsInstance(shapeId, position, orn, color, scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(0.f, position, orn, colIndex, index, false);
}

View file

@ -0,0 +1,45 @@
#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 "CompoundOnSphere";
}
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 "CompoundOnPlane";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new GpuCompoundPlaneScene;
return demo;
}
virtual void createStaticEnvironment(const ConstructionInfo& ci);
};
#endif //GPU_COMPOUND_SCENE_H

View file

@ -0,0 +1,596 @@
#include "GpuConvexScene.h"
#include "GpuRigidBodyDemo.h"
#include "../OpenGLWindow/ShapeData.h"
#include "../OpenGLWindow/GLInstancingRenderer.h"
#include "Bullet3Common/b3Quaternion.h"
#include "../CommonInterfaces/CommonWindowInterface.h"
#include "Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.h"
#include "../CommonOpenCL/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 "Bullet3Collision/NarrowPhaseCollision/b3Config.h"
#include "GpuRigidBodyDemoInternalData.h"
#include "Bullet3Dynamics/ConstraintSolver/b3Point2PointConstraint.h"
#include "../OpenGLWindow/GLPrimitiveRenderer.h"
#include "Bullet3OpenCL/Raycast/b3GpuRaycast.h"
#include "Bullet3Collision/NarrowPhaseCollision/b3ConvexUtility.h"
#include "Bullet3Dynamics/ConstraintSolver/b3FixedConstraint.h"
#include "../OpenGLWindow/GLRenderToTexture.h"
static bool gUseInstancedCollisionShapes = true;
extern int gGpuArraySizeX;
extern int gGpuArraySizeY;
extern int gGpuArraySizeZ;
#include "GpuRigidBodyDemo.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "Bullet3Collision/NarrowPhaseCollision/b3RaycastInfo.h"
class GpuConvexScene : public GpuRigidBodyDemo
{
protected:
class b3GpuRaycast* m_raycaster;
public:
GpuConvexScene(GUIHelperInterface* helper)
: GpuRigidBodyDemo(helper), m_raycaster(0)
{
}
virtual ~GpuConvexScene() {}
virtual const char* getName()
{
return "Tetrahedra";
}
virtual void setupScene();
virtual void destroyScene();
virtual int createDynamicsObjects();
virtual int createDynamicsObjects2(const float* vertices, int numVertices, const int* indices, int numIndices);
virtual void createStaticEnvironment();
};
class GpuConvexPlaneScene : public GpuConvexScene
{
public:
GpuConvexPlaneScene(GUIHelperInterface* helper)
: GpuConvexScene(helper) {}
virtual ~GpuConvexPlaneScene() {}
virtual const char* getName()
{
return "ConvexOnPlane";
}
virtual void createStaticEnvironment();
};
class GpuBoxPlaneScene : public GpuConvexPlaneScene
{
public:
GpuBoxPlaneScene(GUIHelperInterface* helper) : GpuConvexPlaneScene(helper) {}
virtual ~GpuBoxPlaneScene() {}
virtual const char* getName()
{
return "BoxBox";
}
virtual int createDynamicsObjects();
};
class GpuTetraScene : public GpuConvexScene
{
protected:
void createFromTetGenData(const char* ele, const char* node);
public:
virtual const char* getName()
{
return "TetraBreakable";
}
virtual int createDynamicsObjects();
};
b3Vector4 colors[4] =
{
b3MakeVector4(1, 0, 0, 1),
b3MakeVector4(0, 1, 0, 1),
b3MakeVector4(0, 1, 1, 1),
b3MakeVector4(1, 1, 0, 1),
};
void GpuConvexScene::setupScene()
{
m_raycaster = new b3GpuRaycast(m_clData->m_clContext, m_clData->m_clDevice, m_clData->m_clQueue);
int index = 0;
createStaticEnvironment();
index += createDynamicsObjects();
m_data->m_rigidBodyPipeline->writeAllInstancesToGpu();
float camPos[4] = {0, 0, 0, 0}; //ci.arraySizeX,ci.arraySizeY/2,ci.arraySizeZ,0};
//float camPos[4]={1,12.5,1.5,0};
m_guiHelper->getRenderInterface()->getActiveCamera()->setCameraTargetPosition(camPos[0], camPos[1], camPos[2]);
m_guiHelper->getRenderInterface()->getActiveCamera()->setCameraDistance(150);
//m_instancingRenderer->setCameraYaw(85);
m_guiHelper->getRenderInterface()->getActiveCamera()->setCameraYaw(225);
m_guiHelper->getRenderInterface()->getActiveCamera()->setCameraPitch(-30);
m_guiHelper->getRenderInterface()->updateCamera(1); //>updateCamera();
char msg[1024];
int numInstances = index;
sprintf(msg, "Num objects = %d", numInstances);
b3Printf(msg);
//if (ci.m_gui)
// ci.m_gui->setStatusBarMessage(msg,true);
}
void GpuConvexScene::destroyScene()
{
delete m_raycaster;
m_raycaster = 0;
}
int GpuConvexScene::createDynamicsObjects()
{
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 numVertices = sizeof(tetra_vertices) / strideInBytes;
int numIndices = sizeof(tetra_indices) / sizeof(int);
return createDynamicsObjects2(tetra_vertices, numVertices, tetra_indices, numIndices);
}
int GpuBoxPlaneScene::createDynamicsObjects()
{
int strideInBytes = 9 * sizeof(float);
int numVertices = sizeof(cube_vertices) / strideInBytes;
int numIndices = sizeof(cube_indices) / sizeof(int);
return createDynamicsObjects2(cube_vertices_textured, numVertices, cube_indices, numIndices);
}
int GpuConvexScene::createDynamicsObjects2(const float* vertices, int numVertices, const int* indices, int numIndices)
{
int strideInBytes = 9 * sizeof(float);
int textureIndex = -1;
if (0)
{
int width, height, n;
const char* filename = "data/cube.png";
const unsigned char* image = 0;
const char* prefix[] = {"./", "../", "../../", "../../../", "../../../../"};
int numprefix = sizeof(prefix) / sizeof(const char*);
for (int i = 0; !image && i < numprefix; i++)
{
char relativeFileName[1024];
sprintf(relativeFileName, "%s%s", prefix[i], filename);
image = loadImage(relativeFileName, width, height, n);
}
b3Assert(image);
if (image)
{
textureIndex = m_instancingRenderer->registerTexture(image, width, height);
}
}
int shapeId = m_guiHelper->getRenderInterface()->registerShape(&vertices[0], numVertices, indices, numIndices, B3_GL_TRIANGLES, textureIndex);
//int group=1;
//int mask=1;
int index = 0;
{
int curColor = 0;
float scaling[4] = {1, 1, 1, 1};
int prevBody = -1;
//int insta = 0;
b3ConvexUtility* utilPtr = new b3ConvexUtility();
{
b3AlignedObjectArray<b3Vector3> verts;
unsigned char* vts = (unsigned char*)vertices;
for (int i = 0; i < numVertices; i++)
{
float* vertex = (float*)&vts[i * strideInBytes];
verts.push_back(b3MakeVector3(vertex[0] * scaling[0], vertex[1] * scaling[1], vertex[2] * scaling[2]));
}
bool merge = true;
if (numVertices)
{
utilPtr->initializePolyhedralFeatures(&verts[0], verts.size(), merge);
}
}
int colIndex = -1;
if (gUseInstancedCollisionShapes)
colIndex = m_data->m_np->registerConvexHullShape(utilPtr);
//int colIndex = m_data->m_np->registerSphereShape(1);
for (int i = 0; i < gGpuArraySizeX; i++)
{
//printf("%d of %d\n", i, ci.arraySizeX);
for (int j = 0; j < gGpuArraySizeY; j++)
{
for (int k = 0; k < gGpuArraySizeZ; k++)
{
//int colIndex = m_data->m_np->registerConvexHullShape(&vertices[0],strideInBytes,numVertices, scaling);
if (!gUseInstancedCollisionShapes)
colIndex = m_data->m_np->registerConvexHullShape(utilPtr);
float mass = 1.f;
if (j == 0) //ci.arraySizeY-1)
{
//mass=0.f;
}
b3Vector3 position = b3MakeVector3(((j + 1) & 1) + i * 2.2, 1 + j * 2., ((j + 1) & 1) + k * 2.2);
//b3Vector3 position = b3MakeVector3(i*2,1+j*2,k*2);
//b3Vector3 position=b3MakeVector3(1,0.9,1);
b3Quaternion orn(0, 0, 0, 1);
b3Vector4 color = colors[curColor];
curColor++;
curColor &= 3;
// b3Vector4 scaling=b3MakeVector4(1,1,1,1);
int id;
id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId, position, orn, color, scaling);
int pid;
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++;
}
}
}
delete utilPtr;
}
return index;
}
void GpuConvexScene::createStaticEnvironment()
{
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 = m_instancingRenderer->registerShape(&cube_vertices[0], numVertices, cube_indices, numIndices);
//int group=1;
//int mask=1;
int index = 0;
{
b3Vector4 scaling = b3MakeVector4(400, 400, 400, 1);
int colIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0], strideInBytes, numVertices, scaling);
b3Vector3 position = b3MakeVector3(0, -400, 0);
b3Quaternion orn(0, 0, 0, 1);
b3Vector4 color = b3MakeVector4(0, 0, 1, 1);
int id;
id = m_instancingRenderer->registerGraphicsInstance(shapeId, position, orn, color, scaling);
int pid;
pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(0.f, position, orn, colIndex, index, false);
}
}
void GpuConvexPlaneScene::createStaticEnvironment()
{
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 = m_guiHelper->getRenderInterface()->registerShape(&cube_vertices[0], numVertices, cube_indices, numIndices);
// int group=1;
// int mask=1;
int index = 0;
{
b3Vector4 scaling = b3MakeVector4(400, 400, 400, 1);
int colIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0], strideInBytes, numVertices, scaling);
b3Vector3 position = b3MakeVector3(0, -400, 0);
b3Quaternion orn(0, 0, 0, 1);
b3Vector4 color = b3MakeVector4(0, 0, 1, 1);
int id;
id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId, position, orn, color, scaling);
int pid;
pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(0.f, position, orn, colIndex, index, false);
}
}
/*
void GpuConvexPlaneScene::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 shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int group=1;
int mask=1;
int index=0;
{
b3Vector4 scaling=b3MakeVector4(100,0.001,100,1);
//int colIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
b3Vector3 normal=b3MakeVector3(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=b3MakeVector3(0,0,0);
b3Quaternion orn(0,0,0,1);
b3Vector4 color=b3MakeVector4(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);
}
}
*/
struct TetraBunny
{
#include "bunny.inl"
};
struct TetraCube
{
#include "cube.inl"
};
static int nextLine(const char* buffer)
{
int numBytesRead = 0;
while (*buffer != '\n')
{
buffer++;
numBytesRead++;
}
if (buffer[0] == 0x0a)
{
buffer++;
numBytesRead++;
}
return numBytesRead;
}
static float mytetra_vertices[] =
{
-1.f, 0, -1.f, 0.5f, 0, 1, 0, 0, 0,
-1.f, 0, 1.f, 0.5f, 0, 1, 0, 1, 0,
1.f, 0, 1.f, 0.5f, 0, 1, 0, 1, 1,
1.f, 0, -1.f, 0.5f, 0, 1, 0, 0, 1};
static int mytetra_indices[] =
{
0, 1, 2,
3, 1, 2, 3, 2, 0,
3, 0, 1};
/* Create from TetGen .ele, .face, .node data */
void GpuTetraScene::createFromTetGenData(const char* ele,
const char* node)
{
b3Scalar scaling(10);
b3AlignedObjectArray<b3Vector3> pos;
int nnode = 0;
int ndims = 0;
int nattrb = 0;
int hasbounds = 0;
int result = sscanf(node, "%d %d %d %d", &nnode, &ndims, &nattrb, &hasbounds);
result = sscanf(node, "%d %d %d %d", &nnode, &ndims, &nattrb, &hasbounds);
node += nextLine(node);
//b3AlignedObjectArray<b3Vector3> rigidBodyPositions;
//b3AlignedObjectArray<int> rigidBodyIds;
pos.resize(nnode);
for (int i = 0; i < pos.size(); ++i)
{
int index = 0;
//int bound=0;
float x, y, z;
sscanf(node, "%d %f %f %f", &index, &x, &y, &z);
// sn>>index;
// sn>>x;sn>>y;sn>>z;
node += nextLine(node);
//for(int j=0;j<nattrb;++j)
// sn>>a;
//if(hasbounds)
// sn>>bound;
pos[index].setX(b3Scalar(x) * scaling);
pos[index].setY(b3Scalar(y) * scaling);
pos[index].setZ(b3Scalar(z) * scaling);
}
if (ele && ele[0])
{
int ntetra = 0;
int ncorner = 0;
int neattrb = 0;
sscanf(ele, "%d %d %d", &ntetra, &ncorner, &neattrb);
ele += nextLine(ele);
//se>>ntetra;se>>ncorner;se>>neattrb;
for (int i = 0; i < ntetra; ++i)
{
int index = 0;
int ni[4];
//se>>index;
//se>>ni[0];se>>ni[1];se>>ni[2];se>>ni[3];
sscanf(ele, "%d %d %d %d %d", &index, &ni[0], &ni[1], &ni[2], &ni[3]);
ele += nextLine(ele);
b3Vector3 average = b3MakeVector3(0, 0, 0);
for (int v = 0; v < 4; v++)
{
average += pos[ni[v]];
}
average /= 4;
for (int v = 0; v < 4; v++)
{
b3Vector3 shiftedPos = pos[ni[v]] - average;
mytetra_vertices[0 + v * 9] = shiftedPos.getX();
mytetra_vertices[1 + v * 9] = shiftedPos.getY();
mytetra_vertices[2 + v * 9] = shiftedPos.getZ();
}
//todo: subtract average
int strideInBytes = 9 * sizeof(float);
int numVertices = sizeof(mytetra_vertices) / strideInBytes;
int numIndices = sizeof(mytetra_indices) / sizeof(int);
int shapeId = m_instancingRenderer->registerShape(&mytetra_vertices[0], numVertices, mytetra_indices, numIndices);
// int group=1;
// int mask=1;
{
b3Vector4 scaling = b3MakeVector4(1, 1, 1, 1);
int colIndex = m_data->m_np->registerConvexHullShape(&mytetra_vertices[0], strideInBytes, numVertices, scaling);
b3Vector3 position = b3MakeVector3(0, 150, 0);
// position+=average;//*1.2;//*2;
position += average * 1.2; //*2;
//rigidBodyPositions.push_back(position);
b3Quaternion orn(0, 0, 0, 1);
static int curColor = 0;
b3Vector4 color = colors[curColor++];
curColor &= 3;
int id;
id = m_instancingRenderer->registerGraphicsInstance(shapeId, position, orn, color, scaling);
int pid;
pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(1.f, position, orn, colIndex, 0, false);
//rigidBodyIds.push_back(pid);
}
//for(int j=0;j<neattrb;++j)
// se>>a;
//psb->appendTetra(ni[0],ni[1],ni[2],ni[3]);
}
// printf("Nodes: %u\r\n",psb->m_nodes.size());
// printf("Links: %u\r\n",psb->m_links.size());
// printf("Faces: %u\r\n",psb->m_faces.size());
// printf("Tetras: %u\r\n",psb->m_tetras.size());
}
m_data->m_rigidBodyPipeline->writeAllInstancesToGpu();
m_data->m_np->writeAllBodiesToGpu();
m_data->m_bp->writeAabbsToGpu();
m_data->m_rigidBodyPipeline->setupGpuAabbsFull();
m_data->m_bp->calculateOverlappingPairs(m_data->m_config.m_maxBroadphasePairs);
int numPairs = m_data->m_bp->getNumOverlap();
cl_mem pairs = m_data->m_bp->getOverlappingPairBuffer();
b3OpenCLArray<b3Int2> clPairs(m_clData->m_clContext, m_clData->m_clQueue);
clPairs.setFromOpenCLBuffer(pairs, numPairs);
b3AlignedObjectArray<b3Int2> allPairs;
clPairs.copyToHost(allPairs);
for (int p = 0; p < allPairs.size(); p++)
{
b3Vector3 posA, posB;
b3Quaternion ornA, ornB;
int bodyIndexA = allPairs[p].x;
int bodyIndexB = allPairs[p].y;
m_data->m_np->getObjectTransformFromCpu(posA, ornA, bodyIndexA);
m_data->m_np->getObjectTransformFromCpu(posB, ornB, bodyIndexB);
b3Vector3 pivotWorld = (posA + posB) * 0.5f;
b3Transform transA, transB;
transA.setIdentity();
transA.setOrigin(posA);
transA.setRotation(ornA);
transB.setIdentity();
transB.setOrigin(posB);
transB.setRotation(ornB);
b3Vector3 pivotInA = transA.inverse() * pivotWorld;
b3Vector3 pivotInB = transB.inverse() * pivotWorld;
b3Transform frameInA, frameInB;
frameInA.setIdentity();
frameInB.setIdentity();
frameInA.setOrigin(pivotInA);
frameInB.setOrigin(pivotInB);
b3Quaternion relTargetAB = frameInA.getRotation() * frameInB.getRotation().inverse();
//c = new b3FixedConstraint(pid,prevBody,frameInA,frameInB);
float breakingThreshold = 45; //37.f;
//c->setBreakingImpulseThreshold(37.1);
bool useGPU = true;
if (useGPU)
{
int cid;
cid = m_data->m_rigidBodyPipeline->createFixedConstraint(bodyIndexA, bodyIndexB, pivotInA, pivotInB, relTargetAB, breakingThreshold);
}
else
{
b3FixedConstraint* c = new b3FixedConstraint(bodyIndexA, bodyIndexB, frameInA, frameInB);
c->setBreakingImpulseThreshold(breakingThreshold);
m_data->m_rigidBodyPipeline->addConstraint(c);
}
}
printf("numPairs = %d\n", numPairs);
}
int GpuTetraScene::createDynamicsObjects()
{
//createFromTetGenData(TetraCube::getElements(),TetraCube::getNodes());
createFromTetGenData(TetraBunny::getElements(), TetraBunny::getNodes());
return 0;
}
class CommonExampleInterface* OpenCLBoxBoxCreateFunc(struct CommonExampleOptions& options)
{
return new GpuBoxPlaneScene(options.m_guiHelper);
}

View file

@ -0,0 +1,6 @@
#ifndef GPU_CONVEX_SCENE_H
#define GPU_CONVEX_SCENE_H
class CommonExampleInterface* OpenCLBoxBoxCreateFunc(struct CommonExampleOptions& options);
#endif //GPU_CONVEX_SCENE_H

View file

@ -0,0 +1,488 @@
#include "GpuRigidBodyDemo.h"
#include "../OpenGLWindow/ShapeData.h"
#include "../OpenGLWindow/GLInstancingRenderer.h"
#include "Bullet3Common/b3Quaternion.h"
#include "../CommonInterfaces/CommonWindowInterface.h"
#include "Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.h"
#include "Bullet3OpenCL/BroadphaseCollision/b3GpuGridBroadphase.h"
#include "../CommonOpenCL/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 "Bullet3Collision/NarrowPhaseCollision/b3Config.h"
#include "GpuRigidBodyDemoInternalData.h"
#include "Bullet3Collision/BroadPhaseCollision/b3DynamicBvhBroadphase.h"
#include "Bullet3Collision/NarrowPhaseCollision/shared/b3RigidBodyData.h"
#include "Bullet3OpenCL/RigidBody/b3GpuNarrowPhaseInternalData.h"
#include "stb_image/stb_image.h"
#include "../OpenGLWindow/GLPrimitiveRenderer.h"
extern int gPreferredOpenCLDeviceIndex;
extern int gPreferredOpenCLPlatformIndex;
extern int gGpuArraySizeX;
extern int gGpuArraySizeY;
extern int gGpuArraySizeZ;
static b3KeyboardCallback oldCallback = 0;
extern bool gReset;
bool useUniformGrid = false;
bool convertOnCpu = false;
#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(GUIHelperInterface* helper)
: CommonOpenCLBase(helper),
m_instancingRenderer(0),
m_window(0)
{
if (helper->getRenderInterface()->getInternalData())
{
m_instancingRenderer = (GLInstancingRenderer*)helper->getRenderInterface();
}
else
{
m_instancingRenderer = 0;
}
m_window = helper->getAppInterface()->m_window;
m_data = new GpuRigidBodyDemoInternalData;
m_data->m_guiHelper = helper;
}
void GpuRigidBodyDemo::resetCamera()
{
float dist = 114;
float pitch = -35;
float yaw = 52;
float targetPos[3] = {0, 0, 0};
m_data->m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
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()
{
}
void GpuRigidBodyDemo::initPhysics()
{
initCL(gPreferredOpenCLDeviceIndex, gPreferredOpenCLPlatformIndex);
m_guiHelper->setUpAxis(1);
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);
m_data->m_config.m_maxConvexBodies = b3Max(m_data->m_config.m_maxConvexBodies, gGpuArraySizeX * gGpuArraySizeY * gGpuArraySizeZ + 10);
m_data->m_config.m_maxConvexShapes = m_data->m_config.m_maxConvexBodies;
int maxPairsPerBody = 16;
m_data->m_config.m_maxBroadphasePairs = maxPairsPerBody * m_data->m_config.m_maxConvexBodies;
m_data->m_config.m_maxContactCapacity = m_data->m_config.m_maxBroadphasePairs;
b3GpuNarrowPhase* np = new b3GpuNarrowPhase(m_clData->m_clContext, m_clData->m_clDevice, m_clData->m_clQueue, m_data->m_config);
b3GpuBroadphaseInterface* bp = 0;
if (useUniformGrid)
{
bp = new b3GpuGridBroadphase(m_clData->m_clContext, m_clData->m_clDevice, m_clData->m_clQueue);
}
else
{
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;
m_data->m_broadphaseDbvt = new b3DynamicBvhBroadphase(m_data->m_config.m_maxConvexBodies);
m_data->m_rigidBodyPipeline = new b3GpuRigidBodyPipeline(m_clData->m_clContext, m_clData->m_clDevice, m_clData->m_clQueue, np, bp, m_data->m_broadphaseDbvt, m_data->m_config);
setupScene();
m_data->m_rigidBodyPipeline->writeAllInstancesToGpu();
np->writeAllBodiesToGpu();
bp->writeAabbsToGpu();
}
m_guiHelper->getRenderInterface()->writeTransforms();
}
void GpuRigidBodyDemo::exitPhysics()
{
destroyScene();
delete m_data->m_instancePosOrnColor;
delete m_data->m_rigidBodyPipeline;
delete m_data->m_broadphaseDbvt;
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_guiHelper->getRenderInterface()->renderScene();
}
void GpuRigidBodyDemo::stepSimulation(float deltaTime)
{
if (!m_instancingRenderer)
return;
bool animate = true;
int numObjects = m_data->m_rigidBodyPipeline->getNumBodies();
//printf("numObjects=%d\n",numObjects);
if (numObjects > m_instancingRenderer->getInstanceCapacity())
{
static bool once = true;
if (once)
{
once = false;
b3Assert(0);
b3Error("m_instancingRenderer out-of-memory\n");
}
numObjects = m_instancingRenderer->getInstanceCapacity();
}
GLint err = glGetError();
assert(err == GL_NO_ERROR);
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)
{
if (convertOnCpu)
{
b3GpuNarrowPhaseInternalData* npData = m_data->m_np->getInternalData();
npData->m_bodyBufferGPU->copyToHost(*npData->m_bodyBufferCPU);
b3AlignedObjectArray<b3Vector4> vboCPU;
m_data->m_instancePosOrnColor->copyToHost(vboCPU);
for (int i = 0; i < numObjects; i++)
{
b3Vector4 pos = (const b3Vector4&)npData->m_bodyBufferCPU->at(i).m_pos;
b3Quat orn = npData->m_bodyBufferCPU->at(i).m_quat;
pos.w = 1.f;
vboCPU[i] = pos;
vboCPU[i + numObjects] = (b3Vector4&)orn;
}
m_data->m_instancePosOrnColor->copyFromHost(vboCPU);
}
else
{
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, "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);
}
}
b3Vector3 GpuRigidBodyDemo::getRayTo(int x, int y)
{
if (!m_instancingRenderer)
return b3MakeVector3(0, 0, 0);
float top = 1.f;
float bottom = -1.f;
float nearPlane = 1.f;
float tanFov = (top - bottom) * 0.5f / nearPlane;
float fov = b3Scalar(2.0) * b3Atan(tanFov);
b3Vector3 camPos, camTarget;
m_instancingRenderer->getActiveCamera()->getCameraPosition(camPos);
m_instancingRenderer->getActiveCamera()->getCameraTargetPosition(camTarget);
b3Vector3 rayFrom = camPos;
b3Vector3 rayForward = (camTarget - camPos);
rayForward.normalize();
float farPlane = 10000.f;
rayForward *= farPlane;
// b3Vector3 rightOffset;
b3Vector3 m_cameraUp = b3MakeVector3(0, 1, 0);
b3Vector3 vertical = m_cameraUp;
b3Vector3 hor;
hor = rayForward.cross(vertical);
hor.normalize();
vertical = hor.cross(rayForward);
vertical.normalize();
float tanfov = tanf(0.5f * fov);
hor *= 2.f * farPlane * tanfov;
vertical *= 2.f * farPlane * tanfov;
b3Scalar aspect;
float width = m_instancingRenderer->getScreenWidth();
float height = m_instancingRenderer->getScreenHeight();
aspect = width / height;
hor *= aspect;
b3Vector3 rayToCenter = rayFrom + rayForward;
b3Vector3 dHor = hor * 1.f / width;
b3Vector3 dVert = vertical * 1.f / height;
b3Vector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical;
rayTo += b3Scalar(x) * dHor;
rayTo -= b3Scalar(y) * dVert;
return rayTo;
}
unsigned char* GpuRigidBodyDemo::loadImage(const char* fileName, int& width, int& height, int& n)
{
unsigned char* data = stbi_load(fileName, &width, &height, &n, 3);
return data;
}
bool GpuRigidBodyDemo::keyboardCallback(int key, int state)
{
if (m_data)
{
if (key == B3G_ALT)
{
m_data->m_altPressed = state;
}
if (key == B3G_CONTROL)
{
m_data->m_controlPressed = state;
}
}
return false;
}
bool GpuRigidBodyDemo::mouseMoveCallback(float x, float y)
{
if (!m_instancingRenderer)
return false;
if (m_data->m_altPressed != 0 || m_data->m_controlPressed != 0)
return false;
if (m_data->m_pickBody >= 0 && m_data->m_pickConstraint >= 0)
{
m_data->m_rigidBodyPipeline->removeConstraintByUid(m_data->m_pickConstraint);
b3Vector3 newRayTo = getRayTo(x, y);
b3Vector3 rayFrom;
// b3Vector3 oldPivotInB = m_data->m_pickPivotInB;
b3Vector3 newPivotB;
m_guiHelper->getRenderInterface()->getActiveCamera()->getCameraPosition(rayFrom);
b3Vector3 dir = newRayTo - rayFrom;
dir.normalize();
dir *= m_data->m_pickDistance;
newPivotB = rayFrom + dir;
m_data->m_pickPivotInB = newPivotB;
m_data->m_rigidBodyPipeline->copyConstraintsToHost();
m_data->m_pickConstraint = m_data->m_rigidBodyPipeline->createPoint2PointConstraint(m_data->m_pickBody, m_data->m_pickFixedBody, m_data->m_pickPivotInA, m_data->m_pickPivotInB, 1e30);
m_data->m_rigidBodyPipeline->writeAllInstancesToGpu();
return true;
}
return false;
}
bool GpuRigidBodyDemo::mouseButtonCallback(int button, int state, float x, float y)
{
if (!m_instancingRenderer)
return false;
if (state == 1)
{
if (button == 0 && (m_data->m_altPressed == 0 && m_data->m_controlPressed == 0))
{
b3AlignedObjectArray<b3RayInfo> rays;
b3AlignedObjectArray<b3RayHit> hitResults;
b3Vector3 camPos;
m_guiHelper->getRenderInterface()->getActiveCamera()->getCameraPosition(camPos);
b3RayInfo ray;
ray.m_from = camPos;
ray.m_to = getRayTo(x, y);
rays.push_back(ray);
b3RayHit hit;
hit.m_hitFraction = 1.f;
hitResults.push_back(hit);
m_data->m_rigidBodyPipeline->castRays(rays, hitResults);
if (hitResults[0].m_hitFraction < 1.f)
{
int hitBodyA = hitResults[0].m_hitBody;
if (m_data->m_np->getBodiesCpu()[hitBodyA].m_invMass)
{
//printf("hit!\n");
m_data->m_np->readbackAllBodiesToCpu();
m_data->m_pickBody = hitBodyA;
//pivotInA
b3Vector3 pivotInB;
pivotInB.setInterpolate3(ray.m_from, ray.m_to, hitResults[0].m_hitFraction);
b3Vector3 posA;
b3Quaternion ornA;
m_data->m_np->getObjectTransformFromCpu(posA, ornA, hitBodyA);
b3Transform tr;
tr.setOrigin(posA);
tr.setRotation(ornA);
b3Vector3 pivotInA = tr.inverse() * pivotInB;
if (m_data->m_pickFixedBody < 0)
{
b3Vector3 pos = b3MakeVector3(0, 0, 0);
b3Quaternion orn(0, 0, 0, 1);
int fixedSphere = m_data->m_np->registerConvexHullShape(0, 0, 0, 0); //>registerSphereShape(0.1);
m_data->m_pickFixedBody = m_data->m_rigidBodyPipeline->registerPhysicsInstance(0, pos, orn, fixedSphere, 0, false);
m_data->m_rigidBodyPipeline->writeAllInstancesToGpu();
m_data->m_bp->writeAabbsToGpu();
if (m_data->m_pickGraphicsShapeIndex < 0)
{
int strideInBytes = 9 * sizeof(float);
int numVertices = sizeof(point_sphere_vertices) / strideInBytes;
int numIndices = sizeof(point_sphere_indices) / sizeof(int);
m_data->m_pickGraphicsShapeIndex = m_guiHelper->getRenderInterface()->registerShape(&point_sphere_vertices[0], numVertices, point_sphere_indices, numIndices, B3_GL_POINTS);
float color[4] = {1, 0, 0, 1};
float scaling[4] = {1, 1, 1, 1};
m_data->m_pickGraphicsShapeInstance = m_guiHelper->getRenderInterface()->registerGraphicsInstance(m_data->m_pickGraphicsShapeIndex, pivotInB, orn, color, scaling);
m_guiHelper->getRenderInterface()->writeTransforms();
delete m_data->m_instancePosOrnColor;
m_data->m_instancePosOrnColor = 0;
}
else
{
m_guiHelper->getRenderInterface()->writeSingleInstanceTransformToCPU(pivotInB, orn, m_data->m_pickGraphicsShapeInstance);
if (this->m_instancingRenderer)
m_instancingRenderer->writeSingleInstanceTransformToGPU(pivotInB, orn, m_data->m_pickGraphicsShapeInstance);
m_data->m_np->setObjectTransformCpu(pos, orn, m_data->m_pickFixedBody);
}
}
pivotInB.w = 0.f;
m_data->m_pickPivotInA = pivotInA;
m_data->m_pickPivotInB = pivotInB;
m_data->m_rigidBodyPipeline->copyConstraintsToHost();
m_data->m_pickConstraint = m_data->m_rigidBodyPipeline->createPoint2PointConstraint(hitBodyA, m_data->m_pickFixedBody, pivotInA, pivotInB, 1e30); //hitResults[0].m_hitResult0
m_data->m_rigidBodyPipeline->writeAllInstancesToGpu();
m_data->m_np->writeAllBodiesToGpu();
m_data->m_pickDistance = (pivotInB - camPos).length();
return true;
}
}
}
}
else
{
if (button == 0)
{
if (m_data->m_pickConstraint >= 0)
{
m_data->m_rigidBodyPipeline->removeConstraintByUid(m_data->m_pickConstraint);
m_data->m_pickConstraint = -1;
}
}
}
//printf("button=%d, state=%d\n",button,state);
return false;
}

View file

@ -0,0 +1,43 @@
#ifndef GPU_RIGID_BODY_DEMO_H
#define GPU_RIGID_BODY_DEMO_H
#include "Bullet3Common/b3Vector3.h"
#include "../CommonOpenCL/CommonOpenCLBase.h"
class GpuRigidBodyDemo : public CommonOpenCLBase
{
protected:
class GLInstancingRenderer* m_instancingRenderer;
class GLPrimitiveRenderer* m_primRenderer;
class CommonWindowInterface* m_window;
struct GpuRigidBodyDemoInternalData* m_data;
public:
GpuRigidBodyDemo(GUIHelperInterface* helper);
virtual ~GpuRigidBodyDemo();
virtual void initPhysics();
virtual void setupScene();
virtual void destroyScene(){};
virtual void exitPhysics();
virtual void renderScene();
void resetCamera();
virtual void stepSimulation(float deltaTime);
//for picking
b3Vector3 getRayTo(int x, int y);
virtual bool mouseMoveCallback(float x, float y);
virtual bool mouseButtonCallback(int button, int state, float x, float y);
virtual bool keyboardCallback(int key, int state);
unsigned char* loadImage(const char* fileName, int& width, int& height, int& n);
};
#endif //GPU_RIGID_BODY_DEMO_H

View file

@ -0,0 +1,56 @@
#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"
#include "Bullet3Collision/NarrowPhaseCollision/b3Config.h"
struct GpuRigidBodyDemoInternalData
{
cl_kernel m_copyTransformsToVBOKernel;
b3OpenCLArray<b3Vector4>* m_instancePosOrnColor;
class b3GpuRigidBodyPipeline* m_rigidBodyPipeline;
class b3GpuNarrowPhase* m_np;
class b3GpuBroadphaseInterface* m_bp;
struct b3DynamicBvhBroadphase* m_broadphaseDbvt;
b3Vector3 m_pickPivotInA;
b3Vector3 m_pickPivotInB;
float m_pickDistance;
int m_pickBody;
int m_pickConstraint;
int m_altPressed;
int m_controlPressed;
int m_pickFixedBody;
int m_pickGraphicsShapeIndex;
int m_pickGraphicsShapeInstance;
b3Config m_config;
GUIHelperInterface* m_guiHelper;
GpuRigidBodyDemoInternalData()
: m_instancePosOrnColor(0),
m_copyTransformsToVBOKernel(0),
m_rigidBodyPipeline(0),
m_np(0),
m_bp(0),
m_broadphaseDbvt(0),
m_pickConstraint(-1),
m_pickFixedBody(-1),
m_pickGraphicsShapeIndex(-1),
m_pickGraphicsShapeInstance(-1),
m_pickBody(-1),
m_altPressed(0),
m_controlPressed(0),
m_guiHelper(0)
{
}
};
#endif //GPU_RIGIDBODY_INTERNAL_DATA_H

View file

@ -0,0 +1,179 @@
#include "GpuSphereScene.h"
#include "GpuRigidBodyDemo.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 "Bullet3Collision/NarrowPhaseCollision/b3Config.h"
#include "GpuRigidBodyDemoInternalData.h"
#include "Bullet3AppSupport/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] =
{
b3MakeVector4(1, 0, 0, 1),
b3MakeVector4(0, 1, 0, 1),
b3MakeVector4(0, 1, 1, 1),
b3MakeVector4(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 = b3MakeVector3(0, 0, 0);
b3Quaternion orn(0, 0, 0, 1);
b3Vector4 color = colors[curColor];
curColor++;
curColor &= 3;
b3Vector4 scaling = b3MakeVector4(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] =
{
b3MakeVector4(1, 0, 0, 1),
b3MakeVector4(0, 1, 0, 1),
b3MakeVector4(0, 1, 1, 1),
b3MakeVector4(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 = b3MakeVector3(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 = b3MakeVector4(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 = b3MakeVector4(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 = b3MakeVector3(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 = b3MakeVector4(2 * i, 70 + k * 2, 2 * j + 8, 0);
//b3Quaternion orn(0,0,0,1);
b3Quaternion orn(b3MakeVector3(1, 0, 0), 0.3);
b3Vector4 color = b3MakeVector4(0, 0, 1, 1);
int id = ci.m_instancingRenderer->registerGraphicsInstance(shapeId, position, orn, color, scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(1.f, position, orn, colIndex, index, false);
index++;
}
}
if (!writeInstanceToGpu)
{
m_data->m_rigidBodyPipeline->writeAllInstancesToGpu();
}
float camPos[4] = {ci.arraySizeX, ci.arraySizeY / 2, ci.arraySizeZ, 0};
//float camPos[4]={1,12.5,1.5,0};
m_instancingRenderer->setCameraTargetPosition(camPos);
m_instancingRenderer->setCameraDistance(130);
char msg[1024];
int numInstances = index;
sprintf(msg, "Num objects = %d", numInstances);
ci.m_gui->setStatusBarMessage(msg, true);
}

View file

@ -0,0 +1,25 @@
#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 "BoxOnSphere";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new GpuSphereScene;
return demo;
}
virtual void setupScene(const ConstructionInfo& ci);
};
#endif //GPU_SPHERE_SCENE_H

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long