News Mar 20: R.U.B.E v1.7 released. Instanciable objects!
Feb 21: Added RUBE sample loader for Cocos2d-X v3.4.
Feb 17: Funny Fists released in iOS App store and Google Play store. (YouTube video)
2014
May 25: R.U.B.E v1.6 released. Samplers!
May 12: "On-the-fly" resource updating for Cocos2d-x
Apr 22: New blog post: Inverted pendulum control
Apr 7: On-screen logging class for Cocos2d-x
Mar 22: Downhill Supreme 2 released for iOS and Android
Jan 2: YouTube video: Making soft-body wheels in RUBE
2013
Oct 6: Check out Supplyfront RTS, my 7dRTS entry continued.
Sep 26: R.U.B.E v1.5 released. Customizable item labels, snap-to-grid, export filtering, full-text help search.
Sep 18: Added RUBE sample loader for Cocos2d-X.
Sep 16: Updated RUBE sample loader for Cocos2d v2.
Aug 12: RUBE loader for Nape by Zeh Fernando
Aug 7: Added RUBE sample loader for SFML.
Jul 30: Try my MiniLD 7dRTS entry.
Jul 24: Added physics-driven particles tutorial.
Jul 20: New blog post: rendering solid ground (as in Downhill Supreme)
Jul 18: R.U.B.E v1.4 released. Command-line interface for batch jobs, hotkeys for scripts, better script management.
May 22: Downhill Supreme is out now! (iOS)
Apr 2: R.U.B.E v1.3 released. Collision bitplane editing, Cocos2d-iphone loader, usability improvements.
Mar 11: R.U.B.E v1.2 released. Now supports weld, friction, motor joints and automatic image reloading.
Mar 10: RUBE loader for libGDX by Tim Scott
Jan 28: New blog post: a functional combustion engine!
Jan 22: New blog post: wind tunnel
Jan 20: Added explosions tutorial.
Jan 16: Added buoyancy tutorial.
Jan 16: AndEngine sample project to load RUBE scene by Bart Hirst
Jan 14: R.U.B.E v1.1 released, now supports custom properties.
Jan 1: All basic tutorials are now available in Chinese at ohcoder.com Huge thankyou to @OhCoder!
2012
Dec 23: Discussion forums have been set up
Dec 4: R.U.B.E v1.0 is ready !
Dec 2: YouTube video: Box2D pendulum clock
Nov 26: New blog post: rocket platform thingy
Nov 25: Video of R.U.B.E scenes in Chipmunk.
Nov 23: A sample project to load R.U.B.E scenes into Chipmunk physics! Details here.
Nov 14: An XCode sample project to load R.U.B.E scenes on iOS is now available. Details here.
Nov 11: A Java version of b2dJson is now available, based on JBox2D.
Nov 6: A Javascript version of b2dJson based on box2dweb is now available. Demo here!
Nov 2: The full specification of the JSON format used by b2dJson can be found here: b2dJson file structure
Oct 28: YouTube video: 2-minute ragdoll in R.U.B.E Box2D editor
Sep 29: YouTube video: R.U.B.E Box2D editor usage example

Box2D C++ tutorials - Ray casting

Last edited: July 14 2013

Chinese version -> 中文

Ray casting


Ray casting is often used to find out what objects are in a certain part of the world. A ray is just a straight line, and we can use a function provided by Box2D to check if the line crosses a fixture. We can also find out what the normal is at the point the line hits the fixture.

Here is the function I'm talking about, which returns true if the ray hits the fixture. Notice it's a member of the b2Fixture class, which means we'll first need to have one of those to cast a ray against.
1
  bool b2Fixture::RayCast(b2RayCastOutput* output, const b2RayCastInput& input);
Now what are these input and output parameters. Well, straight from the source code here is what a b2RayCastInput contains:
1
2
3
4
5
6
  // Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
  struct b2RayCastInput
  {
      b2Vec2 p1, p2;
      float32 maxFraction;
  };
The points p1 and p2 are used to define a direction for the ray, and the maxFraction specifies how far along the ray should be checked for an intersection. The following image may make this clearer. A maxFraction of 1 simply means the segment from p1 to p2, which in this case would not intersect the shape, but a maxFraction of 2 would. Raycasting And here is what a b2RayCastOutput contains:
1
2
3
4
5
6
7
  // Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2
  // come from b2RayCastInput.
  struct b2RayCastOutput
  {
      b2Vec2 normal;
      float32 fraction;
  };
If the ray does intersect the shape, b2Fixture::RayCast will return true and we can look in the output struct to find the actual fraction of the intersect point, and the normal of the fixture 'surface' at that point: Raycasting

Example


To try out this very handy function, let's set up a scene with a fenced area and some shapes floating inside in a zero-gravity environment. By now you should be getting used to this one, so we'll make the walls as edges instead of boxes just to spice things up.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    FooTest() {
  
      //a static body
      b2BodyDef myBodyDef;
      myBodyDef.type = b2_staticBody;
      myBodyDef.position.Set(0, 0);
      b2Body* staticBody = m_world->CreateBody(&myBodyDef);
  
      //shape definition
      b2PolygonShape polygonShape;
    
      //fixture definition
      b2FixtureDef myFixtureDef;
      myFixtureDef.shape = &polygonShape;
      
      //add four walls to the static body
      b2Vec2 bl(-20, 0);
      b2Vec2 br( 20, 0);
      b2Vec2 tl(-20,40);
      b2Vec2 tr( 20,40);
      polygonShape.SetAsEdge( bl, br ); //ground
      staticBody->CreateFixture(&myFixtureDef);
      polygonShape.SetAsEdge( tl, tr);//ceiling
      staticBody->CreateFixture(&myFixtureDef);
      polygonShape.SetAsEdge( bl, tl );//left wall
      staticBody->CreateFixture(&myFixtureDef);
      polygonShape.SetAsEdge( br, tr );//right wall
      staticBody->CreateFixture(&myFixtureDef);
  
      myBodyDef.type = b2_dynamicBody;
      myBodyDef.position.Set(0,20);
      polygonShape.SetAsBox(2,2);
      myFixtureDef.density = 1;
      for (int i = 0; i < 5; i++)
          m_world->CreateBody(&myBodyDef)->CreateFixture(&myFixtureDef);
  
      //circles
      b2CircleShape circleShape;
      circleShape.m_radius = 2;
      myFixtureDef.shape = &circleShape;
      for (int i = 0; i < 5; i++)
          m_world->CreateBody(&myBodyDef)->CreateFixture(&myFixtureDef);
  
      //turn gravity off
      m_world->SetGravity( b2Vec2(0,0) );
  
    }
Raycasting Now we need a ray to cast against these shapes. Let's make a ray starting from the center of the screen and going outward, and rotating slowly around. The only state we need to keep for this is the current angle, so instead of making a special class for it, we'll just keep a variable at global scope.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  //at global scope
  float currentRayAngle = 0;
  
  //in Step() function
  currentRayAngle += 360 / 20.0 / 60.0 * DEGTORAD; //one revolution every 20 seconds
  
  //calculate points of ray
  float rayLength = 25; //long enough to hit the walls
  b2Vec2 p1( 0, 20 ); //center of scene
  b2Vec2 p2 = p1 + rayLength * b2Vec2( sinf(currentRayAngle), cosf(currentRayAngle) );
  
  //draw a line
  glColor3f(1,1,1); //white
  glBegin(GL_LINES);
  glVertex2f( p1.x, p1.y );
  glVertex2f( p2.x, p2.y );
  glEnd();
Raycasting You should now see a white line circling the scene. Now we just need to use the RayCast function to get the distance to the closest intersected shape, and draw the line at that length. We will check every fixture of every shape, which is not the best way to do this, but will do as an example (see the world querying topic for a more efficient method). It also means we can take a look at how you can iterate over the contents of the world:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  //in Step() function, continuing on from section above
  
      //set up input
      b2RayCastInput input;
      input.p1 = p1;
      input.p2 = p2;
      input.maxFraction = 1;
  
      //check every fixture of every body to find closest
      float closestFraction = 1; //start with end of line as p2
      b2Vec2 intersectionNormal(0,0);
      for (b2Body* b = m_world->GetBodyList(); b; b = b->GetNext()) {
          for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext()) {
  
              b2RayCastOutput output;
              if ( ! f->RayCast( &output, input ) )
                  continue;
              if ( output.fraction < closestFraction ) {
                  closestFraction = output.fraction;
                  intersectionNormal = output.normal;
              }            
          }
      }
  
      b2Vec2 intersectionPoint = p1 + closestFraction * (p2 - p1);
  
      //draw a line
      glColor3f(1,1,1); //white
      glBegin(GL_LINES);
      glVertex2f( p1.x, p1.y );
      glVertex2f( intersectionPoint.x, intersectionPoint.y );
      glEnd();
      
      //draw a point at the intersection point
      glPointSize(5);
      glBegin(GL_POINTS);
      glVertex2f( intersectionPoint.x, intersectionPoint.y );
      glEnd();
You might notice that now we are drawing two lines on top of each other... for clarity, delete the first one and you should get this result: Raycasting Well that's about all there is to finding the intersection point. We can use the normal in the output struct for some interesting stuff though, so let's try it out. First, we'll simply render the normal to see what it looks like:
1
2
3
4
5
6
7
      //draw intersection normal
      b2Vec2 normalEnd = intersectionPoint + intersectionNormal;
      glColor3f(0,1,0); //green
      glBegin(GL_LINES);
      glVertex2f( intersectionPoint.x, intersectionPoint.y );
      glVertex2f( normalEnd.x, normalEnd.y );
      glEnd();
Raycasting And for a grand finale, we can put the raycasting code into its own function and call it recursively to reflect the ray off the intersected fixtures until it runs out. This is not really anything to do with Box2D, I just think it's neat :) Raycasting Here is the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  //new function for FooTest class
  void drawReflectedRay( b2Vec2 p1, b2Vec2 p2 )
  {
      //set up input
      b2RayCastInput input;
      input.p1 = p1;
      input.p2 = p2;
      input.maxFraction = 1;
  
      //check every fixture of every body to find closest
      float closestFraction = 1; //start with end of line as p2
      b2Vec2 intersectionNormal(0,0);
      for (b2Body* b = m_world->GetBodyList(); b; b = b->GetNext()) {
          for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext()) {
  
              b2RayCastOutput output;
              if ( ! f->RayCast( &output, input ) )
                  continue;
              if ( output.fraction < closestFraction ) {
                  closestFraction = output.fraction;
                  intersectionNormal = output.normal;
              }
          }
      }
      b2Vec2 intersectionPoint = p1 + closestFraction * (p2 - p1);
  
      //draw this part of the ray
      glBegin(GL_LINES);
      glVertex2f( p1.x, p1.y );
      glVertex2f( intersectionPoint.x, intersectionPoint.y );
      glEnd();
  
      if ( closestFraction == 1 )
          return; //ray hit nothing so we can finish here
      if ( closestFraction == 0 )
          return;
  
      //still some ray left to reflect
      b2Vec2 remainingRay = (p2 - intersectionPoint);
      b2Vec2 projectedOntoNormal = b2Dot(remainingRay, intersectionNormal) * intersectionNormal;
      b2Vec2 nextp2 = p2 - 2 * projectedOntoNormal;
  
      //recurse
      drawReflectedRay(intersectionPoint, nextp2);
  }
... and then inside Step() you would just have:
1
2
3
4
5
6
7
      //calculate points of ray
      float rayLength = 25;
      b2Vec2 p1( 0, 20 ); //center of scene
      b2Vec2 p2 = p1 + rayLength * b2Vec2( sinf(currentRayAngle), cosf(currentRayAngle) );
  
      glColor3f(1,1,1); //white
      drawReflectedRay(p1, p2);