thecplusplusguy

bulletphysics tutorial 3 - collision callback

Oct 7th, 2012
1,911
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //http://www.youtube.com/user/thecplusplusguy
  2. //bullet physics tutorial 3, collision callback
  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.  
  295.     for(int i=0;i<bodies.size();i++)
  296.     {
  297.         if(bodies[i]->body->getCollisionShape()->getShapeType()==STATIC_PLANE_PROXYTYPE)
  298.             renderPlane(bodies[i]);
  299.         else if(bodies[i]->body->getCollisionShape()->getShapeType()==SPHERE_SHAPE_PROXYTYPE)
  300.             renderSphere(bodies[i]);
  301.         else if(bodies[i]->body->getCollisionShape()->getShapeType()==CYLINDER_SHAPE_PROXYTYPE)
  302.             renderCylinder(bodies[i]);
  303.         else if(bodies[i]->body->getCollisionShape()->getShapeType()==CONE_SHAPE_PROXYTYPE)
  304.             renderCone(bodies[i]);
  305.         else if(bodies[i]->body->getCollisionShape()->getShapeType()==BOX_SHAPE_PROXYTYPE)
  306.             renderBox(bodies[i]);
  307.     }
  308. }
  309.  
  310. bool callbackFunc(btManifoldPoint& cp,const btCollisionObject* obj1,int id1,int index1,const btCollisionObject* obj2,int id2,int index2)
  311. {
  312.     ((bulletObject*)obj1->getUserPointer())->hit=true;
  313.    
  314.     ((bulletObject*)obj2->getUserPointer())->hit=true;
  315.     return false;
  316. }
  317.  
  318. int main()
  319. {
  320.     SDL_Init(SDL_INIT_EVERYTHING);
  321.     SDL_SetVideoMode(640,480,32,SDL_OPENGL);
  322.     Uint32 start;
  323.     SDL_Event event;
  324.     bool running=true;
  325.     float angle=50;
  326.     init(angle);
  327.     gContactAddedCallback=callbackFunc;
  328.     addCylinder(2,5,0,30,0,1.0);
  329.     addCone(2,5,5,30,0,1.0);
  330.     addBox(10,2,3,0,40,0,1.0);
  331.     while(running)
  332.     {
  333.         start=SDL_GetTicks();
  334.         while(SDL_PollEvent(&event))
  335.         {
  336.             switch(event.type)
  337.             {
  338.                 case SDL_QUIT:
  339.                     running=false;
  340.                     break;
  341.                 case SDL_KEYDOWN:
  342.                     switch(event.key.keysym.sym)
  343.                     {
  344.                         case SDLK_ESCAPE:
  345.                             running=false;
  346.                             break;
  347.                         case SDLK_y:
  348.                             cam.mouseIn(false);
  349.                             break;
  350.                         case SDLK_SPACE:
  351.                             btRigidBody* sphere=addSphere(1.0,cam.getLocation().x,cam.getLocation().y,cam.getLocation().z,1.0);
  352.                             vector3d look=cam.getVector()*20;
  353.                             sphere->setLinearVelocity(btVector3(look.x,look.y,look.z));
  354.                             sphere->setCollisionFlags(sphere->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
  355.                             break;
  356.                     }
  357.                     break;
  358.                 case SDL_KEYUP:
  359.                     switch(event.key.keysym.sym)
  360.                     {
  361.                    
  362.                     }
  363.                     break;         
  364.                 case SDL_MOUSEBUTTONDOWN:
  365.                     cam.mouseIn(true);
  366.                     break;
  367.                    
  368.             }
  369.         }
  370.         for(int i=0;i<bodies.size();i++)
  371.             bodies[i]->hit=false;
  372.         world->stepSimulation(1/60.0);
  373.         display();
  374.         SDL_GL_SwapBuffers();
  375.         if(1000.0/60>SDL_GetTicks()-start)
  376.             SDL_Delay(1000.0/60-(SDL_GetTicks()-start));
  377.     }
  378.     //killskybox();
  379.     for(int i=0;i<bodies.size();i++)
  380.     {
  381.         world->removeCollisionObject(bodies[i]->body);
  382.         btMotionState* motionState=bodies[i]->body->getMotionState();
  383.         btCollisionShape* shape=bodies[i]->body->getCollisionShape();
  384.         delete bodies[i]->body;
  385.         delete shape;
  386.         delete motionState;
  387.         delete bodies[i];
  388.     }
  389.     delete dispatcher;
  390.     delete collisionConfig;
  391.     delete solver;
  392.     delete broadphase;
  393.     delete world;
  394.     SDL_Quit();
  395.     gluDeleteQuadric(quad);
  396. }
RAW Paste Data