Skip to main content

navmesh3d/
navmesh3d.rs

1//! Headless navigation: compile with `--no-default-features --features navmesh`.
2use ponko::*;
3
4// ANCHOR: bake
5fn navigation() -> NavMesh3D {
6    let floor = NavSource::from_mesh(&MeshData::plane(30.0), Transform3D::default());
7    let wall = NavSource::from_mesh(&MeshData::cube(4.0), Transform3D::at(vec3(0.0, 2.0, 0.0)));
8    NavMesh3D::bake(&[floor, wall], NavBakeSettings::default()).unwrap()
9}
10// ANCHOR_END: bake
11
12fn main() {
13    // ANCHOR: query
14    let nav = navigation();
15    let start = nav.sample_position(vec3(-8.0, 1.0, 0.0), 2.0).unwrap();
16    let destination = vec3(8.0, 0.0, 0.0);
17    let corners = nav.find_path(start, destination).unwrap();
18    assert!(corners.len() >= 3);
19    // ANCHOR_END: query
20
21    // ANCHOR: agents
22    let mut world = Game::new("Navigation server", 1, 1)
23        .fixed_hz(60)
24        .sim_system(step_navmesh3d)
25        .run_headless(600, |ctx| {
26            ctx.world.insert_resource(nav);
27            let mut agent = NavAgent3D::default();
28            agent.destination = Some(destination);
29            ctx.world.spawn((Transform3D::at(start), agent));
30            // World-space AABB; move its center or despawn it to reopen polygons.
31            ctx.world
32                .spawn((NavObstacle3D::new(vec3(0.0, 1.0, 8.0), vec3(1.0, 1.0, 1.0)),));
33        });
34    let position = world.query::<&Transform3D>().iter().next().unwrap().position;
35    assert!(position.distance(destination) < 0.3);
36    // ANCHOR_END: agents
37}