add preliminary GPU ray cast (brute-force slow, only against sphere, allocates OpenCL buffers at every cast)

This commit is contained in:
erwin coumans
2013-05-28 18:39:53 -07:00
parent f55473d586
commit a886a978b7
7 changed files with 458 additions and 117 deletions

View File

@@ -19,11 +19,15 @@
#include "../gwenUserInterface.h"
#include "Bullet3Dynamics/ConstraintSolver/b3Point2PointConstraint.h"
#include "OpenGLWindow/GLPrimitiveRenderer.h"
#include "Bullet3OpenCL/RayCast/b3GpuRayCast.h"
void GpuConvexScene::setupScene(const ConstructionInfo& ci)
{
m_primRenderer = ci.m_primRenderer;
m_raycaster = new b3GpuRaycast(m_clData->m_clContext,m_clData->m_clDevice,m_clData->m_clQueue);
int index=0;
createStaticEnvironment(ci);
@@ -46,6 +50,12 @@ void GpuConvexScene::setupScene(const ConstructionInfo& ci)
ci.m_gui->setStatusBarMessage(msg,true);
}
void GpuConvexScene::destroyScene()
{
delete m_raycaster;
m_raycaster = 0;
}
int GpuConvexScene::createDynamicsObjects(const ConstructionInfo& ci)
{
int strideInBytes = 9*sizeof(float);
@@ -236,27 +246,6 @@ GpuRaytraceScene::~GpuRaytraceScene()
}
bool sphere_intersect(const b3Vector3& spherePos, b3Scalar radius, const b3Vector3& rayFrom, const b3Vector3& rayTo)
{
// rs = ray.org - sphere.center
const b3Vector3& rs = rayFrom - spherePos;
b3Vector3 rayDir = rayTo-rayFrom;//rayFrom-rayTo;
rayDir.normalize();
float B = b3Dot(rs, rayDir);
float C = b3Dot(rs, rs) - (radius * radius);
float D = B * B - C;
if (D > 0.0)
{
float t = -B - sqrt(D);
if ( (t > 0.0))// && (t < isect.t) )
{
return true;//isect.t = t;
}
}
return false;
}
int GpuRaytraceScene::createDynamicsObjects(const ConstructionInfo& ci)
{
@@ -284,14 +273,14 @@ int GpuRaytraceScene::createDynamicsObjects(const ConstructionInfo& ci)
//int colIndex = m_data->m_np->registerSphereShape(1);
for (int i=0;i<1;i++)
for (int i=0;i<10;i++)
//for (int i=0;i<ci.arraySizeX;i++)
{
//for (int j=0;j<ci.arraySizeY;j++)
for (int j=0;j<5;j++)
for (int j=0;j<10;j++)
{
// for (int k=0;k<ci.arraySizeZ;k++)
for (int k=0;k<1;k++)
for (int k=0;k<10;k++)
{
float mass = 1.f;
if (j==0)//ci.arraySizeY-1)
@@ -328,6 +317,8 @@ int GpuRaytraceScene::createDynamicsObjects(const ConstructionInfo& ci)
}
//create primary rays
b3AlignedObjectArray<b3RayInfo> rays;
void GpuRaytraceScene::renderScene()
{
@@ -339,109 +330,125 @@ void GpuRaytraceScene::renderScene()
m_instancingRenderer->updateCamera();
//generate primary rays
float top = 1.f;
float bottom = -1.f;
float nearPlane = 1.f;
float farPlane = 1000.f;
float tanFov = (top-bottom)*0.5f / nearPlane;
float screenWidth = m_instancingRenderer->getScreenWidth();
float screenHeight = m_instancingRenderer->getScreenHeight();
float fov = 2. * atanf (tanFov);
float aspect = screenWidth / screenHeight;
b3Vector3 rayFrom, camTarget;
m_instancingRenderer->getCameraPosition(rayFrom);
m_instancingRenderer->getCameraTargetPosition(camTarget);
b3Vector3 rayForward = camTarget-rayFrom;
rayForward.normalize();
rayForward*= farPlane;
b3Vector3 rightOffset;
b3Vector3 vertical(0.f,1.f,0.f);
b3Vector3 hor;
hor = rayForward.cross(vertical);
hor.normalize();
vertical = hor.cross(rayForward);
vertical.normalize();
float tanfov = tanf(0.5f*fov);
hor *= aspect*2.f * farPlane * tanfov;
vertical *= 2.f * farPlane * tanfov;
b3Vector3 rayToCenter = rayFrom + rayForward;
float texWidth = m_raytraceData->textureWidth;
float texHeight = m_raytraceData->textureHeight;
float widthFactor = (screenWidth/texWidth);
float heightFactor = (screenHeight/texHeight);
//should be screenwidth/height
b3Vector3 dHor = hor * 1./float(screenWidth);
b3Vector3 dVert = vertical * 1./float(screenHeight);
b3Transform rayFromTrans;
rayFromTrans.setIdentity();
rayFromTrans.setOrigin(rayFrom);
b3Transform rayFromLocal;
b3Transform rayToLocal;
//cast primary rays
m_data->m_np->readbackAllBodiesToCpu();
for (int x=0;x<m_raytraceData->textureWidth;x++)
{
for (int y=0;y<m_raytraceData->textureHeight;y++)
B3_PROFILE("Generate primary rays");
float top = 1.f;
float bottom = -1.f;
float nearPlane = 1.f;
float farPlane = 1000.f;
float tanFov = (top-bottom)*0.5f / nearPlane;
float screenWidth = m_instancingRenderer->getScreenWidth();
float screenHeight = m_instancingRenderer->getScreenHeight();
float fov = 2. * atanf (tanFov);
float aspect = screenWidth / screenHeight;
b3Vector3 rayFrom, camTarget;
m_instancingRenderer->getCameraPosition(rayFrom);
m_instancingRenderer->getCameraTargetPosition(camTarget);
b3Vector3 rayForward = camTarget-rayFrom;
rayForward.normalize();
rayForward*= farPlane;
b3Vector3 rightOffset;
b3Vector3 vertical(0.f,1.f,0.f);
b3Vector3 hor;
hor = rayForward.cross(vertical);
hor.normalize();
vertical = hor.cross(rayForward);
vertical.normalize();
float tanfov = tanf(0.5f*fov);
hor *= aspect*2.f * farPlane * tanfov;
vertical *= 2.f * farPlane * tanfov;
b3Vector3 rayToCenter = rayFrom + rayForward;
float texWidth = m_raytraceData->textureWidth;
float texHeight = m_raytraceData->textureHeight;
float widthFactor = (screenWidth/texWidth);
float heightFactor = (screenHeight/texHeight);
//should be screenwidth/height
b3Vector3 dHor = hor * 1./float(screenWidth);
b3Vector3 dVert = vertical * 1./float(screenHeight);
b3Transform rayFromTrans;
rayFromTrans.setIdentity();
rayFromTrans.setOrigin(rayFrom);
b3Transform rayFromLocal;
b3Transform rayToLocal;
m_data->m_np->readbackAllBodiesToCpu();
//create primary rays
rays.resize(m_raytraceData->textureWidth*m_raytraceData->textureHeight);
b3Vector3 rayTo;
b3RayInfo ray;
{
b3Vector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical;
rayTo += x * dHor*widthFactor;
rayTo -= y * dVert*heightFactor;
//if there is a hit, color the pixels
int numBodies = m_data->m_rigidBodyPipeline->getNumBodies();
bool hits = false;
for (int i=0;i<numBodies && !hits;i++)
for (int x=0;x<m_raytraceData->textureWidth;x++)
{
b3Vector3 pos;
b3Quaternion orn;
m_data->m_np->getObjectTransformFromCpu(pos,orn,i);
b3Scalar radius = 1;
for (int y=0;y<m_raytraceData->textureHeight;y++)
{
hits = sphere_intersect(pos, radius, rayFrom, rayTo);
rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical;
rayTo += x * dHor*widthFactor;
rayTo -= y * dVert*heightFactor;
ray.m_from = rayFrom;
ray.m_to = rayTo;
rays[x+m_raytraceData->textureWidth*y] = ray;
}
}
if (hits)
{
m_raytraceData->m_texels[(x+m_raytraceData->textureWidth*y)*3+0] = 255;
m_raytraceData->m_texels[(x+m_raytraceData->textureWidth*y)*3+1] = 0;
m_raytraceData->m_texels[(x+m_raytraceData->textureWidth*y)*3+2] = 0;
} else
{
m_raytraceData->m_texels[(x+m_raytraceData->textureWidth*y)*3+0] = 0;
m_raytraceData->m_texels[(x+m_raytraceData->textureWidth*y)*3+1] = 0;
m_raytraceData->m_texels[(x+m_raytraceData->textureWidth*y)*3+2] = 0;
}
}
}
b3AlignedObjectArray<b3RayHit> hits;
hits.resize(rays.size());
{
B3_PROFILE("init hits");
for (int i=0;i<hits.size();i++)
{
hits[i].m_hitFraction = 1.f;
}
}
m_raycaster->castRaysHost(rays, hits, this->m_data->m_np->getNumBodiesGpu(), m_data->m_np->getBodiesCpu(), m_data->m_np->getNumCollidablesGpu(), m_data->m_np->getCollidablesCpu());
{
B3_PROFILE("write texels");
for (int i=0;i<hits.size();i++)
{
bool hit = hits[i].m_hitFraction < 1.f;
if (hit)
{
m_raytraceData->m_texels[(i)*3+0] = 255;
m_raytraceData->m_texels[(i)*3+1] = 0;
m_raytraceData->m_texels[(i)*3+2] = 0;
} else
{
m_raytraceData->m_texels[(i)*3+0] = 0;
m_raytraceData->m_texels[(i)*3+1] = 0;
m_raytraceData->m_texels[(i)*3+2] = 0;
}
}
}
GLint err;
err = glGetError();

View File

@@ -8,9 +8,13 @@ class GpuConvexScene : public GpuRigidBodyDemo
protected:
class GLPrimitiveRenderer* m_primRenderer;
class b3GpuRaycast* m_raycaster;
public:
GpuConvexScene() :m_primRenderer(0) {}
GpuConvexScene() :m_primRenderer(0), m_raycaster(0)
{
}
virtual ~GpuConvexScene(){}
virtual const char* getName()
{
@@ -25,6 +29,8 @@ public:
virtual void setupScene(const ConstructionInfo& ci);
virtual void destroyScene();
virtual int createDynamicsObjects(const ConstructionInfo& ci);
virtual int createDynamicsObjects2(const ConstructionInfo& ci,const float* vertices, int numVertices, const int* indices,int numIndices);