code:
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := chipmunk_shared

LOCAL_MODULE_FILENAME := libchipmunk

LOCAL_SRC_FILES := \
src/chipmunk.c \
src/constraints/cpConstraint.c \
src/constraints/cpDampedRotarySpring.c \
src/constraints/cpDampedSpring.c \
src/constraints/cpGearJoint.c \
src/constraints/cpGrooveJoint.c \
src/constraints/cpPinJoint.c \
src/constraints/cpPivotJoint.c \
src/constraints/cpRatchetJoint.c \
src/constraints/cpRotaryLimitJoint.c \
src/constraints/cpSimpleMotor.c \
src/constraints/cpSlideJoint.c \
src/cpArbiter.c \
src/cpArray.c \
src/cpBB.c \
src/cpBody.c \
src/cpCollision.c \
src/cpHashSet.c \
src/cpPolyShape.c \
src/cpShape.c \
src/cpSpace.c \
src/cpSpaceComponent.c \
src/cpSpaceHash.c \
src/cpSpaceQuery.c \
src/cpSpaceStep.c \
src/cpVect.c

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include/chipmunk

LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/chipmunk
LOCAL_CFLAGS := -std=c99

include $(BUILD_SHARED_LIBRARY)

########### Static library

include $(CLEAR_VARS)

LOCAL_MODULE := chipmunk_static

LOCAL_MODULE_FILENAME := libchipmunk

LOCAL_SRC_FILES := \
src/chipmunk.c \
src/constraints/cpConstraint.c \
src/constraints/cpDampedRotarySpring.c \
src/constraints/cpDampedSpring.c \
src/constraints/cpGearJoint.c \
src/constraints/cpGrooveJoint.c \
src/constraints/cpPinJoint.c \
src/constraints/cpPivotJoint.c \
src/constraints/cpRatchetJoint.c \
src/constraints/cpRotaryLimitJoint.c \
src/constraints/cpSimpleMotor.c \
src/constraints/cpSlideJoint.c \
src/cpArbiter.c \
src/cpArray.c \
src/cpBB.c \
src/cpBody.c \
src/cpCollision.c \
src/cpHashSet.c \
src/cpPolyShape.c \
src/cpShape.c \
src/cpSpace.c \
src/cpSpaceComponent.c \
src/cpSpaceHash.c \
src/cpSpaceQuery.c \
src/cpSpaceStep.c \
src/cpVect.c

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include/chipmunk

LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/chipmunk
LOCAL_CFLAGS := -std=c99

include $(BUILD_STATIC_LIBRARY)


code:
ABOUT:
Chipmunk is a simple, lightweight and fast 2D rigid body physics library written in C. It's licensed under the unrestrictive, OSI approved MIT license. My aim is to give 2D developers access the same quality of physics you find in newer 3D games. I hope you enjoy using Chipmunk, and please consider donating to help make it worth our time to continue to support Chipmunk with great new features.

CONTRACTING:
Howling Moon Software (my company) is available for contracting if you want to make the physics in your game really stand out. Given our unique experience with the library, we can help you use Chipmunk to it's fullest potential. Feel free to contact us through our webpage: http://howlingmoonsoftware.com/contracting.php

BUILDING:
Mac OS X: There is an included XCode project file for building the static library and demo application. Alteratively you could use the CMake files.

iPhone: The XCode project can build a static library with all the proper compiler settings. Additionally, if you run the iphonestatic.sh script in the macosx/ directory, it will build you a fat library compiled as release for the device and debug for the simulator. After building that, just copy the static lib and include/chipmunk/ directory to your project.

UNIX: A forum user was kind enough to make a set of CMake files for Chipmunk. This will require you to have CMake installed. To build run 'cmake .' then 'make'. This should build a dynamic library, a static library, and the demo application.

Windows: There is an included MSVC project for building the library and demo application. I do not personally maintain the MSVC project and it apparently hasn't worked for a while. If you are a MSVC whiz, consider lending a hand.

Ruby: I've been using maintaining a Ruby extension for Chipmunk, but at this time is not up to date with all the latest changes. A forum member has been working on an FFI based extention, and that may be a better way to take advantage of Chipmunk from Ruby. Another forum user has offered to maintain the non-FFI version of the extension. Stay tuned.

GETTING STARTED:
First of all, you can find the C API documentation here: http://code.google.com/p/chipmunk-physics/wiki/Documentation

A good starting point is to take a look at the included Demo application. The demos all just set up a Chipmunk simulation space and the demo app draws the graphics directly out of that. This makes it easy to see how the Chipmunk API works without worrying about the graphics code. You are free to use the demo drawing routines in your own projects, though it is certainly not the recommended way of drawing Chipmunk objects as it pokes around at the undocumented parts of Chipmunk.

FORUM:
http://www.slembcke.net/forums

CONTACT:
slembcke@gmail.com (also on Google Talk)

CHANGES SINCE 5.0.0:
* Fixed a NaN issue where raycasts for horizontal or vertical lines would end up in an infinite loop.
* Fixed a number of memory leaks.
* Fixed a number of warnings for various compiler/OS combinations.
* Fixed a number of API issues:
  * Rejecting a collision from a begin() callback permanently rejects the collision until separation.
  * Erroneous collision type parameterns removed from cpSpaceDefaulteCollisionHandler().
* Moved FFI declarations of inlined functions into their own header.
* Rearranged the project structure to separate out the header files into a separate include/ directory.
* Added a static library target for the iPhone.
* Type changes when building on the iPhone to make it friendlier to other APIs.
* Added an AABB query to complement point and segment queries.
* Added CP_NO_GROUP and CP_ALL_LAYERS constants.

CHANGES SINCE 4.x:
* Brand new Joint/Constraint API: New constraints can be added easily and are much more flexible than the old joint system
* Efficient Segment Queries - Like raycasting, but with line segments.
* Brand new collision callback API: Collision begin/separate events, API for removal of objects within callbacks, more programable control over collision handling.

license: mit


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Chipmunk Game Dynamics Documentation</title>

Chipmunk Game Dynamics

Introduction

First of all, Chipmunk is a 2D rigid body physics library distributed under the MIT license. Though not yet complete, it is intended to be fast, numerically stable, and easy to use.

It’s been a long time in coming, but I’ve finally made a stable and usable physics implementation. While not feature complete yet, it’s well on it’s way. I would like to give a Erin Catto a big thank you, as the most of the ideas for the constraint solver come from his Box2D example code. (gPhysics Website). His contact persistence idea allows for stable stacks of objects with very few iterations of the contact solution. Couldn’t have gotten that working without his help.

Overview

rigid bodies: A rigid body holds the physical properties of an object. (mass, position, rotation, velocity, etc.) It does not have a shape by itself. If you’ve done physics with particles before, rigid bodies differ mostly in that they are able to rotate.

collision shapes: By attaching shapes to bodies, you can define the a body’s shape. You can attach many shapes to a single body to define a complex shape, or none if it doesn’t require a shape.

joints: You can attach joints between two bodies to constrain their behavior.

spaces: Spaces are the basic simulation unit in Chipmunk. You add bodies, shapes and joints to a space, and then update the space as a whole.

Rigid bodies, collision shapes and sprites:

There is often confusion between rigid bodies and their collision shapes in Chipmunk and how they relate to sprites. A sprite would be a visual representation of an object, the sprite is drawn at the position of the rigid body. The collision shape would be the material representation of the object, and how it should collide with other objects. A sprite and collision shape have little to do with one another other than you probably want the collision shape to match the sprite’s shape.

C API Documentation

Initializing Chipmunk

Initializing Chipmunk is an extremely complicated process. The following code snippet steps you through the process:

cpInitChipmunk(); /* Actually, that's pretty much it */

Chipmunk memory management

For many of the structures you will use, Chipmunk uses a more or less standard set of memory management functions. For instance:

cpSpaceAlloc() allocates but does not initialize a cpSpace struct.

cpSpaceInit(space, other_args) initializes a cpSpace struct.

cpSpaceNew(args) allocates and initializes a cpSpace struct using args.

cpSpaceDestroy(space) frees all dependancies, but does not free the cpSpace struct.

cpSpaceFree(space) frees all dependancies and the cpSpace struct.

While you will probably use the new/free versions exclusively, the others can be helpful when writing language extensions.

In general, you are responsible for freeing any structs that you allocate. The only exception is that cpShapeDestroy() also destroys the specific shape struct that was passed to the constructor.

Chipmunk floats: cpFloat

typedef float cpFloat;

All Chipmunk code should be double safe, so feel free to redefine this.

Chipmunk vectors: cpVect

User accessible fields:

typedef struct cpVect{
    cpFloat x,y;
} cpVect

Simply a 2D vector packed into a struct. May change in the future to take advantage of SIMD.

#define cpvzero ((cpVect){0.0f, 0.0f})

Constant for the zero vector.

cpVect cpv(const cpFloat x, const cpFloat y)

Convenience constructor for creating new cpVect structs.

cpVect cpvadd(const cpVect v1, const cpVect v2)
cpVect cpvsub(const cpVect v1, const cpVect v2)

Add or subtract two vectors.

cpVect cpvneg(const cpVect v)

Negate a vector.

cpVect cpvmult(const cpVect v, const cpFloat s)

Scalar multiplication.

cpFloat cpvdot(const cpVect v1, const cpVect v2)

Vector dot product.

cpFloat cpvcross(const cpVect v1, const cpVect v2)

2D vector cross product analog. The cross product of 2D vectors exists only in the z component, so only that value is returned.

cpVect cpvperp(const cpVect v)

Returns the perpendicular vector. (90 degree rotation)

cpVect cpvproject(const cpVect v1, const cpVect v2)

Returns the vector projection of v1 onto v2.

cpVect cpvrotate(const cpVect v1, const cpVect v2)

Uses complex multiplication to rotate (and scale) v1 by v2.

cpVect cpvunrotate(const cpVect v1, const cpVect v2)

Inverse of cpvrotate().

cpFloat cpvlength(const cpVect v)

Returns the length of v.

cpFloat cpvlengthsq(const cpVect v)

Returns the squared length of v. Faster than cpvlength() when you only need to compare lengths.

cpVect cpvnormalize(const cpVect v)

Returns a normalized copy of v.

cpVect cpvforangle(const cpFloat a)

Returns the unit length vector for the given angle (in radians).

cpFloat cpvtoangle(const cpVect v)

Returns the angular direction v is pointing in (in radians).

*cpvstr(const cpVect v)

Returns a string representation of v. NOTE: The string points to a static local and is reset every time the function is called.

Chipmunk bounding boxes: cpBB

User accessible fields:

typedef struct cpBB{
    cpFloat l, b, r ,t;
} cpBB

Simple bounding box struct. Stored as left, bottom, right, top values.

cpBB cpBBNew(const cpFloat l, const cpFloat b, const cpFloat r, const cpFloat t)

Convenience constructor for cpBB structs.

int cpBBintersects(const cpBB a, const cpBB b)

Returns true if the bounding boxes intersect.

int cpBBcontainsBB(const cpBB bb, const cpBB other)

Returns true if bb completely contains other.

int cpBBcontainsVect(const cpBB bb, const cpVect v)

Returns true if bb contains v.

cpVect cpBBClampVect(const cpBB bb, const cpVect v)

Returns a copy of v clamped to the bounding box.

cpVect cpBBWrapVect(const cpBB bb, const cpVect v)

Returns a copy of v wrapped to the bounding box.

Chipmunk spatial hashes: cpSpaceHash

The spatial hash isn’t yet ready for user use. However, it has been made in a generic manner that would allow it to be used for more than just Chipmunk’s collision detection needs.

Chipmunk rigid bodies: cpBody

User accessible fields:

typedef struct cpBody{
    cpFloat m, m_inv;
    cpFloat i, i_inv;

    cpVect p, v, f;
    cpFloat a, w, t;
    cpVect rot;
} cpBody

m, and m_inv are the mass and its inverse.

i, and i_inv are the moment of inertia and its inverse.

p, v, and f are the position, velocity and force respectively.

a, w, and t are the angle (in radians), angular velocity (rad/sec), and torque respectively.

rot is the rotation of the body as a unit length vector. (can be used with cpvrotate())

cpBody *cpBodyAlloc(void)
cpBody *cpBodyInit(cpBody *body, cpFloat m, cpFloat i)
cpBody *cpBodyNew(cpFloat m, cpFloat i)

void cpBodyDestroy(cpBody *body)
void cpBodyFree(cpBody *body)

Uses the standard suite of Chipmunk memory functions. m and i are the mass and moment of inertia for the body.

void cpBodySetMass(cpBody *body, cpFloat m);
void cpBodySetMoment(cpBody *body, cpFloat i);
void cpBodySetAngle(cpBody *body, cpFloat a);

Because several of the values are linked, (m/m_inv, i/i_inv, a/rot) don’t set them explicitly, use these setter functions instead.

cpVect cpBodyLocal2World(cpBody *body, cpVect v)

Convert from body local coordinates to world space coordinates.

cpVect cpBodyWorld2Local(cpBody *body, cpVect v)

Convert from world space coordinates to body local coordinates.

void cpBodyApplyImpulse(cpBody *body, cpVect j, cpVect r)

Apply the impulse j to body with offset r. Both j and r should be in world coordinates.

void cpBodyResetForces(cpBody *body)

Zero both the forces and torques accumulated on body.

void cpBodyApplyForce(cpBody *body, cpVect f, cpVect r)

Apply (accumulate) the force f on body with offset r. Both f and r should be in world coordinates.

void cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)

Updates the velocity of the body using Euler integration. You don’t need to call this unless you are managing the object manually instead of adding it to a cpSpace.

void cpBodyUpdatePosition(cpBody *body, cpFloat dt)

Updates the position of the body using Euler integration. Like cpBodyUpdateVelocity() you shouldn’t normally need to call this yourself.

void cpDampedSpring(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat rlen, cpFloat k, cpFloat dmp, cpFloat dt)

Apply a spring force between bodies a and b at anchors anchr1 and anchr2 respectively.  k is the spring constant (force/distance),  rlen is the rest length of the spring,  dmp is the damping constant (force/velocity), and dt is the time step to apply the force over. Note: not solving the damping forces in the impulse solver causes problems with large damping values. This function will eventually be replaced by a new constraint (joint) type.

Notes:

Use forces to modify the rigid bodies if possible. This is likely to be the most stable.

Modifying a body’s velocity shouldn’t necessarily be avoided, but applying large changes can cause strange results in the simulation. Experiment freely, but be warned.

Don’t modify a body’s position every step unless you really know what you are doing. Otherwise you’re likely to get the position/velocity badly out of sync.

Chipmunk collision shapes: cpShape

There are currently 3 possible collision shapes:

Circles: Fastest collision shape. They also roll smoothly.

Line segments: Meant mainly as a static shape. They can be attached to moving bodies, but they don’t generate collisions with other line segments.

Convex polygons: Slowest, but most flexible collision shape.

User accessible fields:

typedef struct cpShape{
    cpBB bb;

    unsigned long collision_type;
    unsigned long group;
    unsigned long layers;

    void *data;

    cpBody *body;
    cpFloat e, u;
    cpVect surface_v;
} cpShape;

bb: The bounding box of the shape. Only guaranteed to be valid after cpShapeCacheBB() is called.

collision_type: A user definable field, see the collision pair function section below for more information.

group: Shapes in the same non-zero group do not generate collisions. Useful when creating an object out of many shapes that you don’t want to self collide. Defaults to 0;

layers: Shapes only collide if they are in the same bit-planes. i.e. (a->layers & b->layers) != 0 By default, a shape occupies all 32 bit-planes.

data: A user definable field.

body: The rigid body the shape is attached to.

e: Elasticity of the shape. A value of 0.0 gives no bounce, while a value of 1.0 will give a “perfect” bounce. However due to inaccuracies in the simulation using 1.0 or greater is not recommended however. See the notes at the end of the section.

u: Friction coefficient. Chipmunk uses the Coulomb friction model, a value of 0.0 is frictionless. Tables of friction coefficients. See the notes at the end of the section.

surface_v: The surface velocity of the object. Useful for creating conveyor belts or players that move around. This value is only used when calculating friction, not the collision.

void cpShapeDestroy(cpShape *shape)
void cpShapeFree(cpShape *shape)

Destroy and Free functions are shared by all shape types.

cpBB cpShapeCacheBB(cpShape *shape)

Updates and returns the bounding box of shape.

void cpResetShapeIdCounter(void)

Chipmunk keeps a counter so that every new shape is given a unique hash value to be used in the spatial hash. Because this affects the order in which the collisions are found and handled, you should reset the shape counter every time you populate a space with new shapes. If you don’t, there might be (very) slight differences in the simulation.

cpCircleShape *cpCircleShapeAlloc(void)
cpCircleShape *cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpVect offset, cpFloat radius)
cpShape *cpCircleShapeNew(cpBody *body, cpVect offset, cpFloat radius)

body is the body to attach the circle to, offset is the offset from the body’s center of gravity in body local coordinates.

cpSegmentShape* cpSegmentShapeAlloc(void)
cpSegmentShape* cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat radius)
cpShape* cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat radius)

body is the body to attach the segment to, a and b are the endpoints, and radius is the thickness of the segment.

cpPolyShape *cpPolyShapeAlloc(void)
cpPolyShape *cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, cpVect *verts, cpVect offset)
cpShape *cpPolyShapeNew(cpBody *body, int numVerts, cpVect *verts, cpVect offset)

body is the body to attach the poly to, verts is an array of cpVect’s defining a convex hull with a counterclockwise winding, offset is the offset from the body’s center of gravity in body local coordinates.

Notes:

You can attach multiple collision shapes to a rigid body. This should allow you to create almost any shape you could possibly need.

Shapes attached to the same rigid body will never generate collisions. You don’t have to worry about overlap when attaching multiple shapes to a rigid body.

The amount of elasticity applied during a collision is determined by multiplying the elasticity of both shapes together. The same is done for determining the friction.

Make sure you add both the body and it’s collision shapes to a space. The exception is when you want to have a static body or a body that you integrate yourself. In that case, only add the shape.

Chipmunk joints: cpJoint

There are currently 4 kinds of joints:

Pin Joints connect two rigid bodies with a solid pin or rod. It keeps the anchor points at a set distance from one another.

Slide Joints are like pin joints, but have a minimum and maximum distance. A chain could be modeled using this joint. It keeps the anchor points from getting to far apart, but will allow them to get closer together.

Pivot Joints simply allow two objects to pivot about a single point.

Groove Joints attach a point on one body to a groove on the other. Think of it as a sliding pivot joint.

void cpJointDestroy(cpJoint *joint)
void cpJointFree(cpJoint *joint)

Destroy and Free functions are shared by all joint types.

cpPinJoint *cpPinJointAlloc(void)
cpPinJoint *cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)
cpJoint *cpPinJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)

a and b are the two bodies to connect, and anchr1 and anchr2 are the anchor points on those bodies.

cpSlideJoint *cpSlideJointAlloc(void)
cpSlideJoint *cpSlideJointInit(cpSlideJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max)
cpJoint *cpSlideJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max)

a and b are the two bodies to connect, anchr1 and anchr2 are the anchor points on those bodies, and min and max define the allowed distances of the anchor points.

cpPivotJoint *cpPivotJointAlloc(void)
cpPivotJoint *cpPivotJointInit(cpPivotJoint *joint, cpBody *a, cpBody *b, cpVect pivot)
cpJoint *cpPivotJointNew(cpBody *a, cpBody *b, cpVect pivot)

a and b are the two bodies to connect, and pivot is the point in world coordinates of the pivot. Because the pivot location is given in world coordinates, you must have the bodies moved into the correct positions already.

cpGrooveJoint *cpGrooveJointAlloc(void)
cpGrooveJoint *cpGrooveJointInit(cpGrooveJoint *joint, cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2)
cpJoint *cpGrooveJointNew(cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2)

The groove goes from groov_a to groove_b on body a_, and the pivot is attached to _anchr2 on body b. All coordinates are body local.

Notes:

You can add multiple joints between two bodies, but make sure that they don’t fight. It can cause the bodies to explode.

Make sure you add both of the connected bodies and the joint to a space.

Chipmunk spaces: cpSpace

User accessible fields:

typedef struct cpSpace{
    int iterations;

    cpVect gravity;
    cpFloat damping;

    int stamp;
} cpSpace;

iterations: The number of iterations to use when solving constraints (collisions and joints). Defaults to 10.

gravity: The amount of gravity applied to the system.

damping: The amount of viscous damping applied to the system.

stamp: The tick stamp. Incremented every time cpSpaceStep() is called. read only

void cpSpaceFreeChildren(cpSpace *space)

Frees all bodies, shapes and joints added to the system.

cpSpace* cpSpaceAlloc(void)
cpSpace* cpSpaceInit(cpSpace *space, int iterations)
cpSpace* cpSpaceNew(int iterations)

void cpSpaceDestroy(cpSpace *space)
void cpSpaceFree(cpSpace *space)

More standard Chipmunk memory functions.

void cpSpaceFreeChildren(cpSpace *space)

This function will free all of the shapes, bodies and joints that have been added to space.

void cpSpaceAddShape(cpSpace *space, cpShape *shape)
void cpSpaceAddStaticShape(cpSpace *space, cpShape *shape)
void cpSpaceAddBody(cpSpace *space, cpBody *body)
void cpSpaceAddJoint(cpSpace *space, cpJoint *joint)

void cpSpaceRemoveShape(cpSpace *space, cpShape *shape)
void cpSpaceRemoveStaticShape(cpSpace *space, cpShape *shape)
void cpSpaceRemoveBody(cpSpace *space, cpBody *body)
void cpSpaceRemoveJoint(cpSpace *space, cpJoint *joint)

These functions add and remove shapes, bodies and joints from space. Shapes added as static are assumed not to move. Static shapes should be be attached to a rigid body with an infinite mass and moment of inertia. Also, don’t add the rigid body used to the space, as that will cause it to fall under the effects of gravity.

void cpSpaceResizeStaticHash(cpSpace *space, cpFloat dim, int count)
void cpSpaceResizeActiveHash(cpSpace *space, cpFloat dim, int count)

The spatial hashes used by Chipmunk’s collision detection are fairly size sensitive. dim is the size of the hash cells. Setting dim to the average objects size is likely to give the best performance.

count is the suggested minimum number of cells in the hash table. Bigger is better, but only to a point. Setting count to ~10x the number of objects in the hash is probably a good starting point.

By default, dim is 100.0, and count is 1000.

void cpSpaceRehashStatic(cpSpace *space)

Rehashes the shapes in the static spatial hash. You only need to call this if you move one of the static shapes.

void cpSpaceStep(cpSpace *space, cpFloat dt)

Update the space for the given time step. Using a fixed time step is highly recommended. Doing so will increase the efficiency of the contact persistence, requiring an order of magnitude fewer iterations to resolve the collisions in the usual case.

Notes:

When removing objects from the space, make sure you remove any other objects that reference it. For instance, when you remove a body, remove the joints and shapes attached to it.

The number of iterations, and the size of the time step determine the quality of the simulation. More iterations, or smaller time steps increase the quality.

Because static shapes are only rehashed when you request it, it’s possible to use a much higher count argument to cpHashResizeStaticHash() than to cpHashResizeStaticHash(). Doing so will use more memory though.

Miscellaneous.

cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset)

Calculate the moment of inertia for a circle. Arguments are similar to cpCircleShapeInit(). m_ is the mass, _r1 and r2 define an inner and outer radius, and offset is the offset of the center from the center of gravity of the rigid body.

cpFloat cpMomentForPoly(cpFloat m, int numVerts, cpVect *verts, cpVect offset)

Calculate the moment of inertia for a poly. Arguments are similar to cpPolyShapeInit() m_ is the mass, _numVerts is the number of vertexes in verts, and offset is the offset of the poly coordinates from the center of gravity of the rigid body.

Collision pair functions

Collision pair functions allow you to add callbacks for certain collision events. Each cpShape structure has a user definable collision_type field that is used to identify its type. For instance, you could define an enumeration of collision types such as bullets and players, and then register a collision pair function to reduce the players health when a collision is found between the two.

Additionally, the return value of a collision pair function determines whether or not a collision will be processed. If the function returns false, the collision will be ignored. One use for this functionality is to allow a rock object to break a vase object. If the approximated energy of the collision is above a certain level, flag the vase to be removed from the space, apply an impulse to the rock to slow it down, and return false. After the cpSpaceStep() returns, remove the vase from the space.

WARNING: It is not safe for collision pair functions to remove or free shapes or bodies from a space. Doing so will likely end in a segfault as an earlier collision may already be referencing the shape or body. You must wait until after the cpSpaceStep() function returns.

typedef struct cpContact{
    cpVect p, n;
    cpFloat dist;

    cpFloat jnAcc, jtAcc;
} cpContact;

An array of cpContact structs are passed to collision pair functions. Some user accessible fields include:

p: position of the collision.

n: normal of the collision.

dist: penetration distance of the collision.

jnAcc and jtAcc: The normal and tangential components of the accumulated (final) impulse applied to resolve the collision. Values will not be valid until after the call to cpSpaceStep() returns.

typedef int (*cpCollFunc)(cpShape *a, cpShape *b, cpContact *contacts, int numContacts, cpFloat normal_coef, void *data)

Prototype for a collision callback function. The two colliding shapes are passed as a and b, along with the contact points, and a user definable pointer are passed as arguments. The shapes are passed in the same order as their types were registered using cpSpaceAddCollisionPairFunc(). Because Chipmunk may swap the shapes to accommodate your collision pair function the normals may be backwards. Always multiply the normals by normal_coef before using the values. The contacts array may be freed on the next call to cpSpaceStep().

void cpSpaceAddCollisionPairFunc(cpSpace *space, unsigned long a, unsigned long b, cpCollFunc func, void *data)

Register func to be called when a collision is found between a shapes with collision_type fields that match a and b. data is passed to func as a parameter. The ordering of the collision types will match the ordering passed to the callback function.

Passing NULL for func will reject any collision with the given collision type pair.

void cpSpaceRemoveCollisionPairFunc(cpSpace *space, unsigned long a, unsigned long b)

Remove the function for the given collision type pair. The order of a and b must match the original order used with cpSpaceAddCollisionPairFunc().

void cpSpaceSetDefaultCollisionPairFunc(cpSpace *space, cpCollFunc func, void *data)

The default function is called when no collision pair function is specified. By default, the default function simply accepts all collisions. Passing NULL for func will reset the default function back to the default. (You know what I mean.)

Passing NULL for func will reject collisions by default.

Advanced topics

Advanced collision processing

Using collision pair functions, it’s possible to get information about a collision such as the locations of the contact points and the normals, but you can’t get the impulse applied to each contact point at the time the callback is called. Because Chipmunk caches the impulses, it is possible to access them after the call to cpSpaceStep() returns.

The impulse information is stored in the jnAcc and jtAcc fields of the cpContact structures passed to the collision pair function. So you must store a reference to the contacts array in the collision pair function so that you can access it later once the impulses have been calculated.

cpVect cpContactsSumImpulses(cpContact *contacts, int numContacts);
cpVect cpContactsSumImpulsesWithFriction(cpContact *contacts, int numContacts);

Sums the impulses applied to the the given contact points. cpContactsSumImpulses() sums only the normal components, while cpContactsSumImpulsesWithFriction() sums the normal and tangential componets.

Notes:

The contact array will either be destroyed or out of date after the next call to cpSpaceStep(). If you need to store the collision information permanently, you’ll have to copy it.

Collision pair functions, groups, and layers

There are three ways that you can specify which shapes are allowed to collide in Chipmunk: collision pair functions, groups, and layers. What are their intended purposes?

Collision pair functions: More than just a callback, collision pair functions can conditionally allow a collision between two shapes. This is the only choice if you need to perform some logic based on the shapes or contact information before deciding to allow the collision.

Groups: Groups filter out collisions between objects in the same non-zero groups. A good example of when groups would be useful is to create a multi-body, multi-shape object such as a ragdoll. You don’t want the parts of the ragdoll to collide with itself, but you do want it to collide with other ragdolls.

Layers: Layers are another way of grouping shapes. Collision between shapes that don’t occupy one or more of the same layers are filtered out. Layers are implemented using a bitmask on an unsigned long, so there are up to 32 layers available.

To be clear, for a collision to occur, all of the tests have to pass. Additionally, collisions between static shapes are not considered nor are collisions between shapes connected to the same rigid body.

Mysteries of cpSpaceStep() explained.

The cpSpaceStep() function is really the workhorse of Chipmunk. So what exactly does it do?

Persistent contacts with a stamp that is out of date by more than cp_contact_persistence are filtered out.

Velocities of all rigid bodies in the space are integrated using cpBodyUpdateVelocity().

All active shapes have their bounding boxes calculated and cached.

Collisions between the active shapes and static shapes are found. (collision pair functions are called)

Collisions between the active shapes are found. (collision pair functions are called)

Information about all constraints (collisions and joints) is pre-calculated.

Impulses are found and applied to solve all constraints (joints and collisions).

Positions of all rigid bodies in the space are integrated using cpBodyUpdatePosition().

Chipmunk does a lot of processing on the shapes in the system in order to provide robust and fast collision detection, but the same is not true of the rigid bodies. Really all cpSpaceStep() does to the bodies in the system is to integrate them and apply impulses to them.

The integration step is really just for convenience. If you integrate the velocity of your rigid bodies before calling cpSpaceStep() and integrate their positions afterward, you don’t have to add them to the space at all. In fact, there are good reasons for not doing so. All bodies in the space are integrated using the same gravity and damping, and this prevents you from providing interesting objects such as moving platforms.

If you are going to do the integration for your rigid bodies manually, I would highly recommend that you use cpBodyUpdatePosition() to integrate the position of the objects and only integrate the velocity. cpBodyUpdatePosition() is a required step for penetration resolution, and weird things could happen if it’s not called. Chipmunk uses Euler integration, so calculating the velocity required to move a body to a specific position is trivial if that is what you wish to do.

Chipmunk globals.

Chipmunk was designed with multithreading in mind, so very few globals are used. This shouldn’t be a problem in most cases as it’s likely you’ll only need to set them on a per application basis (if at all).

int cp_contact_persistence: This determines how long contacts should persist. This number should be fairly small as the cached contacts will only be close for a short time. cp_contact_persistence defaults to 3 as it is large enough to help prevent oscillating contacts, but doesn’t allow stale contact information to be used.

cpFloat cp_collision_slop: The amount that shapes are allowed to penetrate. Setting this to zero will work just fine, but using a small positive amount will help prevent oscillating contacts. cp_collision_slop defaults to 0.1.

cpFloat cp_bias_coef: The amount of penetration to reduce in each step. Values should range from 0 to 1. Using large values will eliminate penetration in fewer steps, but can cause vibration. cp_bias_coef defaults to 0.1.

cpFloat cp_joint_bias_coef: Similar to cp_bias_coef, but for joints. Defaults to 0.1. In the future, joints might have their own bias coefficient instead.

Known Problems

Fast moving objects sometimes pass right through one another. This is because I’m not doing swept volume collisions. Use smaller time steps if this is a problem.

Pointy or thin polygons aren’t handled well. Collision points are generated at the poly’s vertexes. I haven’t decided what to do about this yet.

Elastic shapes don’t stack well.

Performance/Quality tuning

There are a number of things you can do to increase the performance of Chipmunk:

Use simpler collision shapes when possible. It’s easier on the collision detection, you’ll generate fewer contact points, and require fewer iterations.

Make sure you have your spatial hashes tuned properly. It may take some experimenting to find the optimal dim/count parameters.

Use fewer iterations.

Use a larger time step.

Use a fixed time step. This allows contact persistence to work properly, reducing the number of iterations you need by an order of magnitude.

If you have problems with jittery or vibrating objects, you need to do mostly the opposite:

Use simpler shapes. Simpler shapes generate fewer contacts, increasing the efficiency of each iteration.

Use more iterations.

Use a smaller time step.

Use a fixed time step. By allowing the contact persistence to work properly, you can use more iterations without increasing the computational cost.

To do

There are a number of things left on my todo list:

More joint types.

Post collision queries. Being able to query for all the impulses that were applied to an object would be useful.

Python binding. (possibly others if I can get help)

Contact information

Drop me a line. Tell me how great you think Chipmunk is or how terribly buggy it is. I’d love to hear about any project that people are using Chipmunk for.

AIM: slembcke@mac.com

Email: lemb0029(at)morris(dot)umn(dot)edu or slembcke(at)gmail(dot)com

I can also be found lurking about the iDevGames forums.

License

Copyright© 2007 Scott Lembcke

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


code:
/****************************************************************************
Copyright (c) 2010 cocos2d-x.org

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

#ifndef __CCX_COMMON_WOPHONE__
#define __CCX_COMMON_WOPHONE__

#if defined(_WIN32)
    #if defined(SS_MAKEDLL)
    #define CCX_DLL     __declspec(dllexport)
    #elif defined(SS_IGNORE_EXPORT)
    #define CCX_DLL
    #else 		/* use a DLL library */
    #define CCX_DLL     __declspec(dllimport)
    #endif
#else
    #if defined(SS_SHARED)
    #define CCX_DLL     __attribute__((visibility("default")))
    #elif defined(SS_IGNORE_EXPORT)
    #define CCX_DLL
    #else
    #define CCX_DLL
    #endif
#endif

#endif	// end of __CCX_COMMON_WOPHONE__


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#ifndef CHIPMUNK_HEADER
#define CHIPMUNK_HEADER

#ifdef __cplusplus
extern "C" {
#endif

#ifndef CP_ALLOW_PRIVATE_ACCESS
	#define CP_ALLOW_PRIVATE_ACCESS 1
#endif

#if CP_ALLOW_PRIVATE_ACCESS == 1
	#define CP_PRIVATE(symbol) symbol
#else
	#define CP_PRIVATE(symbol) symbol##_private
#endif

void cpMessage(const char *message, const char *condition, const char *file, int line, int isError);
#ifdef NDEBUG
	#define	cpAssertWarn(condition, message)
#else
	#define cpAssertWarn(condition, message) if(!(condition)) cpMessage(message, #condition, __FILE__, __LINE__, 0)
#endif

#ifdef NDEBUG
	#define	cpAssert(condition, message)
#else
	#define cpAssert(condition, message) if(!(condition)) cpMessage(message, #condition, __FILE__, __LINE__, 1)
#endif

#include "chipmunk_types.h"

// Maximum allocated size for various Chipmunk buffers
#define CP_BUFFER_BYTES (32*1024)

#define cpmalloc malloc
#define cpcalloc calloc
#define cprealloc realloc
#define cpfree free

#include "cpVect.h"
#include "cpBB.h"
#include "cpArray.h"
#include "cpHashSet.h"
#include "cpSpaceHash.h"

#include "cpBody.h"
#include "cpShape.h"
#include "cpPolyShape.h"

#include "cpArbiter.h"
#include "cpCollision.h"

#include "constraints/cpConstraint.h"

#include "cpSpace.h"

#define CP_HASH_COEF (3344921057ul)
#define CP_HASH_PAIR(A, B) ((cpHashValue)(A)*CP_HASH_COEF ^ (cpHashValue)(B)*CP_HASH_COEF)

extern const char *cpVersionString;
void cpInitChipmunk(void);

/**
	Calculate the moment of inertia for a circle.
	r1 and r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
*/
cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset);

/**
	Calculate area of a hollow circle.
*/
cpFloat cpAreaForCircle(cpFloat r1, cpFloat r2);

/**
	Calculate the moment of inertia for a line segment.
	Beveling radius is not supported.
*/
cpFloat cpMomentForSegment(cpFloat m, cpVect a, cpVect b);

/**
	Calculate the area of a fattened (capsule shaped) line segment.
*/
cpFloat cpAreaForSegment(cpVect a, cpVect b, cpFloat r);

/**
	Calculate the moment of inertia for a solid polygon shape assuming it's center of gravity is at it's centroid. The offset is added to each vertex.
*/
cpFloat cpMomentForPoly(cpFloat m, int numVerts, const cpVect *verts, cpVect offset);

/**
	Calculate the signed area of a polygon.
*/
cpFloat cpAreaForPoly(const int numVerts, const cpVect *verts);

/**
	Calculate the natural centroid of a polygon.
*/
cpVect cpCentroidForPoly(const int numVerts, const cpVect *verts);

/**
	Center the polygon on the origin. (Subtracts the centroid of the polygon from each vertex)
*/
void cpRecenterPoly(const int numVerts, cpVect *verts);

/**
	Calculate the moment of inertia for a solid box.
*/
cpFloat cpMomentForBox(cpFloat m, cpFloat width, cpFloat height);

#ifdef __cplusplus
}

static inline cpVect operator *(const cpVect v, const cpFloat s){return cpvmult(v, s);}
static inline cpVect operator +(const cpVect v1, const cpVect v2){return cpvadd(v1, v2);}
static inline cpVect operator -(const cpVect v1, const cpVect v2){return cpvsub(v1, v2);}
static inline cpBool operator ==(const cpVect v1, const cpVect v2){return cpveql(v1, v2);}
static inline cpVect operator -(const cpVect v){return cpvneg(v);}

#endif

#endif


code:
// Create non static inlined copies of Chipmunk functions, useful for working with dynamic FFIs
// This file should only be included in chipmunk.c

#ifndef _CHIPMUNK_FFI_H_
#define _CHIPMUNK_FFI_H_

#ifdef _MSC_VER
 #if _MSC_VER >= 1600
  #define MAKE_REF(name) decltype(name) *_##name = name
 #else
  #define MAKE_REF(name)
 #endif
#else
 #define MAKE_REF(name) __typeof__(name) *_##name = name
#endif

MAKE_REF(cpv); // makes a variable named _cpv that contains the function pointer for cpv()
MAKE_REF(cpveql);
MAKE_REF(cpvadd);
MAKE_REF(cpvneg);
MAKE_REF(cpvsub);
MAKE_REF(cpvmult);
MAKE_REF(cpvdot);
MAKE_REF(cpvcross);
MAKE_REF(cpvperp);
MAKE_REF(cpvrperp);
MAKE_REF(cpvproject);
MAKE_REF(cpvrotate);
MAKE_REF(cpvunrotate);
MAKE_REF(cpvlengthsq);
MAKE_REF(cpvlerp);
MAKE_REF(cpvnormalize);
MAKE_REF(cpvnormalize_safe);
MAKE_REF(cpvclamp);
MAKE_REF(cpvlerpconst);
MAKE_REF(cpvdist);
MAKE_REF(cpvdistsq);
MAKE_REF(cpvnear);

MAKE_REF(cpBBNew);
MAKE_REF(cpBBintersects);
MAKE_REF(cpBBcontainsBB);
MAKE_REF(cpBBcontainsVect);
MAKE_REF(cpBBmerge);
MAKE_REF(cpBBexpand);

MAKE_REF(cpBodyWorld2Local);
MAKE_REF(cpBodyLocal2World);
MAKE_REF(cpBodyApplyImpulse);
MAKE_REF(cpBodyIsSleeping);
MAKE_REF(cpBodyIsRogue);
MAKE_REF(cpBodyKineticEnergy);

MAKE_REF(cpArbiterIsFirstContact);
MAKE_REF(cpArbiterGetShapes);
MAKE_REF(cpArbiterGetNormal);
MAKE_REF(cpArbiterGetPoint);

MAKE_REF(cpConstraintGetImpulse);

MAKE_REF(cpSegmentQueryHitPoint);
MAKE_REF(cpSegmentQueryHitDist);

#endif // _CHIPMUNK_FFI_H_


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#ifndef _CHIPMUNK_PRIVATE_H_
#define _CHIPMUNK_PRIVATE_H_

#define CP_ALLOW_PRIVATE_ACCESS 1
#include "chipmunk.h"

void *cpSpaceGetPostStepData(cpSpace *space, void *obj);

void cpSpaceActivateBody(cpSpace *space, cpBody *body);

static inline void
cpSpaceLock(cpSpace *space)
{
	space->locked++;
}

static inline void
cpSpaceUnlock(cpSpace *space)
{
	space->locked--;
	cpAssert(space->locked >= 0, "Internal error:Space lock underflow.");

	if(!space->locked){
		cpArray *waking = space->rousedBodies;
		for(int i=0, count=waking->num; i<count; i++){
			cpSpaceActivateBody(space, (cpBody *)waking->arr[i]);
		}

		waking->num = 0;
	}
}

#endif


code:
#ifndef _CHIPMUNK_TYPES_H_
#define _CHIPMUNK_TYPES_H_

#ifdef __APPLE__
#ifndef AIRPLAYUSECHIPMUNK
   #import "TargetConditionals.h"
#endif
#endif

// cocos2d-x: dont' use CGPoints to make your code multi-platform
// #if (defined TARGET_OS_IPHONE) && (!defined CP_USE_CGPOINTS)
//	#define CP_USE_CGPOINTS
// #endif

#ifdef CP_USE_CGPOINTS
	#if TARGET_OS_IPHONE
		#import <CoreGraphics/CGGeometry.h>
	#elif TARGET_OS_MAC
		#import <ApplicationServices/ApplicationServices.h>
	#endif

	#if defined(__LP64__) && __LP64__
		#define CP_USE_DOUBLES 1
	#else
		#define CP_USE_DOUBLES 0
	#endif
#endif

#ifndef CP_USE_DOUBLES
	// use doubles by default for higher precision
	// cocos2d-x: GL_DOUBLE isn't support on all platforms
	// #define CP_USE_DOUBLES 1
#endif

#if CP_USE_DOUBLES
	typedef double cpFloat;
	#define cpfsqrt sqrt
	#define cpfsin sin
	#define cpfcos cos
	#define cpfacos acos
	#define cpfatan2 atan2
	#define cpfmod fmod
	#define cpfexp exp
	#define cpfpow pow
	#define cpffloor floor
	#define cpfceil ceil
#else
	typedef float cpFloat;
	#define cpfsqrt sqrtf
	#define cpfsin sinf
	#define cpfcos cosf
	#define cpfacos acosf
	#define cpfatan2 atan2f
	#define cpfmod fmodf
	#define cpfexp expf
	#define cpfpow powf
	#define cpffloor floorf
	#define cpfceil ceilf
#endif

#ifndef INFINITY
	#ifdef _MSC_VER
		union MSVC_EVIL_FLOAT_HACK
		{
			unsigned __int8 Bytes[4];
			float Value;
		};
		static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}};
		#define INFINITY (INFINITY_HACK.Value)
	#endif

	#ifdef __GNUC__
		#define INFINITY (__builtin_inf())
	#endif

	#ifndef INFINITY
		#define INFINITY (1e1000)
	#endif
#endif

#ifndef M_PI
	#define M_PI 3.14159265358979323846264338327950288
#endif

#ifndef M_E
	#define M_E 2.71828182845904523536028747135266250
#endif

static inline cpFloat
cpfmax(cpFloat a, cpFloat b)
{
	return (a > b) ? a : b;
}

static inline cpFloat
cpfmin(cpFloat a, cpFloat b)
{
	return (a < b) ? a : b;
}

static inline cpFloat
cpfabs(cpFloat n)
{
	return (n < 0) ? -n : n;
}

static inline cpFloat
cpfclamp(cpFloat f, cpFloat min, cpFloat max)
{
	return cpfmin(cpfmax(f, min), max);
}

static inline cpFloat
cpflerp(cpFloat f1, cpFloat f2, cpFloat t)
{
	return f1*(1.0f - t) + f2*t;
}

static inline cpFloat
cpflerpconst(cpFloat f1, cpFloat f2, cpFloat d)
{
	return f1 + cpfclamp(f2 - f1, -d, d);
}

// CGPoints are structurally the same, and allow
// easy interoperability with other Cocoa libraries
#ifdef CP_USE_CGPOINTS
	typedef CGPoint cpVect;
#else
	typedef struct cpVect{cpFloat x,y;} cpVect;
#endif

typedef unsigned int cpHashValue;

// Oh C, how we love to define our own boolean types to get compiler compatibility
#ifdef CP_BOOL_TYPE
	typedef CP_BOOL_TYPE cpBool;
#else
	typedef int cpBool;
#endif

#ifndef cpTrue
	#define cpTrue 1
#endif

#ifndef cpFalse
	#define cpFalse 0
#endif

#ifdef CP_DATA_POINTER_TYPE
	typedef CP_DATA_POINTER_TYPE cpDataPointer;
#else
	typedef void * cpDataPointer;
#endif

#ifdef CP_COLLISION_TYPE_TYPE
	typedef CP_COLLISION_TYPE_TYPE cpCollisionType;
#else
	typedef unsigned int cpCollisionType;
#endif

#ifdef CP_GROUP_TYPE
	typedef CP_GROUP_TYPE cpGroup;
#else
	typedef unsigned int cpGroup;
#endif

#ifdef CP_LAYERS_TYPE
	typedef CP_LAYERS_TYPE cpLayers;
#else
	typedef unsigned int cpLayers;
#endif

#ifdef CP_TIMESTAMP_TYPE
	typedef CP_TIMESTAMP_TYPE cpTimestamp;
#else
	typedef unsigned int cpTimestamp;
#endif

#ifndef CP_NO_GROUP
	#define CP_NO_GROUP ((cpGroup)0)
#endif

#ifndef CP_ALL_LAYERS
	#define CP_ALL_LAYERS (~(cpLayers)0)
#endif

#endif // _CHIPMUNK_TYPES_H_


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/* This header defines a number of "unsafe" operations on Chipmunk objects.
 * In this case "unsafe" is referring to operations which may reduce the
 * physical accuracy or numerical stability of the simulation, but will not
 * cause crashes.
 *
 * The prime example is mutating collision shapes. Chipmunk does not support
 * this directly. Mutating shapes using this API will caused objects in contact
 * to be pushed apart using Chipmunk's overlap solver, but not using real
 * persistent velocities. Probably not what you meant, but perhaps close enough.
 */

#ifndef CHIPMUNK_UNSAFE_HEADER
#define CHIPMUNK_UNSAFE_HEADER

#ifdef __cplusplus
extern "C" {
#endif

void cpCircleShapeSetRadius(cpShape *shape, cpFloat radius);
void cpCircleShapeSetOffset(cpShape *shape, cpVect offset);

void cpSegmentShapeSetEndpoints(cpShape *shape, cpVect a, cpVect b);
void cpSegmentShapeSetRadius(cpShape *shape, cpFloat radius);

void cpPolyShapeSetVerts(cpShape *shape, int numVerts, cpVect *verts, cpVect offset);

#ifdef __cplusplus
}
#endif

#endif


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

// TODO: Comment me!

extern cpFloat cp_constraint_bias_coef;

struct cpConstraintClass;
struct cpConstraint;

typedef void (*cpConstraintPreStepFunction)(struct cpConstraint *constraint, cpFloat dt, cpFloat dt_inv);
typedef void (*cpConstraintApplyImpulseFunction)(struct cpConstraint *constraint);
typedef cpFloat (*cpConstraintGetImpulseFunction)(struct cpConstraint *constraint);

typedef struct cpConstraintClass {
	cpConstraintPreStepFunction preStep;
	cpConstraintApplyImpulseFunction applyImpulse;
	cpConstraintGetImpulseFunction getImpulse;
} cpConstraintClass;

typedef struct cpConstraint {
	CP_PRIVATE(const cpConstraintClass *klass);

	cpBody *a, *b;
	cpFloat maxForce;
	cpFloat biasCoef;
	cpFloat maxBias;

	cpDataPointer data;
} cpConstraint;

#ifdef CP_USE_DEPRECATED_API_4
typedef cpConstraint cpJoint;
#endif

void cpConstraintDestroy(cpConstraint *constraint);
void cpConstraintFree(cpConstraint *constraint);

static inline void
cpConstraintActivateBodies(cpConstraint *constraint)
{
	cpBody *a = constraint->a; if(a) cpBodyActivate(a);
	cpBody *b = constraint->b; if(b) cpBodyActivate(b);
}

static inline cpFloat
cpConstraintGetImpulse(cpConstraint *constraint)
{
	return constraint->CP_PRIVATE(klass)->getImpulse(constraint);
}

#define cpConstraintCheckCast(constraint, struct) \
	cpAssert(constraint->CP_PRIVATE(klass) == struct##GetClass(), "Constraint is not a "#struct);

#define CP_DefineConstraintGetter(struct, type, member, name) \
static inline type \
struct##Get##name(const cpConstraint *constraint){ \
	cpConstraintCheckCast(constraint, struct); \
	return ((struct *)constraint)->member; \
} \

#define CP_DefineConstraintSetter(struct, type, member, name) \
static inline void \
struct##Set##name(cpConstraint *constraint, type value){ \
	cpConstraintCheckCast(constraint, struct); \
	cpConstraintActivateBodies(constraint); \
	((struct *)constraint)->member = value; \
} \

#define CP_DefineConstraintProperty(struct, type, member, name) \
CP_DefineConstraintGetter(struct, type, member, name) \
CP_DefineConstraintSetter(struct, type, member, name)

// Built in Joint types
#include "cpPinJoint.h"
#include "cpSlideJoint.h"
#include "cpPivotJoint.h"
#include "cpGrooveJoint.h"
#include "cpDampedSpring.h"
#include "cpDampedRotarySpring.h"
#include "cpRotaryLimitJoint.h"
#include "cpRatchetJoint.h"
#include "cpGearJoint.h"
#include "cpSimpleMotor.h"


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

typedef cpFloat (*cpDampedRotarySpringTorqueFunc)(struct cpConstraint *spring, cpFloat relativeAngle);

const cpConstraintClass *cpDampedRotarySpringGetClass();

typedef struct cpDampedRotarySpring {
	cpConstraint constraint;
	cpFloat restAngle;
	cpFloat stiffness;
	cpFloat damping;
	cpDampedRotarySpringTorqueFunc springTorqueFunc;

	cpFloat target_wrn;
	cpFloat w_coef;

	cpFloat iSum;
} cpDampedRotarySpring;

cpDampedRotarySpring *cpDampedRotarySpringAlloc(void);
cpDampedRotarySpring *cpDampedRotarySpringInit(cpDampedRotarySpring *joint, cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping);
cpConstraint *cpDampedRotarySpringNew(cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping);

CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, restAngle, RestAngle);
CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, stiffness, Stiffness);
CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, damping, Damping);
CP_DefineConstraintProperty(cpDampedRotarySpring, cpDampedRotarySpringTorqueFunc, springTorqueFunc, SpringTorqueFunc);


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

struct cpDampedSpring;

typedef cpFloat (*cpDampedSpringForceFunc)(struct cpConstraint *spring, cpFloat dist);

const cpConstraintClass *cpDampedSpringGetClass();

typedef struct cpDampedSpring {
	cpConstraint constraint;
	cpVect anchr1, anchr2;
	cpFloat restLength;
	cpFloat stiffness;
	cpFloat damping;
	cpDampedSpringForceFunc springForceFunc;

	cpFloat target_vrn;
	cpFloat v_coef;

	cpVect r1, r2;
	cpFloat nMass;
	cpVect n;
} cpDampedSpring;

cpDampedSpring *cpDampedSpringAlloc(void);
cpDampedSpring *cpDampedSpringInit(cpDampedSpring *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping);
cpConstraint *cpDampedSpringNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping);

CP_DefineConstraintProperty(cpDampedSpring, cpVect, anchr1, Anchr1);
CP_DefineConstraintProperty(cpDampedSpring, cpVect, anchr2, Anchr2);
CP_DefineConstraintProperty(cpDampedSpring, cpFloat, restLength, RestLength);
CP_DefineConstraintProperty(cpDampedSpring, cpFloat, stiffness, Stiffness);
CP_DefineConstraintProperty(cpDampedSpring, cpFloat, damping, Damping);
CP_DefineConstraintProperty(cpDampedSpring, cpDampedSpringForceFunc, springForceFunc, SpringForceFunc);


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

const cpConstraintClass *cpGearJointGetClass();

typedef struct cpGearJoint {
	cpConstraint constraint;
	cpFloat phase, ratio;
	cpFloat ratio_inv;

	cpFloat iSum;

	cpFloat bias;
	cpFloat jAcc, jMax;
} cpGearJoint;

cpGearJoint *cpGearJointAlloc(void);
cpGearJoint *cpGearJointInit(cpGearJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio);
cpConstraint *cpGearJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio);

CP_DefineConstraintProperty(cpGearJoint, cpFloat, phase, Phase);
CP_DefineConstraintGetter(cpGearJoint, cpFloat, ratio, Ratio);
void cpGearJointSetRatio(cpConstraint *constraint, cpFloat value);


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

const cpConstraintClass *cpGrooveJointGetClass();

typedef struct cpGrooveJoint {
	cpConstraint constraint;
	cpVect grv_n, grv_a, grv_b;
	cpVect  anchr2;

	cpVect grv_tn;
	cpFloat clamp;
	cpVect r1, r2;
	cpVect k1, k2;

	cpVect jAcc;
	cpFloat jMaxLen;
	cpVect bias;
} cpGrooveJoint;

cpGrooveJoint *cpGrooveJointAlloc(void);
cpGrooveJoint *cpGrooveJointInit(cpGrooveJoint *joint, cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2);
cpConstraint *cpGrooveJointNew(cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2);

CP_DefineConstraintGetter(cpGrooveJoint, cpVect, grv_a, GrooveA);
void cpGrooveJointSetGrooveA(cpConstraint *constraint, cpVect value);
CP_DefineConstraintGetter(cpGrooveJoint, cpVect, grv_b, GrooveB);
void cpGrooveJointSetGrooveB(cpConstraint *constraint, cpVect value);
CP_DefineConstraintProperty(cpGrooveJoint, cpVect, anchr2, Anchr2);


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

const cpConstraintClass *cpPinJointGetClass();

typedef struct cpPinJoint {
	cpConstraint constraint;
	cpVect anchr1, anchr2;
	cpFloat dist;

	cpVect r1, r2;
	cpVect n;
	cpFloat nMass;

	cpFloat jnAcc, jnMax;
	cpFloat bias;
} cpPinJoint;

cpPinJoint *cpPinJointAlloc(void);
cpPinJoint *cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
cpConstraint *cpPinJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);

CP_DefineConstraintProperty(cpPinJoint, cpVect, anchr1, Anchr1);
CP_DefineConstraintProperty(cpPinJoint, cpVect, anchr2, Anchr2);
CP_DefineConstraintProperty(cpPinJoint, cpFloat, dist, Dist);


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

const cpConstraintClass *cpPivotJointGetClass();

typedef struct cpPivotJoint {
	cpConstraint constraint;
	cpVect anchr1, anchr2;

	cpVect r1, r2;
	cpVect k1, k2;

	cpVect jAcc;
	cpFloat jMaxLen;
	cpVect bias;
} cpPivotJoint;

cpPivotJoint *cpPivotJointAlloc(void);
cpPivotJoint *cpPivotJointInit(cpPivotJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
cpConstraint *cpPivotJointNew(cpBody *a, cpBody *b, cpVect pivot);
cpConstraint *cpPivotJointNew2(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);

CP_DefineConstraintProperty(cpPivotJoint, cpVect, anchr1, Anchr1);
CP_DefineConstraintProperty(cpPivotJoint, cpVect, anchr2, Anchr2);


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

const cpConstraintClass *cpRatchetJointGetClass();

typedef struct cpRatchetJoint {
	cpConstraint constraint;
	cpFloat angle, phase, ratchet;

	cpFloat iSum;

	cpFloat bias;
	cpFloat jAcc, jMax;
} cpRatchetJoint;

cpRatchetJoint *cpRatchetJointAlloc(void);
cpRatchetJoint *cpRatchetJointInit(cpRatchetJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);
cpConstraint *cpRatchetJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);

CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, angle, Angle);
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, phase, Phase);
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, ratchet, Ratchet);


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

const cpConstraintClass *cpRotaryLimitJointGetClass();

typedef struct cpRotaryLimitJoint {
	cpConstraint constraint;
	cpFloat min, max;

	cpFloat iSum;

	cpFloat bias;
	cpFloat jAcc, jMax;
} cpRotaryLimitJoint;

cpRotaryLimitJoint *cpRotaryLimitJointAlloc(void);
cpRotaryLimitJoint *cpRotaryLimitJointInit(cpRotaryLimitJoint *joint, cpBody *a, cpBody *b, cpFloat min, cpFloat max);
cpConstraint *cpRotaryLimitJointNew(cpBody *a, cpBody *b, cpFloat min, cpFloat max);

CP_DefineConstraintProperty(cpRotaryLimitJoint, cpFloat, min, Min);
CP_DefineConstraintProperty(cpRotaryLimitJoint, cpFloat, max, Max);


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

const cpConstraintClass *cpSimpleMotorGetClass();

typedef struct cpSimpleMotor {
	cpConstraint constraint;
	cpFloat rate;

	cpFloat iSum;

	cpFloat jAcc, jMax;
} cpSimpleMotor;

cpSimpleMotor *cpSimpleMotorAlloc(void);
cpSimpleMotor *cpSimpleMotorInit(cpSimpleMotor *joint, cpBody *a, cpBody *b, cpFloat rate);
cpConstraint *cpSimpleMotorNew(cpBody *a, cpBody *b, cpFloat rate);

CP_DefineConstraintProperty(cpSimpleMotor, cpFloat, rate, Rate);


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

const cpConstraintClass *cpSlideJointGetClass();

typedef struct cpSlideJoint {
	cpConstraint constraint;
	cpVect anchr1, anchr2;
	cpFloat min, max;

	cpVect r1, r2;
	cpVect n;
	cpFloat nMass;

	cpFloat jnAcc, jnMax;
	cpFloat bias;
} cpSlideJoint;

cpSlideJoint *cpSlideJointAlloc(void);
cpSlideJoint *cpSlideJointInit(cpSlideJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max);
cpConstraint *cpSlideJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max);

CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr1, Anchr1);
CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr2, Anchr2);
CP_DefineConstraintProperty(cpSlideJoint, cpFloat, min, Min);
CP_DefineConstraintProperty(cpSlideJoint, cpFloat, max, Max);


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#define CP_DefineClassGetter(t)													\
const cpConstraintClass * t##GetClass(void);									\
const cpConstraintClass * t##GetClass(){return (cpConstraintClass *)&klass;}

void cpConstraintInit(cpConstraint *constraint, const cpConstraintClass *klass, cpBody *a, cpBody *b);

#define J_MAX(constraint, dt) (((cpConstraint *)constraint)->maxForce*(dt))

// Get valid body pointers and exit early if the bodies are idle
#define CONSTRAINT_BEGIN(constraint, a_var, b_var) \
cpBody *a_var, *b_var; { \
	a_var = ((cpConstraint *)constraint)->a; \
	b_var = ((cpConstraint *)constraint)->b; \
	if( \
		(cpBodyIsSleeping(a_var) || cpBodyIsStatic(a_var)) && \
		(cpBodyIsSleeping(b_var) || cpBodyIsStatic(b_var)) \
	) return; \
}

static inline cpVect
relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2){
	cpVect v1_sum = cpvadd(a->v, cpvmult(cpvperp(r1), a->w));
	cpVect v2_sum = cpvadd(b->v, cpvmult(cpvperp(r2), b->w));

	return cpvsub(v2_sum, v1_sum);
}

static inline cpFloat
normal_relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n){
	return cpvdot(relative_velocity(a, b, r1, r2), n);
}

static inline void
apply_impulse(cpBody *body, cpVect j, cpVect r){
	body->v = cpvadd(body->v, cpvmult(j, body->m_inv));
	body->w += body->i_inv*cpvcross(r, j);
}

static inline void
apply_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
{
	apply_impulse(a, cpvneg(j), r1);
	apply_impulse(b, j, r2);
}

static inline void
apply_bias_impulse(cpBody *body, cpVect j, cpVect r)
{
	body->v_bias = cpvadd(body->v_bias, cpvmult(j, body->m_inv));
	body->w_bias += body->i_inv*cpvcross(r, j);
}

static inline void
apply_bias_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
{
	apply_bias_impulse(a, cpvneg(j), r1);
	apply_bias_impulse(b, j, r2);
}

static inline cpVect
clamp_vect(cpVect v, cpFloat len)
{
	return cpvclamp(v, len);
//	return (cpvdot(v,v) > len*len) ? cpvmult(cpvnormalize(v), len) : v;
}

static inline cpFloat
k_scalar(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n)
{
	cpFloat mass_sum = a->m_inv + b->m_inv;
	cpFloat r1cn = cpvcross(r1, n);
	cpFloat r2cn = cpvcross(r2, n);

	cpFloat value = mass_sum + a->i_inv*r1cn*r1cn + b->i_inv*r2cn*r2cn;
	cpAssert(value != 0.0, "Unsolvable collision or constraint.");

	return value;
}

static inline void
k_tensor(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect *k1, cpVect *k2)
{
	// calculate mass matrix
	// If I wasn't lazy and wrote a proper matrix class, this wouldn't be so gross...
	cpFloat k11, k12, k21, k22;
	cpFloat m_sum = a->m_inv + b->m_inv;

	// start with I*m_sum
	k11 = m_sum; k12 = 0.0f;
	k21 = 0.0f;  k22 = m_sum;

	// add the influence from r1
	cpFloat a_i_inv = a->i_inv;
	cpFloat r1xsq =  r1.x * r1.x * a_i_inv;
	cpFloat r1ysq =  r1.y * r1.y * a_i_inv;
	cpFloat r1nxy = -r1.x * r1.y * a_i_inv;
	k11 += r1ysq; k12 += r1nxy;
	k21 += r1nxy; k22 += r1xsq;

	// add the influnce from r2
	cpFloat b_i_inv = b->i_inv;
	cpFloat r2xsq =  r2.x * r2.x * b_i_inv;
	cpFloat r2ysq =  r2.y * r2.y * b_i_inv;
	cpFloat r2nxy = -r2.x * r2.y * b_i_inv;
	k11 += r2ysq; k12 += r2nxy;
	k21 += r2nxy; k22 += r2xsq;

	// invert
	cpFloat determinant = k11*k22 - k12*k21;
	cpAssert(determinant != 0.0, "Unsolvable constraint.");

	cpFloat det_inv = 1.0f/determinant;
	*k1 = cpv( k22*det_inv, -k12*det_inv);
	*k2 = cpv(-k21*det_inv,  k11*det_inv);
}

static inline cpVect
mult_k(cpVect vr, cpVect k1, cpVect k2)
{
	return cpv(cpvdot(vr, k1), cpvdot(vr, k2));
}


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

 struct cpArbiter;
 struct cpSpace;
 struct cpCollisionHandler;

// Determines how fast penetrations resolve themselves.
extern cpFloat cp_bias_coef;
// Amount of allowed penetration. Used to reduce vibrating contacts.
extern cpFloat cp_collision_slop;

// Data structure for contact points.
typedef struct cpContact {
	// Contact point and normal.
	cpVect CP_PRIVATE(p), CP_PRIVATE(n);
	// Penetration distance.
	CP_PRIVATE(cpFloat dist);

	// Calculated by cpArbiterPreStep().
	cpVect CP_PRIVATE(r1), CP_PRIVATE(r2);
	cpFloat CP_PRIVATE(nMass), CP_PRIVATE(tMass), CP_PRIVATE(bounce);

	// Persistant contact information.
	cpFloat CP_PRIVATE(jnAcc), CP_PRIVATE(jtAcc), CP_PRIVATE(jBias);
	CP_PRIVATE(cpFloat bias);

	// Hash value used to (mostly) uniquely identify a contact.
	CP_PRIVATE(cpHashValue hash);
} cpContact;

// Contacts are always allocated in groups.
cpContact* cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash);

// Sum the contact impulses. (Can be used after cpSpaceStep() returns)
cpVect CP_PRIVATE(cpContactsSumImpulses)(cpContact *contacts, int numContacts);
cpVect CP_PRIVATE(cpContactsSumImpulsesWithFriction)(cpContact *contacts, int numContacts);

#define CP_MAX_CONTACTS_PER_ARBITER 6

typedef enum cpArbiterState {
	cpArbiterStateNormal,
	cpArbiterStateFirstColl,
	cpArbiterStateIgnore,
	cpArbiterStateSleep,
	cpArbiterStateCached,
} cpArbiterState;

// Data structure for tracking collisions between shapes.
typedef struct cpArbiter {
	// Information on the contact points between the objects.
	CP_PRIVATE(int numContacts);
	CP_PRIVATE(cpContact *contacts);

	// The two shapes and bodies involved in the collision.
	// These variables are NOT in the order defined by the collision handler.
	// Using CP_ARBITER_GET_SHAPES and CP_ARBITER_GET_BODIES will save you from
	// many headaches
	cpShape CP_PRIVATE(*a), CP_PRIVATE(*b);

	// Calculated before calling the pre-solve collision handler
	// Override them with custom values if you want specialized behavior
	CP_PRIVATE(cpFloat e);
	CP_PRIVATE(cpFloat u);
	 // Used for surface_v calculations, implementation may change
	CP_PRIVATE(cpVect surface_vr);

	// Time stamp of the arbiter. (from cpSpace)
	CP_PRIVATE(cpTimestamp stamp);

	CP_PRIVATE(struct cpCollisionHandler *handler);

	// Are the shapes swapped in relation to the collision handler?
	CP_PRIVATE(cpBool swappedColl);
	CP_PRIVATE(cpArbiterState state);
} cpArbiter;

// Arbiters are allocated in large buffers by the space and don't require a destroy function
cpArbiter* CP_PRIVATE(cpArbiterInit)(cpArbiter *arb, cpShape *a, cpShape *b);

// These functions are all intended to be used internally.
// Inject new contact points into the arbiter while preserving contact history.
void CP_PRIVATE(cpArbiterUpdate)(cpArbiter *arb, cpContact *contacts, int numContacts, struct cpCollisionHandler *handler, cpShape *a, cpShape *b);
// Precalculate values used by the solver.
void CP_PRIVATE(cpArbiterPreStep)(cpArbiter *arb, cpFloat dt_inv);
void CP_PRIVATE(cpArbiterApplyCachedImpulse)(cpArbiter *arb);
// Run an iteration of the solver on the arbiter.
void CP_PRIVATE(cpArbiterApplyImpulse)(cpArbiter *arb, cpFloat eCoef);

// Arbiter Helper Functions
cpVect cpArbiterTotalImpulse(cpArbiter *arb);
cpVect cpArbiterTotalImpulseWithFriction(cpArbiter *arb);
void cpArbiterIgnore(cpArbiter *arb);

static inline void
cpArbiterGetShapes(const cpArbiter *arb, cpShape **a, cpShape **b)
{
	if(arb->CP_PRIVATE(swappedColl)){
		(*a) = arb->CP_PRIVATE(b), (*b) = arb->CP_PRIVATE(a);
	} else {
		(*a) = arb->CP_PRIVATE(a), (*b) = arb->CP_PRIVATE(b);
	}
}
#define CP_ARBITER_GET_SHAPES(arb, a, b) cpShape *a, *b; cpArbiterGetShapes(arb, &a, &b);

static inline void
cpArbiterGetBodies(const cpArbiter *arb, cpBody **a, cpBody **b)
{
	CP_ARBITER_GET_SHAPES(arb, shape_a, shape_b);
	(*a) = shape_a->body;
	(*b) = shape_b->body;
}
#define CP_ARBITER_GET_BODIES(arb, a, b) cpBody *a, *b; cpArbiterGetBodies(arb, &a, &b);

static inline cpBool
cpArbiterIsFirstContact(const cpArbiter *arb)
{
	return arb->CP_PRIVATE(state) == cpArbiterStateFirstColl;
}

static inline int
cpArbiterGetCount(const cpArbiter *arb)
{
	return arb->CP_PRIVATE(numContacts);
}

static inline cpVect
cpArbiterGetNormal(const cpArbiter *arb, int i)
{
	cpVect n = arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(n);
	return arb->CP_PRIVATE(swappedColl) ? cpvneg(n) : n;
}

static inline cpVect
cpArbiterGetPoint(const cpArbiter *arb, int i)
{
	return arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(p);
}

static inline cpFloat
cpArbiterGetDepth(const cpArbiter *arb, int i)
{
	return arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(dist);
}

typedef struct cpContactPointSet {
	int count;

	struct {
		cpVect point, normal;
		cpFloat dist;
	} points[CP_MAX_CONTACTS_PER_ARBITER];
} cpContactPointSet;

static inline cpContactPointSet
cpArbiterGetContactPointSet(const cpArbiter *arb)
{
	cpContactPointSet set;
	set.count = cpArbiterGetCount(arb);

	int i;
	for(i=0; i<set.count; i++){
		set.points[i].point = arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(p);
		set.points[i].normal = arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(n);
		set.points[i].dist = arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(dist);
	}

	return set;
}


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

// NOTE: cpArray is rarely used and will probably go away.

typedef struct cpArray{
	CP_PRIVATE(int num);
	CP_PRIVATE(int max);
	CP_PRIVATE(void **arr);
} cpArray;

typedef void (*cpArrayIter)(void *ptr, void *data);

cpArray *cpArrayAlloc(void);
cpArray *cpArrayInit(cpArray *arr, int size);
cpArray *cpArrayNew(int size);

void cpArrayDestroy(cpArray *arr);
void cpArrayFree(cpArray *arr);

void cpArrayClear(cpArray *arr);

void cpArrayPush(cpArray *arr, void *object);
void *cpArrayPop(cpArray *arr);
void cpArrayDeleteIndex(cpArray *arr, int idx);
void cpArrayDeleteObj(cpArray *arr, void *obj);

void cpArrayAppend(cpArray *arr, cpArray *other);

void cpArrayEach(cpArray *arr, cpArrayIter iterFunc, void *data);
cpBool cpArrayContains(cpArray *arr, void *ptr);


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

typedef struct cpBB{
	cpFloat l, b, r ,t;
} cpBB;

static inline cpBB
cpBBNew(const cpFloat l, const cpFloat b,
		const cpFloat r, const cpFloat t)
{
	cpBB bb = {l, b, r, t};
	return bb;
}

static inline cpBool
cpBBintersects(const cpBB a, const cpBB b)
{
	return (a.l<=b.r && b.l<=a.r && a.b<=b.t && b.b<=a.t);
}

static inline cpBool
cpBBcontainsBB(const cpBB bb, const cpBB other)
{
	return (bb.l < other.l && bb.r > other.r && bb.b < other.b && bb.t > other.t);
}

static inline cpBool
cpBBcontainsVect(const cpBB bb, const cpVect v)
{
	return (bb.l < v.x && bb.r > v.x && bb.b < v.y && bb.t > v.y);
}

static inline cpBB
cpBBmerge(const cpBB a, const cpBB b){
	return cpBBNew(
		cpfmin(a.l, b.l),
		cpfmin(a.b, b.b),
		cpfmax(a.r, b.r),
		cpfmax(a.t, b.t)
	);
}

static inline cpBB
cpBBexpand(const cpBB bb, const cpVect v){
	return cpBBNew(
		cpfmin(bb.l, v.x),
		cpfmin(bb.b, v.y),
		cpfmax(bb.r, v.x),
		cpfmax(bb.t, v.y)
	);
}

cpVect cpBBClampVect(const cpBB bb, const cpVect v); // clamps the vector to lie within the bbox
// TODO edge case issue
cpVect cpBBWrapVect(const cpBB bb, const cpVect v); // wrap a vector to a bbox


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

struct cpBody;
struct cpShape;
struct cpSpace;

typedef void (*cpBodyVelocityFunc)(struct cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);
typedef void (*cpBodyPositionFunc)(struct cpBody *body, cpFloat dt);

extern cpBodyVelocityFunc cpBodyUpdateVelocityDefault;
extern cpBodyPositionFunc cpBodyUpdatePositionDefault;

// Structure to hold information about the contact graph components
// when putting groups of objects to sleep.
// No interesting user accessible fields.
typedef struct cpComponentNode {
	struct cpBody *parent;
	struct cpBody *next;
	int rank;
	cpFloat idleTime;
} cpComponentNode;

typedef struct cpBody{
	// *** Integration Functions.

	// Function that is called to integrate the body's velocity. (Defaults to cpBodyUpdateVelocity)
	cpBodyVelocityFunc velocity_func;

	// Function that is called to integrate the body's position. (Defaults to cpBodyUpdatePosition)
	cpBodyPositionFunc position_func;

	// *** Mass Properties

	// Mass and it's inverse.
	// Always use cpBodySetMass() whenever changing the mass as these values must agree.
	cpFloat m, m_inv;

	// Moment of inertia and it's inverse.
	// Always use cpBodySetMoment() whenever changing the moment as these values must agree.
	cpFloat i, i_inv;

	// *** Positional Properties

	// Linear components of motion (position, velocity, and force)
	cpVect p, v, f;

	// Angular components of motion (angle, angular velocity, and torque)
	// Always use cpBodySetAngle() to set the angle of the body as a and rot must agree.
	cpFloat a, w, t;

	// Cached unit length vector representing the angle of the body.
	// Used for fast vector rotation using cpvrotate().
	cpVect rot;

	// *** User Definable Fields

	// User defined data pointer.
	cpDataPointer data;

	// *** Other Fields

	// Maximum velocities this body can move at after integrating velocity
	cpFloat v_limit, w_limit;

	// *** Internally Used Fields

	// Velocity bias values used when solving penetrations and correcting constraints.
	CP_PRIVATE(cpVect v_bias);
	CP_PRIVATE(cpFloat w_bias);

	// Space this body has been added to
	CP_PRIVATE(struct cpSpace *space);

	// Pointer to the shape list.
	// Shapes form a linked list using cpShape.next when added to a space.
	CP_PRIVATE(struct cpShape *shapesList);

	// Used by cpSpaceStep() to store contact graph information.
	CP_PRIVATE(cpComponentNode node);
} cpBody;

// Basic allocation/destruction functions
cpBody *cpBodyAlloc(void);
cpBody *cpBodyInit(cpBody *body, cpFloat m, cpFloat i);
cpBody *cpBodyNew(cpFloat m, cpFloat i);

cpBody *cpBodyInitStatic(cpBody *body);
cpBody *cpBodyNewStatic();

void cpBodyDestroy(cpBody *body);
void cpBodyFree(cpBody *body);

// Wake up a sleeping or idle body. (defined in cpSpace.c)
void cpBodyActivate(cpBody *body);

// Force a body to sleep;
// defined in cpSpaceComponent.c
void cpBodySleep(cpBody *body);
void cpBodySleepWithGroup(cpBody *body, cpBody *group);

static inline cpBool
cpBodyIsSleeping(const cpBody *body)
{
	return (CP_PRIVATE(body->node).next != ((cpBody*)0));
}

static inline cpBool
cpBodyIsStatic(const cpBody *body)
{
	return CP_PRIVATE(body->node).idleTime == INFINITY;
}

static inline cpBool
cpBodyIsRogue(const cpBody *body)
{
	return (body->CP_PRIVATE(space) == ((struct cpSpace*)0));
}

#define CP_DefineBodyGetter(type, member, name) \
static inline type cpBodyGet##name(const cpBody *body){return body->member;}

#define CP_DefineBodySetter(type, member, name) \
static inline void \
cpBodySet##name(cpBody *body, const type value){ \
	cpBodyActivate(body); \
	body->member = value; \
} \

#define CP_DefineBodyProperty(type, member, name) \
CP_DefineBodyGetter(type, member, name) \
CP_DefineBodySetter(type, member, name)

// Accessors for cpBody struct members
CP_DefineBodyGetter(cpFloat, m, Mass);
void cpBodySetMass(cpBody *body, cpFloat m);

CP_DefineBodyGetter(cpFloat, i, Moment);
void cpBodySetMoment(cpBody *body, cpFloat i);

CP_DefineBodyProperty(cpVect, p, Pos);
CP_DefineBodyProperty(cpVect, v, Vel);
CP_DefineBodyProperty(cpVect, f, Force);
CP_DefineBodyGetter(cpFloat, a, Angle);
void cpBodySetAngle(cpBody *body, cpFloat a);
CP_DefineBodyProperty(cpFloat, w, AngVel);
CP_DefineBodyProperty(cpFloat, t, Torque);
CP_DefineBodyGetter(cpVect, rot, Rot);
CP_DefineBodyProperty(cpFloat, v_limit, VelLimit);
CP_DefineBodyProperty(cpFloat, w_limit, AngVelLimit);

//  Modify the velocity of the body so that it will move to the specified absolute coordinates in the next timestep.
// Intended for objects that are moved manually with a custom velocity integration function.
void cpBodySlew(cpBody *body, cpVect pos, cpFloat dt);

// Default Integration functions.
void cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);
void cpBodyUpdatePosition(cpBody *body, cpFloat dt);

// Convert body local to world coordinates
static inline cpVect
cpBodyLocal2World(const cpBody *body, const cpVect v)
{
	return cpvadd(body->p, cpvrotate(v, body->rot));
}

// Convert world to body local coordinates
static inline cpVect
cpBodyWorld2Local(const cpBody *body, const cpVect v)
{
	return cpvunrotate(cpvsub(v, body->p), body->rot);
}

// Zero the forces on a body.
void cpBodyResetForces(cpBody *body);
// Apply a force (in world coordinates) to a body at a point relative to the center of gravity (also in world coordinates).
void cpBodyApplyForce(cpBody *body, const cpVect f, const cpVect r);
// Apply an impulse (in world coordinates) to the body at a point relative to the center of gravity (also in world coordinates).
void cpBodyApplyImpulse(cpBody *body, const cpVect j, const cpVect r);

static inline cpFloat
cpBodyKineticEnergy(const cpBody *body)
{
	// Need to do some fudging to avoid NaNs
	cpFloat vsq = cpvdot(body->v, body->v);
	cpFloat wsq = body->w*body->w;
	return (vsq ? vsq*body->m : 0.0f) + (wsq ? wsq*body->i : 0.0f);
}

// Apply a damped spring force between two bodies.
// Warning: Large damping values can be unstable. Use a cpDampedSpring constraint for this instead.
void cpApplyDampedSpring(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat rlen, cpFloat k, cpFloat dmp, cpFloat dt);


code:
/* Copyright (c) 2007 Scott Lembcke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

//TODO delete this header?

// Collides two cpShape structures.
// Returns the number of contact points added to arr
// which should be at least CP_MAX_CONTACTS_PER_ARBITER in length.
// This function is very lonely in this header :(
int cpCollideShapes(const cpShape *a, const cpShape *b, cpContact *arr);