Advertisement
thecplusplusguy

bulletphysics tutorial 4 - soft body

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