recast-rs

Rust bindings for Recast from recastnavigation.

Getting started

Recast is essentially a toolbox for generating navigation meshes from geometry. A good starting point for generating navigation meshes is:

  1. Create a Heightfield.
  2. Rasterize triangles into the Heightfield. Consider marking triangles as walkable.
  3. Create a CompactHeightfield from the Heightfield.
  4. (Optional) Erode the walkable area.
  5. (Optional) Mark areas using boxes, cylinders, or convex polygons.
  6. Build regions for the CompactHeightfield.
  7. Create a ContourSet from the CompactHeightfield (with regions).
  8. Create a PolyMesh from the ContourSet.
  9. Use the PolyMesh data as a navigation mesh.

As a simple example of this process:

```Rust use recast_rs::*;

fn generatenavmesh( vertices: &[Vec3], triangles: &[Vec3], ) -> Result>>, ()> { let mut context = Context::new();

let (minbounds, maxbounds) = util::calculate_bounds(vertices);

let mut heightfield = Heightfield::new( &mut context, minbounds, maxbounds, /* cellhorizontalsize / 1.0, / cell_height= */ 1.0, )?;

let mut areaids = vec![0; triangles.len()]; util::markwalkabletriangles( &mut context, /* walkableslopeangle= */ 45.0, vertices, triangles, &mut areaids, );

heightfield.rasterizeindexedtrianglesi32( &mut context, vertices, triangles, &areaids, /* flagmergethreshold= */ 1, )?;

let mut compactheightfield = CompactHeightfield::::new( &heightfield, &mut context, /* walkableheight= / 3, / walkable_climb= */ 1, )?;

compactheightfield .erodewalkable_area(&mut context, /* radius= */ 1)?;

let compactheightfield = compactheightfield.buildregions( &mut context, /* bordersize= / 0, / minregionarea= / 0, / mergeregionarea= */ 0, )?;

let contourset = ContourSet::new( &compactheightfield, &mut context, /* maxerror= */ 1.0, /* maxedgelen= */ 10, ContourBuildFlags { tessellatewalledges: true, tessellatearea_edges: false, }, )?;

let polymesh = PolyMesh::new( &contourset, &mut context, /* maxverticesper_polygon= */ 8, )?;

Ok( polymesh .polygonsiter() .map(|polygon| { polygon .validvertices() .iter() .map(|&vertexindex| polymesh.vertex(vertexindex as usize).as_f32()) .collect() }) .collect(), ) } ```

Note in this example we just create a Vec for each polygon filled with the vertices that make up that polygon. In practice, you likely want to extract the neighbour information for each polygon to use this as a navigation mesh.

License

Licensed under the MIT license.