Files
bullet3/Demos/ParticlesOpenCL/btParticlesDynamicsWorld.h
2010-07-24 06:52:55 +00:00

184 lines
5.5 KiB
C++

/*
Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
Copyright (C) 2006 - 2009 Sony Computer Entertainment Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_PARTICLES_DYNAMICS_WORLD_H
#define BT_PARTICLES_DYNAMICS_WORLD_H
#ifdef USE_MINICL
#include <MiniCL/cl.h>
#include <MiniCL/cl_gl.h>
#else
#ifdef __APPLE__
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
#include <CL/cl_gl.h>
#endif __APPLE__
#endif
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
#include "btParticlesSharedDefs.h"
#include "btParticlesSharedTypes.h"
#define PARTICLES_MAX_NEIGHBORS (32)
#define DEF_PARTICLE_RADIUS (0.023f)
//#define WORLD_SIZE 1.9f
#define WORLD_SIZE 1.f
enum
{
PARTICLES_KERNEL_INTEGRATE_MOTION = 0,
PARTICLES_KERNEL_COMPUTE_CELL_ID,
PARTICLES_KERNEL_CLEAR_CELL_START,
PARTICLES_KERNEL_FIND_CELL_START,
PARTICLES_KERNEL_COLLIDE_PARTICLES,
PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_LOCAL,
PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_LOCAL_1,
PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_GLOBAL,
PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_LOCAL,
PARTICLES_KERNEL_TOTAL
};
enum
{
SIMSTAGE_NONE = 0,
SIMSTAGE_INTEGRATE_MOTION,
SIMSTAGE_COMPUTE_CELL_ID,
SIMSTAGE_SORT_CELL_ID,
SIMSTAGE_FIND_CELL_START,
SIMSTAGE_COLLIDE_PARTICLES,
SIMSTAGE_TOTAL
};
struct btKernelInfo
{
int m_Id;
cl_kernel m_kernel;
char* m_name;
int m_workgroupSize;
};
class btParticlesDynamicsWorld : public btDiscreteDynamicsWorld
{
public:
int m_numParticles;
int m_usedDevice;
btScalar m_particleRad;
struct GL_ToggleControl* m_useCpuControls[SIMSTAGE_TOTAL];
protected:
int m_hashSize; // power of 2 >= m_numSpheres;
int m_numGridCells;
int m_maxNeighbors;
int m_numSolverIterations;
// CPU side data
public:
btAlignedObjectArray<btVector3> m_hPos;
btAlignedObjectArray<btVector3> m_hVel;
btAlignedObjectArray<btVector3> m_hSortedPos;
btAlignedObjectArray<btVector3> m_hSortedVel;
protected:
btAlignedObjectArray<btInt2> m_hPosHash;
btAlignedObjectArray<int> m_hCellStart;
// GPU side data
cl_mem m_dPos;
cl_mem m_dVel;
cl_mem m_dPosHash;
cl_mem m_dCellStart;
cl_mem m_dSimParams; // copy of m_simParams : global simulation paramerers such as gravity, etc.
cl_mem m_dSortedPos;
cl_mem m_dSortedVel;
// OpenCL
public:
cl_context m_cxMainContext;
cl_device_id m_cdDevice;
cl_command_queue m_cqCommandQue;
cl_program m_cpProgram;
protected:
btKernelInfo m_kernels[PARTICLES_KERNEL_TOTAL];
btVector3 m_cellSize;
public:
btVector3 m_worldMin;
btVector3 m_worldMax;
// vbo variables
GLuint m_vbo;
unsigned int m_posVbo;
unsigned int m_colVbo;
btSimParams m_simParams;
float m_timeStep;
int getNumParticles() { return m_numParticles; }
float* getPosBuffer() { return (float*)&(m_hPos[0]); }
btParticlesDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration,
int maxObjs , int maxNeighbors = PARTICLES_MAX_NEIGHBORS)
: btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration)
{
m_cxMainContext = 0;
m_usedDevice = 1;
// m_particleRad = btScalar(0.5f);
m_particleRad = DEF_PARTICLE_RADIUS;
m_simParams.m_gravity[0] = 0.f;
m_simParams.m_gravity[1] = -10.f;
m_simParams.m_gravity[2] = 0.f;
m_simParams.m_gravity[3] = 0.f;
m_numSolverIterations = 4;
}
virtual ~btParticlesDynamicsWorld();
virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.));
void initDeviceData();
void initCLKernels(int argc, char** argv);
void createVBO();
void postInitDeviceData();
void getShapeData();
void allocateBuffers();
void grabSimulationData();
void adjustGrid();
void runIntegrateMotionKernel();
void runComputeCellIdKernel();
void runSortHashKernel();
void runFindCellStartKernel();
void runCollideParticlesKernel();
void initKernel(int kernelId, char* pName);
void runKernelWithWorkgroupSize(int kernelId, int globalSize);
void bitonicSortNv(cl_mem pKey, unsigned int batch, unsigned int arrayLength, unsigned int dir);
void scanExclusiveLocal1(cl_mem d_Dst, cl_mem d_Src, unsigned int n, unsigned int size);
void scanExclusiveLocal2(cl_mem d_Buffer, cl_mem d_Dst, cl_mem d_Src, unsigned int n, unsigned int size);
void uniformUpdate(cl_mem d_Dst, cl_mem d_Buffer, unsigned int n);
void scanExclusive(cl_mem d_Dst, cl_mem d_Src, unsigned int arrayLength);
};
#endif //BT_PARTICLES_DYNAMICS_WORLD_H