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);
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.
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); }