/* * Copyright (c) 2005 Erwin Coumans * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies. * Erwin Coumans makes no representations about the suitability * of this software for any purpose. * It is provided "as is" without express or implied warranty. */ /* Raytracer uses the Convex rayCast to visualize the Collision Shapes/Minkowski Sum. Very basic raytracer, rendering into a texture. */ ///Low level demo, doesn't include btBulletCollisionCommon.h #include "GL_Simplex1to4.h" #include "LinearMath/btQuaternion.h" #include "LinearMath/btTransform.h" #include "GL_ShapeDrawer.h" #include "GLDebugDrawer.h" #include "Raytracer.h" #include "GlutStuff.h" #include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" #include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h" #include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h" #ifdef USE_ALGEBRAIC_CCD #include "NarrowPhaseCollision/BU_CollisionPair.h" #endif //USE_ALGEBRAIC_CCD #include "BulletCollision/CollisionShapes/btSphereShape.h" #include "BulletCollision/CollisionShapes/btMultiSphereShape.h" #include "BulletCollision/CollisionShapes/btConvexHullShape.h" #include "LinearMath/btAabbUtil2.h" #include "BulletCollision/CollisionShapes/btBoxShape.h" #include "BulletCollision/CollisionShapes/btTetrahedronShape.h" #include "BulletCollision/CollisionShapes/btConeShape.h" #include "BulletCollision/CollisionShapes/btCylinderShape.h" #include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" #include "RenderTexture.h" btVoronoiSimplexSolver simplexSolver; float yaw=0.f,pitch=0.f,roll=0.f; const int maxNumObjects = 4; const int numObjects = 1; /// simplex contains the vertices, and some extra code to draw and debug GL_Simplex1to4 simplex; btConvexShape* shapePtr[maxNumObjects]; btTransform transforms[maxNumObjects]; renderTexture* raytracePicture = 0; //this applies to the raytracer virtual screen/image buffer int screenWidth = 128; //float aspectRatio = (3.f/4.f); int screenHeight = 128;//screenWidth * aspectRatio; GLuint glTextureId; btSphereShape mySphere(1); btBoxShape myBox(btVector3(0.4f,0.4f,0.4f)); btCylinderShape myCylinder(btVector3(0.3f,0.3f,0.3f)); btConeShape myCone(1,1); btMinkowskiSumShape myMink(&myCylinder,&myBox); GLDebugDrawer debugDrawer; /// /// /// int main(int argc,char** argv) { Raytracer* raytraceDemo = new Raytracer(); raytraceDemo->initPhysics(); raytraceDemo->setCameraDistance(6.f); return glutmain(argc, argv,640,640,"Bullet GJK Implicit Shape Raytracer Demo",raytraceDemo); } void Raytracer::initPhysics() { raytracePicture = new renderTexture(screenWidth,screenHeight); myBox.setMargin(0.02f); myCone.setMargin(0.2f); simplex.setSimplexSolver(&simplexSolver); simplex.addVertex(btPoint3(-1,0,-1)); simplex.addVertex(btPoint3(1,0,-1)); simplex.addVertex(btPoint3(0,0,1)); simplex.addVertex(btPoint3(0,1,0)); /// convex hull of 5 spheres #define NUM_SPHERES 5 btVector3 inertiaHalfExtents(10.f,10.f,10.f); btVector3 positions[NUM_SPHERES] = { btVector3(-1.2f, -0.3f, 0.f), btVector3(0.8f, -0.3f, 0.f), btVector3(0.5f, 0.6f, 0.f), btVector3(-0.5f, 0.6f, 0.f), btVector3(0.f, 0.f, 0.f) }; //btMultiSphereShape* multiSphereShape = new btMultiSphereShape(inertiaHalfExtents,positions,radi,NUM_SPHERES); btVector3 sphereOffset(0,0,0); btScalar sphereRadius = 2.f; btVector3 nonUniformScaling(0.5,2,0.5); btMultiSphereShape* nonuniformScaledSphere = new btMultiSphereShape(inertiaHalfExtents,&sphereOffset,&sphereRadius,1); nonuniformScaledSphere->setLocalScaling(nonUniformScaling); nonuniformScaledSphere->setMargin(0.04); btConvexHullShape* convexHullShape = new btConvexHullShape(&positions[0].getX(),3); //choose shape shapePtr[0] = &myCone;//&myBox;//nonuniformScaledSphere;//&myCone; shapePtr[1] =&simplex; shapePtr[2] =convexHullShape; shapePtr[3] =&myMink;//myBox;//multiSphereShape simplex.setMargin(0.3f); } //to be implemented by the demo void Raytracer::clientMoveAndDisplay() { displayCallback(); } int once = 1; void Raytracer::displayCallback() { updateCamera(); for (int i=0;isetPixel(x,y,rgba); } } btConvexCast::CastResult rayResult; btTransform rayToTrans; rayToTrans.setIdentity(); btVector3 rayTo; for (x=0;xgetAabb(transforms[s],aabbMin,aabbMax); btScalar hitLambda = 1.f; btVector3 hitNormal; if (btRayAabb(rayFrom,rayTo,aabbMin,aabbMax,hitLambda,hitNormal)) { //choose the continuous collision detection method btSubsimplexConvexCast convexCaster(&pointShape,shapePtr[s],&simplexSolver); //GjkConvexCast convexCaster(&pointShape,shapePtr[0],&simplexSolver); //ContinuousConvexCollision convexCaster(&pointShape,shapePtr[0],&simplexSolver,0); //reset previous result rayResult.m_fraction = 1.f; if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,transforms[s],transforms[s],rayResult)) { //float fog = 1.f - 0.1f * rayResult.m_fraction; rayResult.m_normal.normalize(); btVector3 worldNormal; worldNormal = transforms[s].getBasis() *rayResult.m_normal; float lightVec0 = worldNormal.dot(btVector3(0,-1,-1));//0.4f,-1.f,-0.4f)); float lightVec1= worldNormal.dot(btVector3(-1,0,-1));//-0.4f,-1.f,-0.4f)); rgba = btVector4(lightVec0,lightVec1,0,1.f); rgba.setMin(btVector3(1,1,1)); rgba.setMax(btVector3(0.2,0.2,0.2)); rgba[3] = 1.f; raytracePicture->setPixel(x,y,rgba); } else { //clear is already done //rgba = btVector4(0.f,0.f,0.f,0.f); //raytracePicture->setPixel(x,y,rgba); } } else { btVector4 rgba = raytracePicture->getPixel(x,y); if (!rgba.length2()) { raytracePicture->setPixel(x,y,btVector4(1,1,1,1)); } } } } } #define TEST_PRINTF #ifdef TEST_PRINTF extern BMF_FontData BMF_font_helv10; raytracePicture->grapicalPrintf("CCD RAYTRACER",&BMF_font_helv10); char buffer[256]; sprintf(buffer,"%d RAYS / Frame",screenWidth*screenHeight*numObjects); raytracePicture->grapicalPrintf(buffer,&BMF_font_helv10,0,10); #endif //TEST_PRINTF glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glFrustum(-1.0,1.0,-1.0,1.0,3,2020.0); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); // reset The Modelview Matrix glTranslatef(0.0f,0.0f,-3.0f); // Move Into The Screen 5 Units glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,glTextureId ); const unsigned char *ptr = raytracePicture->getBuffer(); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, raytracePicture->getWidth(),raytracePicture->getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, ptr); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f (1,1,1,1); // alpha=0.5=half visible glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex2f(-1,1); glTexCoord2f(1.0f, 0.0f); glVertex2f(1,1); glTexCoord2f(1.0f, 1.0f); glVertex2f(1,-1); glTexCoord2f(0.0f, 1.0f); glVertex2f(-1,-1); glEnd(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); #endif //RAYRACER glDisable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); GL_ShapeDrawer::drawCoordSystem(); { for (int i=0;igetAabb(transforms[i],aabbMin,aabbMax); debugDrawer.setDebugMode(1); debugDrawer.drawAabb(aabbMin,aabbMax,btVector3(255,0,0)); } } glPushMatrix(); /* /// normal opengl rendering float m[16]; int i; for (i=0;i