Advertisement
thecplusplusguy

bulletphysics tutorial 4 - raytracing

Oct 7th, 2012
1,376
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.14 KB | None | 0 0
  1. //http://www.youtube.com/user/thecplusplusguy
  2. //bullet physics tutorial 4, raytracing
  3. #include <iostream>
  4. #include <SDL/SDL.h>
  5. #include <GL/gl.h>
  6. #include <GL/glu.h>
  7. #include "camera.h"
  8. #include <vector>
  9. #include <bullet/btBulletDynamicsCommon.h>
  10.  
  11. struct bulletObject{
  12.     int id;
  13.     float r,g,b;
  14.     bool hit;
  15.     btRigidBody* body;
  16.     bulletObject(btRigidBody* b,int i,float r0,float g0,float b0) : body(b),id(i),r(r0),g(g0),b(b0),hit(false) {}
  17. };
  18.  
  19. camera cam;
  20. GLUquadricObj* quad;
  21. btDynamicsWorld* world;
  22. btDispatcher* dispatcher;
  23. btCollisionConfiguration* collisionConfig;
  24. btBroadphaseInterface* broadphase;
  25. btConstraintSolver* solver;
  26. std::vector<bulletObject*> bodies;
  27.  
  28.  
  29.  
  30. btRigidBody* addSphere(float rad,float x,float y,float z,float mass)
  31. {
  32.     btTransform t;
  33.     t.setIdentity();
  34.     t.setOrigin(btVector3(x,y,z));
  35.     btSphereShape* sphere=new btSphereShape(rad);
  36.     btVector3 inertia(0,0,0);
  37.     if(mass!=0.0)
  38.         sphere->calculateLocalInertia(mass,inertia);
  39.    
  40.     btMotionState* motion=new btDefaultMotionState(t);
  41.     btRigidBody::btRigidBodyConstructionInfo info(mass,motion,sphere,inertia);
  42.     btRigidBody* body=new btRigidBody(info);
  43.     world->addRigidBody(body);
  44.     bodies.push_back(new bulletObject(body,0,1.0,0.0,0.0));
  45.     body->setUserPointer(bodies[bodies.size()-1]);
  46.     return body;
  47. }
  48.  
  49. void renderSphere(bulletObject* bobj)
  50. {
  51.     btRigidBody* sphere=bobj->body;
  52.     if(sphere->getCollisionShape()->getShapeType()!=SPHERE_SHAPE_PROXYTYPE)
  53.         return;
  54.     if(!bobj->hit)
  55.         glColor3f(bobj->r,bobj->g,bobj->b);
  56.     else
  57.         glColor3f(1,0,0);
  58.        
  59.     float r=((btSphereShape*)sphere->getCollisionShape())->getRadius();
  60.     btTransform t;
  61.     sphere->getMotionState()->getWorldTransform(t);
  62.     float mat[16];
  63.     t.getOpenGLMatrix(mat);
  64.     glPushMatrix();
  65.         glMultMatrixf(mat); //translation,rotation
  66.         gluSphere(quad,r,20,20);
  67.     glPopMatrix();
  68. }
  69.  
  70. btRigidBody* addCylinder(float d,float h,float x,float y,float z,float mass)
  71. {
  72.     btTransform t;
  73.     t.setIdentity();
  74.     t.setOrigin(btVector3(x,y,z));
  75.     btCylinderShape* sphere=new btCylinderShape(btVector3(d/2.0,h/2.0,d/2.0));
  76.     btVector3 inertia(0,0,0);
  77.     if(mass!=0.0)
  78.         sphere->calculateLocalInertia(mass,inertia);
  79.    
  80.     btMotionState* motion=new btDefaultMotionState(t);
  81.     btRigidBody::btRigidBodyConstructionInfo info(mass,motion,sphere,inertia);
  82.     btRigidBody* body=new btRigidBody(info);
  83.     world->addRigidBody(body);
  84.     bodies.push_back(new bulletObject(body,1,0.0,1.0,0.0));
  85.     body->setUserPointer(bodies[bodies.size()-1]);
  86.     return body;
  87. }
  88.  
  89. void renderCylinder(bulletObject* bobj)
  90. {
  91.     btRigidBody* sphere=bobj->body;
  92.     if(sphere->getCollisionShape()->getShapeType()!=CYLINDER_SHAPE_PROXYTYPE)
  93.         return;
  94.     if(!bobj->hit)
  95.         glColor3f(bobj->r,bobj->g,bobj->b);
  96.     else
  97.         glColor3f(1,0,0);
  98.     btVector3 extent=((btCylinderShape*)sphere->getCollisionShape())->getHalfExtentsWithoutMargin();
  99.     btTransform t;
  100.     sphere->getMotionState()->getWorldTransform(t);
  101.     float mat[16];
  102.     t.getOpenGLMatrix(mat);
  103.     glPushMatrix();
  104.         glMultMatrixf(mat); //translation,rotation
  105.         glTranslatef(0,extent.y(),0);
  106.         glRotatef(90,1,0,0);
  107.         gluCylinder(quad,extent.x(),extent.x(),extent.y()*2.0,20,20);
  108.     glPopMatrix();
  109. }
  110.  
  111. btRigidBody* addCone(float d,float h,float x,float y,float z,float mass)
  112. {
  113.     btTransform t;
  114.     t.setIdentity();
  115.     t.setOrigin(btVector3(x,y,z));
  116.     btConeShape* sphere=new btConeShape(d,h);
  117.     btVector3 inertia(0,0,0);
  118.     if(mass!=0.0)
  119.         sphere->calculateLocalInertia(mass,inertia);
  120.    
  121.     btMotionState* motion=new btDefaultMotionState(t);
  122.     btRigidBody::btRigidBodyConstructionInfo info(mass,motion,sphere,inertia);
  123.     btRigidBody* body=new btRigidBody(info);
  124.     world->addRigidBody(body);
  125.     bodies.push_back(new bulletObject(body,2,1.0,0.0,1.0));
  126.     body->setUserPointer(bodies[bodies.size()-1]);
  127.     return body;
  128. }
  129.  
  130. void renderCone(bulletObject* bobj)
  131. {
  132.     btRigidBody* sphere=bobj->body;
  133.     if(sphere->getCollisionShape()->getShapeType()!=CONE_SHAPE_PROXYTYPE)
  134.         return;
  135.     if(!bobj->hit)
  136.         glColor3f(bobj->r,bobj->g,bobj->b);
  137.     else
  138.         glColor3f(1,0,0);
  139.     float r=((btConeShape*)sphere->getCollisionShape())->getRadius();
  140.     float h=((btConeShape*)sphere->getCollisionShape())->getHeight();
  141.     btTransform t;
  142.     sphere->getMotionState()->getWorldTransform(t);
  143.     float mat[16];
  144.     t.getOpenGLMatrix(mat);
  145.     glPushMatrix();
  146.         glMultMatrixf(mat); //translation,rotation
  147.         glTranslatef(0,h/2.0,0);
  148.         glRotatef(90,1,0,0);
  149.         gluCylinder(quad,0,r,h,20,20);
  150.     glPopMatrix();
  151. }
  152.  
  153. btRigidBody* addBox(float width,float height,float depth,float x,float y,float z,float mass)
  154. {
  155.     btTransform t;
  156.     t.setIdentity();
  157.     t.setOrigin(btVector3(x,y,z));
  158.     btBoxShape* sphere=new btBoxShape(btVector3(width/2.0,height/2.0,depth/2.0));
  159.     btVector3 inertia(0,0,0);
  160.     if(mass!=0.0)
  161.         sphere->calculateLocalInertia(mass,inertia);
  162.    
  163.     btMotionState* motion=new btDefaultMotionState(t);
  164.     btRigidBody::btRigidBodyConstructionInfo info(mass,motion,sphere,inertia);
  165.     btRigidBody* body=new btRigidBody(info);
  166.     world->addRigidBody(body);
  167.     bodies.push_back(new bulletObject(body,3,1.0,1.0,0.0));
  168.     body->setUserPointer(bodies[bodies.size()-1]);
  169.     return body;
  170. }
  171.  
  172. void renderBox(bulletObject* bobj)
  173. {
  174.     btRigidBody* sphere=bobj->body;
  175.     if(sphere->getCollisionShape()->getShapeType()!=BOX_SHAPE_PROXYTYPE)
  176.         return;
  177.     if(!bobj->hit)
  178.         glColor3f(bobj->r,bobj->g,bobj->b);
  179.     else
  180.         glColor3f(1,0,0);
  181.     btVector3 extent=((btBoxShape*)sphere->getCollisionShape())->getHalfExtentsWithoutMargin();
  182.     btTransform t;
  183.     sphere->getMotionState()->getWorldTransform(t);
  184.     float mat[16];
  185.     t.getOpenGLMatrix(mat);
  186.     glPushMatrix();
  187.         glMultMatrixf(mat); //translation,rotation
  188.         glBegin(GL_QUADS);
  189.             glVertex3f(-extent.x(),extent.y(),-extent.z());
  190.             glVertex3f(-extent.x(),-extent.y(),-extent.z());
  191.             glVertex3f(-extent.x(),-extent.y(),extent.z());
  192.             glVertex3f(-extent.x(),extent.y(),extent.z());     
  193.         glEnd();
  194.         glBegin(GL_QUADS);
  195.             glVertex3f(extent.x(),extent.y(),-extent.z());
  196.             glVertex3f(extent.x(),-extent.y(),-extent.z());
  197.             glVertex3f(extent.x(),-extent.y(),extent.z());
  198.             glVertex3f(extent.x(),extent.y(),extent.z());      
  199.         glEnd();
  200.         glBegin(GL_QUADS);
  201.             glVertex3f(-extent.x(),extent.y(),extent.z());
  202.             glVertex3f(-extent.x(),-extent.y(),extent.z());
  203.             glVertex3f(extent.x(),-extent.y(),extent.z());
  204.             glVertex3f(extent.x(),extent.y(),extent.z());      
  205.         glEnd();
  206.         glBegin(GL_QUADS);
  207.             glVertex3f(-extent.x(),extent.y(),-extent.z());
  208.             glVertex3f(-extent.x(),-extent.y(),-extent.z());
  209.             glVertex3f(extent.x(),-extent.y(),-extent.z());
  210.             glVertex3f(extent.x(),extent.y(),-extent.z());     
  211.         glEnd();
  212.         glBegin(GL_QUADS);
  213.             glVertex3f(-extent.x(),extent.y(),-extent.z());
  214.             glVertex3f(-extent.x(),extent.y(),extent.z());
  215.             glVertex3f(extent.x(),extent.y(),extent.z());
  216.             glVertex3f(extent.x(),extent.y(),-extent.z());     
  217.         glEnd();
  218.         glBegin(GL_QUADS);
  219.             glVertex3f(-extent.x(),-extent.y(),-extent.z());
  220.             glVertex3f(-extent.x(),-extent.y(),extent.z());
  221.             glVertex3f(extent.x(),-extent.y(),extent.z());
  222.             glVertex3f(extent.x(),-extent.y(),-extent.z());    
  223.         glEnd();       
  224.     glPopMatrix();
  225. }
  226.  
  227. void renderPlane(bulletObject* bobj)
  228. {
  229.     btRigidBody* plane=bobj->body;
  230.     if(plane->getCollisionShape()->getShapeType()!=STATIC_PLANE_PROXYTYPE)
  231.         return;
  232.     if(!bobj->hit)
  233.         glColor3f(bobj->r,bobj->g,bobj->b);
  234.     else
  235.         glColor3f(1,0,0);
  236.     btTransform t;
  237.     plane->getMotionState()->getWorldTransform(t);
  238.     float mat[16];
  239.     t.getOpenGLMatrix(mat);
  240.     glPushMatrix();
  241.         glMultMatrixf(mat); //translation,rotation
  242.         glBegin(GL_QUADS);
  243.             glVertex3f(-1000,0,1000);
  244.             glVertex3f(-1000,0,-1000);
  245.             glVertex3f(1000,0,-1000);
  246.             glVertex3f(1000,0,1000);
  247.         glEnd();
  248.     glPopMatrix();
  249. }
  250.  
  251.  
  252. void init(float angle)
  253. {
  254.     collisionConfig=new btDefaultCollisionConfiguration();
  255.     dispatcher=new btCollisionDispatcher(collisionConfig);
  256.     broadphase=new btDbvtBroadphase();
  257.     solver=new btSequentialImpulseConstraintSolver();
  258.     world=new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfig);
  259.     world->setGravity(btVector3(0,-10,0));
  260.    
  261.     btTransform t;
  262.     t.setIdentity();
  263.     t.setOrigin(btVector3(0,0,0));
  264.     btStaticPlaneShape* plane=new btStaticPlaneShape(btVector3(0,1,0),0);
  265.     btMotionState* motion=new btDefaultMotionState(t);
  266.     btRigidBody::btRigidBodyConstructionInfo info(0.0,motion,plane);
  267.     btRigidBody* body=new btRigidBody(info);
  268.     world->addRigidBody(body);
  269.     bodies.push_back(new bulletObject(body,4,0.8,0.8,0.8));
  270.     body->setUserPointer(bodies[bodies.size()-1]);
  271.    
  272.     addSphere(1.0,0,20,0,1.0);
  273.    
  274.     glClearColor(0,0,0,1);
  275.     glMatrixMode(GL_PROJECTION);
  276.         glLoadIdentity();
  277.         gluPerspective(angle,640.0/480.0,1,1000);
  278.     glMatrixMode(GL_MODELVIEW);
  279.     quad=gluNewQuadric();
  280.     //initskybox();
  281.     glEnable(GL_DEPTH_TEST);
  282.     cam.setLocation(vector3d(10,10,10));    //the player will be top of the terrain
  283. }
  284.  
  285.  
  286. void display()
  287. {
  288.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  289.     glLoadIdentity();
  290.     cam.Control();
  291.     //drawSkybox(50);
  292.     cam.UpdateCamera();
  293.  
  294.     vector3d direction=cam.getVector()*10000;
  295.     btCollisionWorld::AllHitsRayResultCallback rayCallback(btVector3(cam.getLocation().x,cam.getLocation().y,cam.getLocation().z),btVector3(direction.x,direction.y,direction.z));
  296.     world->rayTest(btVector3(cam.getLocation().x,cam.getLocation().y,cam.getLocation().z),btVector3(direction.x,direction.y,direction.z),rayCallback);
  297.     if(rayCallback.hasHit())
  298.     {
  299.         for(int i=0;i<rayCallback.m_collisionObjects.size();i++)
  300.         {
  301.             ((bulletObject*)(rayCallback.m_collisionObjects[i]->getUserPointer()))->hit=true;
  302.             std::cout << rayCallback.m_hitFractions[i] << std::endl;
  303.         }
  304.     }
  305.  
  306.     for(int i=0;i<bodies.size();i++)
  307.     {
  308.         if(bodies[i]->body->getCollisionShape()->getShapeType()==STATIC_PLANE_PROXYTYPE)
  309.             renderPlane(bodies[i]);
  310.         else if(bodies[i]->body->getCollisionShape()->getShapeType()==SPHERE_SHAPE_PROXYTYPE)
  311.             renderSphere(bodies[i]);
  312.         else if(bodies[i]->body->getCollisionShape()->getShapeType()==CYLINDER_SHAPE_PROXYTYPE)
  313.             renderCylinder(bodies[i]);
  314.         else if(bodies[i]->body->getCollisionShape()->getShapeType()==CONE_SHAPE_PROXYTYPE)
  315.             renderCone(bodies[i]);
  316.         else if(bodies[i]->body->getCollisionShape()->getShapeType()==BOX_SHAPE_PROXYTYPE)
  317.             renderBox(bodies[i]);
  318.     }
  319. }
  320.  
  321. bool callbackFunc(btManifoldPoint& cp,const btCollisionObject* obj1,int id1,int index1,const btCollisionObject* obj2,int id2,int index2)
  322. {
  323.     ((bulletObject*)obj1->getUserPointer())->hit=true;
  324.    
  325.     ((bulletObject*)obj2->getUserPointer())->hit=true;
  326.     return false;
  327. }
  328.  
  329. int main()
  330. {
  331.     SDL_Init(SDL_INIT_EVERYTHING);
  332.     SDL_SetVideoMode(640,480,32,SDL_OPENGL);
  333.     Uint32 start;
  334.     SDL_Event event;
  335.     bool running=true;
  336.     float angle=50;
  337.     init(angle);
  338.     gContactAddedCallback=callbackFunc;
  339.     addCylinder(2,5,0,30,0,1.0);
  340.     addCone(2,5,5,30,0,1.0);
  341.     addBox(10,2,3,0,40,0,1.0);
  342.     while(running)
  343.     {
  344.         start=SDL_GetTicks();
  345.         while(SDL_PollEvent(&event))
  346.         {
  347.             switch(event.type)
  348.             {
  349.                 case SDL_QUIT:
  350.                     running=false;
  351.                     break;
  352.                 case SDL_KEYDOWN:
  353.                     switch(event.key.keysym.sym)
  354.                     {
  355.                         case SDLK_ESCAPE:
  356.                             running=false;
  357.                             break;
  358.                         case SDLK_y:
  359.                             cam.mouseIn(false);
  360.                             break;
  361.                         case SDLK_SPACE:
  362.                             btRigidBody* sphere=addSphere(1.0,cam.getLocation().x,cam.getLocation().y,cam.getLocation().z,1.0);
  363.                             vector3d look=cam.getVector()*20;
  364.                             sphere->setLinearVelocity(btVector3(look.x,look.y,look.z));
  365.                             sphere->setCollisionFlags(sphere->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
  366.                             break;
  367.                     }
  368.                     break;
  369.                 case SDL_KEYUP:
  370.                     switch(event.key.keysym.sym)
  371.                     {
  372.                    
  373.                     }
  374.                     break;         
  375.                 case SDL_MOUSEBUTTONDOWN:
  376.                     cam.mouseIn(true);
  377.                     break;
  378.                    
  379.             }
  380.         }
  381.         for(int i=0;i<bodies.size();i++)
  382.             bodies[i]->hit=false;
  383.         world->stepSimulation(1/60.0);
  384.         display();
  385.         SDL_GL_SwapBuffers();
  386.         if(1000.0/60>SDL_GetTicks()-start)
  387.             SDL_Delay(1000.0/60-(SDL_GetTicks()-start));
  388.     }
  389.     //killskybox();
  390.     for(int i=0;i<bodies.size();i++)
  391.     {
  392.         world->removeCollisionObject(bodies[i]->body);
  393.         btMotionState* motionState=bodies[i]->body->getMotionState();
  394.         btCollisionShape* shape=bodies[i]->body->getCollisionShape();
  395.         delete bodies[i]->body;
  396.         delete shape;
  397.         delete motionState;
  398.         delete bodies[i];
  399.     }
  400.     delete dispatcher;
  401.     delete collisionConfig;
  402.     delete solver;
  403.     delete broadphase;
  404.     delete world;
  405.     SDL_Quit();
  406.     gluDeleteQuadric(quad);
  407. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement