collide-mesh 0.1.0

Triangle mesh collider for the collide crate (3D)
Documentation
# collide-mesh

[![crates.io](https://img.shields.io/crates/v/collide-mesh)](https://crates.io/crates/collide-mesh)
[![docs.rs](https://img.shields.io/docsrs/collide-mesh)](https://docs.rs/collide-mesh)

Triangle mesh collision for character controllers: capsule-vs-mesh resolution with ground classification, plus raycasts. Built for walkable level geometry loaded from triangle meshes (glTF and similar).

Unlike the rest of the collide ecosystem, this crate is **deliberately 3D-only** and uses `ga3::Vector<f32>` directly: triangle meshes have no meaningful N-dimensional generalization, and Y-up ground semantics (walkable slopes, ground height) are inherently 3D gameplay concepts. The dimension-generic core traits of `collide` remain untouched by this exception.

## Features

- `TriangleMesh`: built from raw vertex positions and indices; degenerate triangles are skipped; per-face normals; automatic BVH above 16 triangles.
- `CollisionWorld`: a set of meshes behind a second BVH level. `collide_capsule` resolves a vertical capsule against all meshes and reports ground contact (walkable if the face normal's Y exceeds 0.5), the supporting ground height and normal, and an accumulated push vector out of steep geometry. `raycast` returns the closest hit distance.
- Robust against degenerate input: zero-area triangles, broken indices and zero-length segments are tolerated.

## Usage

```rust
use collide_capsule::Capsule;
use collide_ray::Ray;
use collide_mesh::{CollisionWorld, TriangleMesh};
use ga3::Vector;

let mesh = TriangleMesh::from_vertices(&positions, &indices);
let world = CollisionWorld::new(vec![mesh]);

let result = world.collide_capsule(&capsule, velocity_y);
if result.grounded {
    body_y = result.ground_y;
}

let hit = world.raycast(&Ray::new(origin, direction), 100.0);
```

The capsule is assumed to be vertical (a character controller). `velocity_y` distinguishes landing on ground from passing it while moving upward.

## Future work

- Implementing `collide::Collider<Capsule>` for plain penetration info (the rich ground classification does not map onto `CollisionInfo`'s contact-point semantics, so the dedicated API stays primary).
- Moving platforms and per-triangle surface attributes.