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_capsuleresolves a capsule aligned withupagainst all meshes and returns anOption<Ground>(walkable if the face normal's alignment withupexceeds 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.raycastreturns the closest hit distance.- Robust against degenerate input: zero-area triangles, broken indices and zero-length segments are tolerated.
Usage
use Capsule;
use Ray;
use ;
use Vector;
let mesh = from_vertices;
let world = new;
let up = new;
let result = world.collide_capsule;
if let Some = result.ground
&& ground.distance >= 0.0
body_position += result.push;
let hit = world.raycast;
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 ontoCollisionInfo's contact-point semantics, so the dedicated API stays primary). - Moving platforms and per-triangle surface attributes.