nightshade_api/
navigation.rs1use nightshade::prelude::nalgebra_glm::Mat4;
6use nightshade::prelude::*;
7
8pub fn bake_navmesh(world: &mut World) {
13 let mut sources: Vec<(Entity, String, Mat4)> = Vec::new();
14 world
15 .core
16 .query()
17 .with(RENDER_MESH | GLOBAL_TRANSFORM)
18 .without(NAVMESH_AGENT | CLOTH)
19 .iter(|entity, table, index| {
20 sources.push((
21 entity,
22 table.render_mesh[index].name.clone(),
23 table.global_transform[index].0,
24 ));
25 });
26
27 let mut vertices: Vec<[f32; 3]> = Vec::new();
28 let mut indices: Vec<[u32; 3]> = Vec::new();
29 for (entity, source_mesh_name, matrix) in sources {
30 if world
31 .core
32 .get_visibility(entity)
33 .is_some_and(|visibility| !visibility.visible)
34 {
35 continue;
36 }
37 if world
38 .core
39 .get_name(entity)
40 .is_some_and(|name| name.0.starts_with(crate::runner::RESERVED_PREFIX))
41 {
42 continue;
43 }
44 #[cfg(feature = "physics")]
45 if world.core.get_rigid_body(entity).is_some_and(|body| {
46 !matches!(
47 body.body_type,
48 nightshade::ecs::physics::types::RigidBodyType::Fixed
49 )
50 }) {
51 continue;
52 }
53 let Some(mesh) = registry_entry_by_name(
54 &world.resources.assets.mesh_cache.registry,
55 &source_mesh_name,
56 ) else {
57 continue;
58 };
59 let base_index = vertices.len() as u32;
60 for vertex in &mesh.vertices {
61 let position = matrix
62 * vec4(
63 vertex.position[0],
64 vertex.position[1],
65 vertex.position[2],
66 1.0,
67 );
68 vertices.push([position.x, position.y, position.z]);
69 }
70 for triangle in mesh.indices.chunks_exact(3) {
71 indices.push([
72 base_index + triangle[0],
73 base_index + triangle[1],
74 base_index + triangle[2],
75 ]);
76 }
77 }
78
79 if let Some(navmesh) =
80 generate_navmesh_recast(&vertices, &indices, &RecastNavMeshConfig::default())
81 {
82 world.resources.navmesh = navmesh;
83 }
84}
85
86pub fn spawn_walker(world: &mut World, position: Vec3) -> Entity {
92 spawn_navmesh_agent(world, position, 3.0)
93}
94
95#[inline]
97pub fn walk_to(world: &mut World, agent: Entity, destination: Vec3) {
98 set_agent_destination(world, agent, destination);
99}
100
101#[inline]
103pub fn set_walk_speed(world: &mut World, agent: Entity, speed: f32) {
104 set_agent_speed(world, agent, speed);
105}
106
107#[inline]
109pub fn stop_walking(world: &mut World, agent: Entity) {
110 stop_agent(world, agent);
111}