123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512 |
- #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;
- }
- 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;
- }
|