Example Code Snippets:

Getting a Transformation from a Rigid Body:

You can quickly and easily build a transformation matrix from a Chipmunk body. The following code is for OpenGL, but it should be trivial to modify for DirectX or affine transforms. (Note that OpenGL matrices are column-major)

cpVect pos = body->p;
cpVect rot = body->rot;

GLFloat matrix[16] = {
   rot.x, rot.y, 0.0f, 0.0f,
  -rot.y, rot.x, 0.0f, 0.0f,
   0.0f,   0.0f, 1.0f, 0.0f,
   pos.x, pos.y, 0.0f, 1.0f,
};

glMultMatrixf(matrix.farr);

Collision Callbacks:

This snippet demonstrates several Chipmunk collision callback features. It defines a collision handler that is called when collision shapes start touching and also a post-step callback to remove the collision shape and body.

static void
postStepRemove(cpSpace *space, cpShape *shape, void *unused)
{
  cpSpaceRemoveBody(space, shape->body);
  cpSpaceRemoveShape(space, shape);
  
  cpShapeFree(shape);
  cpBodyFree(shape->body);
}

static int
begin(cpArbiter *arb, cpSpace *space, void *unused)
{
  // Get the cpShapes involved in the collision
  // The order will be the same as you defined in the handler definition
  // a->collision_type will be BULLET_TYPE and b->collision_type will be MONSTER_TYPE
  cpShape *a, *b; cpArbiterGetShapes(arb, &a, &b);
  
  // Alternatively you can use the CP_ARBITER_GET_SHAPES() macro
  // It defines and sets the variables for you.
  //CP_ARBITER_GET_SHAPES(arb, a, b);
  
  // Add a post step callback to safely remove the body and shape from the space.
  // Calling cpSpaceRemove*() directly from a collision handler callback can cause crashes.
  cpSpaceAddPostStepCallback(space, (cpPostStepFunc)postStepRemove, b, NULL);
  
  // The object is dead, don’t process the collision further
  return 0;
}

#define BULLET_TYPE 1
#define MONSTER_TYPE 2

// Define a collision handler for bullets and monsters
// Kill the monster by removing it’s shape and body from the space as soon as it’s hit by a bullet 
cpSpaceAddCollisionHandler(space, BULLET_TYPE, MONSTER_TYPE, begin, NULL, NULL, NULL, NULL);

For more callback examples, see the One Way Platform Demo, Sensors Demo, or the Player Demo.

Query Examples:

The following example is taken directly from ChipmunkDemo.c. When the mouse is clicked, a point query is performed to see if there is a shape under the mouse. If there is, it adds a joint to the body that links it to the mouse's movement.

static void
click(int button, int state, int x, int y)
{
  if(button == GLUT_LEFT_BUTTON){
    if(state == GLUT_DOWN){
      cpVect point = mouseToSpace(x, y);
    
      cpShape *shape = cpSpacePointQueryFirst(space, point, GRABABLE_MASK_BIT, 0);
      if(shape){
        cpBody *body = shape->body;
        mouseJoint = cpPivotJointNew2(mouseBody, body, cpvzero, cpBodyWorld2Local(body, point));
        mouseJoint->maxForce = 50000.0f;
        mouseJoint->biasCoef = 0.15f;
        cpSpaceAddConstraint(space, mouseJoint);
      }
    } else if(mouseJoint){
      cpSpaceRemoveConstraint(space, mouseJoint);
      cpConstraintFree(mouseJoint);
      mouseJoint = NULL;
    }
  }
}

Perform a segment query to see if a laser beam hits a shape. We want to draw particles at both the position where the beam enters and exits the shape.

cpVect a = cpv(...), b = cpv(...);

cpSegmentQueryInfo info = {};
if(cpSpaceSegmentQueryFirst(space, a, b, -1, 0, &info)){
  cpSegmentQueryInfo info2;
  cpShapeSegmentQuery(info.shape, b, a, &info2);
  
  cpVect enterPoint = cpSegmentQueryHitPoint(a, b, info);
  cpVect exitPoint = cpSegmentQueryHitPoint(b, a, info2);
}