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 - User data

Last edited: July 14 2013

Chinese version -> 中文

User data


In the previous topic, we saw how useful it was to have a reference to a physics object from a game entity class. Sometimes it is also useful to have the opposite - a pointer from a physics object to an entity in your game. In Box2D this is called user data, and it is just a pointer which you can set to hold some information that may be useful for you. The following classes have this functionality:
  • b2Body
  • b2Fixture
  • b2Joint
Box2D doesn't care what this information is, and it doesn't do anything with it. It just holds it and tells you what it is when you ask. The above classes all have the following functions to do this:
1
2
3
  //in b2Body, b2Fixture, b2Joint
  void SetUserData(void* data);
  void* GetUserData();
Setting something in the user data for bodies and fixtures will be extremely useful in upcoming topics, so let's try a simple example to get the hang of it. In this example we will implement exactly what we just did in the previous topic (getting the render position and velocity of the game entity) but we will do it without storing a pointer to the physics body in the Ball class. Instead, we will store a pointer to a Ball object in each physics body, and after each time step we will update class member variables of the ball object with the new information. Note that this is not really a practical way to approach the task, it's just for demonstration.

In order to access the user data for each physics body, we'll also need to try out a method for looping across all bodies in the scene. Instead of a loop in the proper sense, this is done by a linked list of bodies. We can use b2World::GetBodyList() to get the first element in the list to start iterating on.

So, start with the source code from the previous topic and modify it a bit. Firstly, take out all references to the m_body member variable of the Ball class, and alter its constructor to set the Ball class itself in the user data of the created physics body:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    Ball(b2World* world, float radius) {
      m_radius = radius;
  
      //set up dynamic body
      b2BodyDef myBodyDef;
      myBodyDef.type = b2_dynamicBody;
      myBodyDef.position.Set(0, 20);    
      b2Body* body = world->CreateBody(&myBodyDef);
      
      //set this Ball object in the body's user data
      body->SetUserData( this ); 
  
      //add circle fixture
      b2CircleShape circleShape;
      circleShape.m_p.Set(0, 0); 
      circleShape.m_radius = m_radius;
      b2FixtureDef myFixtureDef;
      myFixtureDef.shape = &circleShape;
      myFixtureDef.density = 1; 
      body->CreateFixture(&myFixtureDef); 
    }
Next, add some member variables to the Ball class to hold the physics information we'll need:
1
2
3
    b2Vec2 m_position;
    float m_angle;
    b2Vec2 m_linearVelocity;
... and replace the locations where calls to m_body->GetPosition(), m_body->GetAngle() and m_body->GetLinearVelocity() were previously used, to simply use these new member variables. For example, the section in renderAtBodyPosition to position the smiley face will now be:
1
2
  glTranslatef( m_position.x, m_position.y, 0 );
  glRotatef( m_angle * RADTODEG, 0, 0, 1 );
Running this as is, you'll see we are back at the initial stage of the last topic where the all the balls are rendered at (0,0) with no rotation: User data So to fix this in the Step() function, after the Test::Step() call and before we do our own rendering, we need to update the ball object positions from their physics bodies. To do this, iterate over all bodies in the world, get the necessary position/angle/velocity values and set them in the Ball object contained in the user data:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    b2Body* b = m_world->GetBodyList();//get start of list
    while ( b != NULL ) {
  
      //obtain Ball pointer from user data
      Ball* ball = static_cast<Ball*>( b->GetUserData() );
      if ( ball != NULL ) {
        ball->m_position = b->GetPosition();
        ball->m_angle = b->GetAngle();
        ball->m_linearVelocity = b->GetLinearVelocity();
      }
  
      //continue to next body
      b = b->GetNext();
    }
This should get the behaviour back to how it was before. Once again, this is not a recommended way of linking your game entities to a physics body for the purposes of rendering, it's just to demonstrate the user data functionality. For rendering, the previous method was much easier to implement and manage. Driving the information updates from the physics body doesn't help us much, because we are continuously rendering all the time regardless of what's happening in the physics simulation.

So what kind of practical uses does this user data feature have then? The usefulness comes when we want to be informed about something happening in the physics engine that we can't easily predict, such as when fixtures collide, what they collided with and what the reaction forces will be, etc. Other useful things include ray-casting or AABB queries to find intersected fixtures (and get the related game entity from the user data in the fixture).


Setting complex user data


Since the user data accepts a void pointer, anything that can be cast to a void pointer can be set in the user data. This could be a single number, an existing object pointer (as above) or a pointer that you make specifically to hold some complex information relating to the physics object. Here are some examples:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  //setting and retrieving an integer
  int myInt = 123;
  body->SetUserData( (void*)myInt );
  ...later...
  int udInt = (int)body->GetUserData();
  
  
  //setting and retrieving a complex structure
  struct bodyUserData {
      int entityType;
      float health;
      float stunnedTimeout;
  };
  bodyUserData* myStruct = new bodyUserData;
  myStruct->health = 4;//set structure contents as necessary
  body->SetUserData(myStruct);
  ...later...
  bodyUserData* udStruct = (bodyUserData*)body->GetUserData();
In each case, you should set the same type of value for the user data. For example, if you give a fixture an integer user data as in the first example here, then all fixtures should be given an integer for their user data. If you were to give some fixtures an integer and other fixtures a structure, when retrieving the user data from a fixture with GetUserData() it would be difficult to tell whether you are dealing with an integer or a structure (the collision callbacks topic will explain why you cannot always know which fixture or body you are dealing with when a collision is detected).

For most applications it is very handy to set a structure with multiple members in the user data. Box2D does not delete any of your user data objects when you destroy a body/fixture/joint, so you must remember to clean these up yourself when they are no longer needed.

In the structure example above the members of the structure are fixed, which gives a limited set of attributes to use, and not much flexibility if you have different entity types in your game. See the section of the collision callbacks topic titled 'real scenarios' for an example of using class inheritance for a more practical approach for when you have many types of entities.