# collide-mesh
[](https://crates.io/crates/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 ground semantics (walkable slopes, ground height) are inherently 3D gameplay concepts. The dimension-generic core traits of `collide` remain untouched by this exception.
The up direction is a caller-supplied unit vector, not fixed to an axis: a world that isn't Y-up needs no conversion at this boundary.
## 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 capsule aligned with `up` against all meshes and returns an `Option<Ground>` (walkable if the face normal's alignment with `up` exceeds 0.5) carrying the signed distance from the capsule's feet to the supporting ground and its normal, plus 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 up = Vector::new(0.0, 0.0, 1.0);
let result = world.collide_capsule(&capsule, up, velocity);
if let Some(ground) = result.ground
&& ground.distance >= 0.0
{
body_position += up * ground.distance;
}
body_position += result.push;
let hit = world.raycast(&Ray::new(origin, direction), 100.0);
```
The capsule is assumed to be aligned with `up` (a character controller). `velocity` distinguishes landing on ground from passing it while moving up (its component along `up`).
Ground and push are independent: a capsule can be pushed out of a wall while airborne, so `push` sits outside the `Option`. `Ground::distance` is signed — positive means the feet are below the ground and the capsule must move along `up` to rest on it, negative means it hovers within the snap tolerance.
## 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.