JSON file structure
This topic will look at the JSON structure of the 'raw info' data that is exported by R.U.B.E.
Users with a reasonable knowledge of Box2D in their target language may be able to implement
a loader to parse and use the exported data if there is no existing loader available.
Some shortcuts have been made to keep down the size of the exported JSON, so it's important to
be aware of these.
- Boolean values that do not exist in the JSON are implicitly false.
- Numerical values that do not exist in the JSON are implicitly zero. *
- String values that do not exist in the JSON are implicitly empty strings.
- Properties that are expected to be a vector but are numeric zero, are the vector (0,0).
- Properties that are expected to be numerical but are strings should be interpreted as
the hexadecimal representation of a 32-bit floating point number. This is done to preserve accuracy and
decrease file size (average case). See the floatToHex/hexToFloat
functions in the b2dJson source code for an implementation of converting these in C++. (You
can disable the saving of floating point numbers as hexadecimal under the File tab of
the Options dialog.)
* There are some exceptions to the second point above.
A full listing of the properties of each object type is available at www.iforce2d.net/rube/json-structure
(opens default browser).
We will use the scene below as an example to illustrate various types of body and shape.
This scene contains four bodies, one image and one joint. The image is attached to the circular
body, and the joint connects the two bodies at the top, with the circular body being body A.
Let' start by looking at the mostly 'collapsed' JSON and gradually expand it see more details.
(Incidentally, these screenshots are taken using the excellent online JSON formatter at
http://www.bodurov.com/JsonFormatter/ which
you may find useful when examining JSON data.)
World
The root object in the exported data is the world. This contains a handful of boolean and numeric
values describing world properties, and a vector to hold the gravity property. The four bodies,
and the joint and the image are held in array children of the world.
Body
Here is the bottom right body expanded (this body will be exported with two circle fixtures and
one polygon fixture). Fixtures are held in an array child of the body they belong to.
Fixture
Fixtures have properties such as density, friction and restitution, and a single shape child which
can be a circle, polygon or chain.
Here is the fixture array of the bottom right body - we can see it has one polygon and two circle
fixtures.
Circle shape
Circle shapes have a center and a radius.
Polygon shape
Polygon shapes have two array children to hold the x and y coordinates of their vertices.
Here is the polygon shape of the upper right body.
Chain shape
Chain shapes have two array children to hold the x and y coordinates of their vertices.
The presence of the nextVertex/prevVertex members means the shape will be a closed loop shape
rather than an open-ended line.
Here is the chain shape of the lower left body.
Joint
Joints contain all the relevant properties for the type of joint, and the indices of the two
bodies they connect. The index for the bodies is their position in the bodies array, starting from index
zero.
Image
Images contain all the necessary information to load an image. Two array children hold the x
and y coordinates of the image corner locations. If the image is attached to a body,
the 'body' property will be an index for a body (the position in the bodies array, starting from index
zero) and the positions for the image will be relative to the body position. If the image is not
attached to a body, the 'body' property will be -1 and the positions will be absolute positions
in the world.
The glDrawElements, glTexCoordPointer and glVertexPointer properties contain information intended for
use with the OpenGL functions of the same name.
The values in these arrays can be used like this (example is for C++).
float* vertices; //load the glVertexPointer array into here
float* texCoords; //load the glTexCoordPointer array into here
unsigned short* indices; //load the glDrawElements array into here
int numIndices = 6; //set to length of glDrawElements array
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, indices);