getSupportFn = function getSupportFn( bodyA, bodyB ){

        var hash = Physics.util.pairHash( bodyA.uid, bodyB.uid )
            ,fn = supportFnStack[ hash ]
            ;

        if ( !fn ){
            fn = supportFnStack[ hash ] = function pairSupportFunction( searchDir ){

                var tA = fn.tA
                    ,tB = fn.tB
                    ,vA = fn.tmpv1
                    ,vB = fn.tmpv2
                    ;

                if ( fn.useCore ){
                    vA = bodyA.geometry.getFarthestCorePoint( searchDir.rotateInv( tA ), vA, fn.marginA );
                    vB = bodyB.geometry.getFarthestCorePoint( searchDir.rotate( tA ).rotateInv( tB ).negate(), vB, fn.marginB );
                } else {
                    vA = bodyA.geometry.getFarthestHullPoint( searchDir.rotateInv( tA ), vA );
                    vB = bodyB.geometry.getFarthestHullPoint( searchDir.rotate( tA ).rotateInv( tB ).negate(), vB );
                }

                vA.vadd( bodyA.offset ).transform( tA );
                vB.vadd( bodyB.offset ).transform( tB );
                searchDir.negate().rotate( tB );

                return {
                    a: vA.values(),
                    b: vB.values(),
                    pt: vA.vsub( vB ).values()
                };
            };

            // transforms for coordinate transformations
            fn.tA = new Physics.transform();
            fn.tB = new Physics.transform();

            // temp vectors (used too frequently to justify scratchpad)
            fn.tmpv1 = new Physics.vector();
            fn.tmpv2 = new Physics.vector();
        }

        fn.useCore = false;
        fn.margin = 0;
        fn.tA.setRotation( bodyA.state.angular.pos ).setTranslation( bodyA.state.pos );
        fn.tB.setRotation( bodyB.state.angular.pos ).setTranslation( bodyB.state.pos );
        fn.bodyA = bodyA;
        fn.bodyB = bodyB;

        return fn;
    }
class BodyCollisionDetectionBehavior < Behavior

`Physics.behavior('body-collision-detection')`.

Detect collisions of bodies.

Publishes collision events to the world as a group of detected collisions per iteration.

The event data will have a `.collisions` property that is an array of collisions of the form:

```javascript
{
    bodyA: // the first body
    bodyB: // the second body
    norm: // the normal vector (Vectorish)
    mtv: // the minimum transit vector. (the direction and length needed to extract bodyB from bodyA)
    pos: // the collision point relative to bodyA
    overlap: // the amount bodyA overlaps bodyB
}
```

Additional options include:
- check: channel to listen to for collision candidates (default: `collisions:candidates`). set to `true` to force check every pair of bodies in the world
- channel: channel to publish events to (default: `collisions:detected`)