Advertisement
thecplusplusguy

Box2D tutorial 4 - joints

Sep 28th, 2012
961
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.98 KB | None | 0 0
  1. //http://www.youtube.com/user/thecplusplusguy
  2. //Box2D joints example (revolute joint and wheel joint)
  3. #include <iostream>
  4. #include <SDL/SDL.h>
  5. #include <SDL/SDL_image.h>
  6. #include <GL/gl.h>
  7. #include <GL/glu.h>
  8. #include <Box2D/Box2D.h>
  9.  
  10. const int WIDTH=640;
  11. const int HEIGHT=480;
  12. const float M2P=20;
  13. const float P2M=1/M2P;
  14. b2World* world;
  15.  
  16.  
  17. int ground=0;
  18.  
  19. b2Body* addRect(int x,int y,int w,int h,bool dyn=true)
  20. {
  21.     b2BodyDef bodydef;
  22.     bodydef.position.Set(x*P2M,y*P2M);
  23.     if(dyn)
  24.         bodydef.type=b2_dynamicBody;
  25.     b2Body* body=world->CreateBody(&bodydef);
  26.    
  27.     b2PolygonShape shape;
  28.     shape.SetAsBox(P2M*w/2,P2M*h/2);
  29.    
  30.     b2FixtureDef fixturedef;
  31.     fixturedef.shape=&shape;
  32.     fixturedef.density=1.0;
  33.     body->CreateFixture(&fixturedef);
  34.     body->SetUserData(&ground);
  35.     return body;
  36. }
  37.  
  38. b2Body* addCircle(int x,int y,int r,bool dyn=true)
  39. {
  40.     b2BodyDef bodydef;
  41.     bodydef.position.Set(x*P2M,y*P2M);
  42.     if(dyn)
  43.         bodydef.type=b2_dynamicBody;
  44.     b2Body* body=world->CreateBody(&bodydef);
  45.    
  46.     b2CircleShape shape;
  47.     shape.m_radius=r*P2M;
  48.     shape.m_p.Set(0,0);
  49.    
  50.     b2FixtureDef fixturedef;
  51.     fixturedef.shape=&shape;
  52.     fixturedef.density=1.0;
  53.     fixturedef.friction=0.8;
  54.     body->CreateFixture(&fixturedef);
  55.     body->SetUserData(&ground);
  56.     return body;
  57. }
  58.  
  59. void drawCircle(b2Vec2 center,float r,float angle)
  60. {
  61.     const int PRECISION=30;
  62.     glColor3f(1,1,1);
  63.     glPushMatrix();
  64.         glTranslatef(center.x*M2P,center.y*M2P,0);
  65.         glRotatef(angle*180.0/M_PI,0,0,1);
  66.         glBegin(GL_TRIANGLE_FAN);
  67.             glVertex2f(0,0);
  68.             for(float i=0.0;i<=360;i+=360.0/PRECISION)
  69.             {
  70.                 if(i<50)
  71.                     glColor3f(1,0,0);
  72.                 else
  73.                     glColor3f(1,1,1);
  74.                 glVertex2f((cos(i*M_PI/180.0)*r)*M2P,(sin(i*M_PI/180.0)*r)*M2P);
  75.         }
  76.         glEnd();
  77.     glPopMatrix();
  78. }
  79.  
  80. void drawSquare(b2Vec2* points,b2Vec2 center,float angle)
  81. {
  82.     glColor3f(1,1,1);
  83.     glPushMatrix();
  84.         glTranslatef(center.x*M2P,center.y*M2P,0);
  85.         glRotatef(angle*180.0/M_PI,0,0,1);
  86.         glBegin(GL_QUADS);
  87.             for(int i=0;i<4;i++)
  88.                 glVertex2f(points[i].x*M2P,points[i].y*M2P);
  89.         glEnd();
  90.     glPopMatrix();
  91. }
  92.  
  93. b2Body* myRect;
  94. int num=6;
  95. void init()
  96. {
  97.     glMatrixMode(GL_PROJECTION);
  98.         glOrtho(0,WIDTH,HEIGHT,0,-1,1);
  99.     glMatrixMode(GL_MODELVIEW);
  100.     glClearColor(0,0,0,1);
  101.     world=new b2World(b2Vec2(0.0,9.81));
  102.     addRect(WIDTH/2,HEIGHT-50,WIDTH,30,false);
  103. }
  104.  
  105. void display()
  106. {
  107.     glClear(GL_COLOR_BUFFER_BIT);
  108.     glLoadIdentity();
  109.     int x,y;
  110.     SDL_GetMouseState(&x,&y);
  111.     b2Vec2 mouse(x,y);
  112.     //mouse-=(M2P*myRect->GetWorldCenter());
  113.     //myRect->ApplyForce(mouse,myRect->GetWorldCenter());
  114.     b2Body* tmp=world->GetBodyList();
  115.     b2Vec2 points[4];
  116.     while(tmp)
  117.     {
  118.         if(tmp->GetFixtureList()->GetShape()->GetType()==0)
  119.         {
  120.             b2CircleShape* c=((b2CircleShape*)tmp->GetFixtureList()->GetShape());
  121.             drawCircle(tmp->GetWorldCenter(),c->m_radius,tmp->GetAngle());
  122.         }else{
  123.             for(int i=0;i<4;i++)
  124.                 points[i]=((b2PolygonShape*)tmp->GetFixtureList()->GetShape())->GetVertex(i);
  125.             drawSquare(points,tmp->GetWorldCenter(),tmp->GetAngle());
  126.         }
  127.         tmp=tmp->GetNext();
  128.     }
  129. }
  130.  
  131. void createBridge(b2Body* sta1,b2Body* sta2,int w,int h)
  132. {
  133.     b2Vec2 pos1=M2P*(sta1->GetWorldCenter()+(((b2PolygonShape*)sta1->GetFixtureList()->GetShape())->GetVertex(1)));
  134.     b2Vec2 pos2=M2P*(sta2->GetWorldCenter()+(((b2PolygonShape*)sta2->GetFixtureList()->GetShape())->GetVertex(0)));
  135.     int num=(pos2.x-pos1.x)/w;
  136.     b2RevoluteJointDef jointDef;
  137.     jointDef.bodyA=sta1;
  138.     b2Body* prev,*cur;
  139.     prev=addRect(pos1.x+(w/2),pos1.y,w,h,true);
  140.     jointDef.bodyB=prev;
  141.     jointDef.localAnchorA.Set(((b2PolygonShape*)sta1->GetFixtureList()->GetShape())->GetVertex(1).x,0);
  142.     jointDef.localAnchorB.Set(-w/2*P2M,0);
  143.     world->CreateJoint(&jointDef);
  144.     for(int i=0;i<num-1;i++)
  145.     {
  146.         cur=addRect(pos1.x+i*w,pos1.y,w,h,true);
  147.         jointDef.bodyA=prev;
  148.         jointDef.bodyB=cur;
  149.         jointDef.localAnchorA.Set(w/2*P2M,0);
  150.         jointDef.localAnchorB.Set(-w/2*P2M,0);
  151.         world->CreateJoint(&jointDef);
  152.         prev=cur;  
  153.     }
  154.     jointDef.bodyA=prev;
  155.     jointDef.bodyB=sta2;
  156.     jointDef.localAnchorA.Set(w/2*P2M,0);
  157.     jointDef.localAnchorB.Set((((b2PolygonShape*)sta2->GetFixtureList()->GetShape())->GetVertex(0)).x,0);
  158.     world->CreateJoint(&jointDef); 
  159. }
  160.  
  161. b2WheelJoint* wheel;
  162.  
  163. void makeCar()
  164. {
  165.     b2Body* body=addRect(200,200,100,40);
  166.     b2Body* wheel1=addCircle(150,220,15);
  167.     b2Body* wheel2=addCircle(250,220,15);
  168.    
  169.     b2WheelJointDef jointDef;
  170.     jointDef.bodyA=body;
  171.     jointDef.bodyB=wheel1;
  172.     jointDef.localAnchorA.Set(-50*P2M,20*P2M);
  173.     jointDef.localAnchorB.Set(0,0);
  174.     jointDef.enableMotor=true;
  175.     jointDef.maxMotorTorque=100.0;
  176.     jointDef.dampingRatio=0.1;
  177.     wheel=(b2WheelJoint*)world->CreateJoint(&jointDef);
  178.    
  179.     jointDef.bodyA=body;
  180.     jointDef.bodyB=wheel2;
  181.     jointDef.localAnchorA.Set(50*P2M,20*P2M);
  182.     jointDef.localAnchorB.Set(0,0);
  183.     jointDef.enableMotor=false;
  184.     jointDef.maxMotorTorque=0.0;
  185.     world->CreateJoint(&jointDef);
  186. }
  187.  
  188. int main()
  189. {
  190.     SDL_Init(SDL_INIT_EVERYTHING);
  191.     SDL_SetVideoMode(640,480,32,SDL_OPENGL);
  192.     Uint32 start;
  193.     SDL_Event event;
  194.     bool running=true;
  195.     init();
  196.     b2Body* sta1=addRect(100,300,50,10,false);
  197.     b2Body* sta2=addRect(600,300,50,10,false);
  198.     createBridge(sta1,sta2,50,10);
  199.     makeCar();
  200.     while(running)
  201.     {
  202.         start=SDL_GetTicks();
  203.         while(SDL_PollEvent(&event))
  204.         {
  205.             switch(event.type)
  206.             {
  207.                 case SDL_QUIT:
  208.                     running=false;
  209.                     break;
  210.                 case SDL_KEYDOWN:
  211.                     switch(event.key.keysym.sym)
  212.                     {
  213.                         case SDLK_ESCAPE:
  214.                             running=false;
  215.                             break;
  216.                         case SDLK_SPACE:
  217.                             //myRect->ApplyLinearImpulse(b2Vec2(0,-40),myRect->GetWorldCenter()+b2Vec2(-25*P2M,-25*P2M));
  218.                             break;
  219.                     }
  220.                     break;
  221.                 case SDL_MOUSEBUTTONDOWN:
  222.                     //addRect(event.button.x,event.button.y,20,20,true);
  223.                     addCircle(event.button.x,event.button.y,15,true);
  224.                     break;
  225.                    
  226.             }
  227.         }
  228.         Uint8* keys=SDL_GetKeyState(0);
  229.         if(keys[SDLK_d])
  230.             wheel->SetMotorSpeed(50);
  231.         if(keys[SDLK_a])
  232.             wheel->SetMotorSpeed(-50);
  233.            
  234.         display();
  235.         world->Step(1.0/30.0,8,3);  //update
  236.         SDL_GL_SwapBuffers();
  237.         if(1000.0/30>SDL_GetTicks()-start)
  238.             SDL_Delay(1000.0/30-(SDL_GetTicks()-start));
  239.     }
  240.     SDL_Quit();
  241. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement