/ Reference / Box2D API

abc2midi guide .. abc cheatsheet
Fiddle Runtime .. Fiddle Resources
Extending Fiddle .. Installing Fiddle
General MIDI .. MIDI CC .. MIDI notes
Box2D API .. Tidal Cheatsheet
Banklist File .. Sample TOC File
Audio Troubleshooting


This API can be used to build 2D worlds for use with Box2D node and DbBox2D chugin

DbBox2D API for ChucK

We expose a subset of the entire Box2D API to simplify the programming model and to target expected use-cases like sonification.

Many Box2D parameters are 2 or 3 dimensional. Rather than represent vectors as lists of floats, we leverage ChucK's builtin types, complex and vec3 to improve interface expressivity.

Currently we don't expose body or joint deletion to minimize instability. The memory associated with a previous world is released on worldBegin or when the DbBox2D instance goes out of scope.

Constants

Member Description
int staticType (0) One of 3 body types. Used for rooms, rocks, etc.
int kinematicType (1) One of 3 body types. Used for platforms. (ie: moving but "immovable").
int dynamicType (2) One of 3 body types. Used for moving body. (ie: most of them).
float degToRad Constant to convert from degrees to radians.
float radToDeg Constant to convert from radians to degrees.

Scene Construction

New shapes are usually created between calls to worldBegin and worldEnd.
Each body is assigned an id which can be used to query and change the state of various body or shape properties. The bodyType parameter is can be one of three values staticType, kinematicType, or dynamicType, available as a member variable off the DbBox2D instance.

Method Description
worldBegin(complex gravity) cancels current world and starts a new one.
worldEnd() finishes the current world definition. Simulation can now happen.
int newPoint(complex pos) creates a static point. Often used as joint anchor point.
int newEdge(complex p1, complex p2) creates a solid, two-sided static line. Often used for floors and walls.
int newCircle(complex pos, float radius, float density, int bodyType) creates a solid circle.
int newTriangle(complex p1, complex p2, complex p3, float density, int bodyType) creates a solid triangle.
int newTrianglePos(complex p1, complex p2, complex p3, complex pos, float density, int bodyType) alternate triangle creator whose coords are relative to pos
int newPolygon(complex pts[], complex pos, float density, int bodyType) creates a solid polygon given an array of points. Polygons must be convex.
int newRoom(complex pos, complex size, float density, int bodyType) creates a "room" comprised of 4 rectangles. Usually staticType or kinematicType.

Joints can be added to dynamically constrain bodies in the simulation.

Method Description
int newRevoluteJoint(int bodyA, int bodyB, complex localAnchorA, complex localAnchorB, float refAngle, float motorSpeed, float maxMotorTorque) creates a revolute joint. Returns a joint id.
int newDistanceJoint(int bodyA, int bodyB, complex localAnchorA, complex localAnchorB, float freqHz, float damping) creates a distance joint. When freqHz != 0 we creat a spring joint.

Scene Queries

Scene queries are useful for delivering internal scene state to interested parties. For example, it is used to implement Fiddle's Box2D plotting surface.

Member Description
int getNumBodies() returns the total number of bodies in the world.
int getNumBodyShapes(int bodyId) returns the number of shapes associated with the identified body. Usually 1.
int getBodyShapeType(int bodyId, int shapeIndex) returns the body shape type: 0: circle, 1: edge, 2:polygon, 3:chain.
float getCircleRadius(int bodyId, int shapeIndex) returns the radius of the identified circle.
getEdgePoints(int bodyId, int shapeIndex, complex pts[]) returns the 2 points of the identified edge.
getPolygonPoints(int bodyId, int shapeIndex, complex pts[]) returns the n points of the identified polygon.
getChainPoints(int bodyId, int shapeIndex, complex pts[]) returns the n points of the identified chain.
int getNumJoints() returns the total number of joints in the world.
complex getJointBodies(int jointId) returns two bodyIds associated with the enumerated joint (stuff into complex).

Simulation Query + Control

Once you have created a world you can control and query the simulation. Object properties can be changed during the simulation. To modify object properities its class (Body, Contact, Joint) couples with its id to uniquely identify the object.

Method Description
step(dur amt) causes the simulation to proceed to its next step. amt is typically 1/60th of a second.
dur getAvgSimTime() returns the average measured compute time for a simulation step.
complex getPosition(int id) returns the position of the identified body.
complex getVelocity(int id) returns the linear velocity of the identified body.
float getAngle(int id) returns the angle (in radians) of the identified body.
complex getAngularVelocity(int id) returns the angular velocity of the identified body.
int getNumContacts() returns the number of contact events that occured in the last frame.
vec3 getContact(int id) returns the contact info for the identified contact. 3 values are stuffed into the vec3: shapeAId, shapeBId, touching.
setGravity(complex g) allows you to change gravity during the simulation.
setFriction(int id, float x) change the friction value for identified body.
setDensity(int id, float x) change the density value for identified body.
setRestitution(int id, float x) change the restitution (bounciness) value for identified body.

Custom Dynamics and the Event Callback

To programatically exert forces acting on one or more bodies in the world, we:

  1. implement a EventHandler subclass, overriding the OnEvent method to properly time the delivery of scene changes. Box2D delivers two event types:
    • step is invoked after each simulation step
    • contact is invoked after each simulation step when collisions have occurred.
  2. use these force-modification entrypoints to target the scene changes.
Member Description
applyForce(int bodyId, complex force, complex pt) apply a force to the identified body at the worldspace pt.
applyImpulse(int bodyId, complex force) apply an impulse force to the identified body. Force is applyied at body center.
applyTorque(int bodyId, float torque) apply a torque to the identified body.
applyAngularImpulse(int bodyId, float torque) apply an angular impulse force to the identified body.

Example

// boxOfShapes.ck - example Box2D world-generator

// Verify that Fiddle has delivered a Box2D node operating context.
if(me.args() == 0)
{
    <<<"This script is intended for use by Box2D. Bailing...", me.id()>>>;
    1::second => now;
    me.exit();
}

// Lookup our Box2D node context
me.arg(0).toInt() => int boxId;
Box2D.Boxes[boxId] @=> Box2D boxO; 

// Example of an EventHandler subclass to respond to context or step
// events.  We can interact with these events by applying forces
// to individual dynamic bodies.
class eHandler extends EventHandler
{
    int stepCounter;
    fun void OnEvent(string type, Object ctx)    
    {
        ctx $ Box2D @=> boxO;
        if(type == "step")
        {
            this.stepCounter++;
            if((this.stepCounter % 200) == 0)
            {
                <<<"BoxOfShapes count", this.stepCounter>>>;
                boxO.dbBox2D.applyForce(#)
            }
        }
        // else type == "contact"
    }
};

eHandler myHandler; // create handler instance
boxO.SetEventHandler(myHandler);   // install our event handler

// define our world
boxO.dbBox2D @=> DbBox2D box2D;    // get a handle for DbBox2D chugin
box2D.worldBegin(#(0, -20));  // gravity points down
box2D.newEdge(#(-40, 0), #(40, 0)); // floor: p1, p2
box2D.newEdge(#(-40, 0), #(-40, 30)); // left wall
box2D.newEdge(#(40, 0), #(40, 30)); // right wall
box2D.newCircle(#(0, 25), 2, 2, box2D.dynamicType) => int c1; // p, radius, density
box2D.newCircle(#(-5, 20), 10, 2, box2D.dynamicType) => int c2; // p, radius, density
box2D.newTriangle(#(-5, 0), #(5, 0), #(0, -5), #(10,10), 1, box2D.dynamicType) => int t1;
box2D.setRestitution(c1, .75); // bounciness
box2D.setRestitution(c2, .85); 
box2D.setRestitution(t1, .85);
box2D.setDensity(c2, 100);
box2D.worldEnd();
home .. topics .. interface .. reference .. examples .. tipjar