collision-detection 0.8.1

A generic collision detection library based on the `collide` crate
Documentation
# collision-detection

Collision management on top of the `collide` crate.

## Design decisions

**Efficiency is preferred over safety.** This is the guiding trade-off for this
crate — when a safety net costs runtime or memory, it stays out.

- `ColliderId` is a raw `slab` handle, deliberately **not** generational. After
  `remove_collider`, the slot is recycled: a stale `ColliderId` silently
  addresses whatever collider now occupies that slot. Keeping ids valid is the
  caller's job. Do not propose `slotmap` or a generation counter — the cost was
  weighed and rejected.

**The six `compute_*` methods stay explicit.** They form a 3×2 matrix
(brute-force / spatial / BVH × inner / cross), and every cell is a genuinely
different algorithm, not duplicated boilerplate:

- `inner` iterates triangularly (`i+1..`, no self-pairs) and pushes
  bidirectionally (`info` and `-info`); `cross` walks the full product of two
  sets and pushes unidirectionally.
- `inner` therefore needs `C::Vector: Neg`, `cross` never does.

Generalising over the strategy (a `CollisionMethod` trait) or over the mode (an
`enum Target`) was considered and rejected: it would hide the differences behind
a trait bound or a match arm without removing any code, and the strategy axis
would force `cross` to carry `inner`'s `Neg` bound.

## Acceleration structures are rebuilt per call

`cell_map` and the BVH are built from scratch on every `compute_*_spatial` /
`compute_*_bvh` call. This suits layers whose colliders move each frame. A
prepared/cached variant for static layers is a possible future addition.