use nightshade::prelude::nalgebra_glm::Mat4;
use nightshade::prelude::*;
pub fn bake_navmesh(world: &mut World) {
let mut sources: Vec<(Entity, String, Mat4)> = Vec::new();
world
.core
.query()
.with(RENDER_MESH | GLOBAL_TRANSFORM)
.without(NAVMESH_AGENT | CLOTH)
.iter(|entity, table, index| {
sources.push((
entity,
table.render_mesh[index].name.clone(),
table.global_transform[index].0,
));
});
let mut vertices: Vec<[f32; 3]> = Vec::new();
let mut indices: Vec<[u32; 3]> = Vec::new();
for (entity, source_mesh_name, matrix) in sources {
if world
.core
.get_visibility(entity)
.is_some_and(|visibility| !visibility.visible)
{
continue;
}
if world
.core
.get_name(entity)
.is_some_and(|name| name.0.starts_with(crate::runner::RESERVED_PREFIX))
{
continue;
}
#[cfg(feature = "physics")]
if world.core.get_rigid_body(entity).is_some_and(|body| {
!matches!(
body.body_type,
nightshade::ecs::physics::types::RigidBodyType::Fixed
)
}) {
continue;
}
let Some(mesh) = registry_entry_by_name(
&world.resources.assets.mesh_cache.registry,
&source_mesh_name,
) else {
continue;
};
let base_index = vertices.len() as u32;
for vertex in &mesh.vertices {
let position = matrix
* vec4(
vertex.position[0],
vertex.position[1],
vertex.position[2],
1.0,
);
vertices.push([position.x, position.y, position.z]);
}
for triangle in mesh.indices.chunks_exact(3) {
indices.push([
base_index + triangle[0],
base_index + triangle[1],
base_index + triangle[2],
]);
}
}
if let Some(navmesh) =
generate_navmesh_recast(&vertices, &indices, &RecastNavMeshConfig::default())
{
world.resources.navmesh = navmesh;
}
}
pub fn spawn_walker(world: &mut World, position: Vec3) -> Entity {
spawn_navmesh_agent(world, position, 3.0)
}
#[inline]
pub fn walk_to(world: &mut World, agent: Entity, destination: Vec3) {
set_agent_destination(world, agent, destination);
}
#[inline]
pub fn set_walk_speed(world: &mut World, agent: Entity, speed: f32) {
set_agent_speed(world, agent, speed);
}
#[inline]
pub fn stop_walking(world: &mut World, agent: Entity) {
stop_agent(world, agent);
}