From a26ea8bbea402c8148fbfa5a61b1b00673082441 Mon Sep 17 00:00:00 2001 From: Jan Nils Ferner Date: Tue, 21 Feb 2023 00:54:14 +0100 Subject: [PATCH] Optimize navmesh Former-commit-id: 3d509125adc0db892641484d4d14c42a747044df --- src/dev.rs | 4 +-- src/movement/navigation.rs | 58 +++++++++++++------------------------- 2 files changed, 21 insertions(+), 41 deletions(-) diff --git a/src/dev.rs b/src/dev.rs index 83c0d7e1..64c4be26 100644 --- a/src/dev.rs +++ b/src/dev.rs @@ -14,8 +14,8 @@ pub struct DevPlugin; impl Plugin for DevPlugin { fn build(&self, app: &mut App) { { - app.insert_resource(default_editor_controls()) - .add_plugin(EditorPlugin) + app.add_plugin(EditorPlugin) + .insert_resource(default_editor_controls()) .add_plugin(FrameTimeDiagnosticsPlugin::default()) .add_plugin(DebugLinesPlugin::default()) .add_plugin(DevEditorPlugin) diff --git a/src/movement/navigation.rs b/src/movement/navigation.rs index 60bc2e46..5adaaf91 100644 --- a/src/movement/navigation.rs +++ b/src/movement/navigation.rs @@ -1,5 +1,6 @@ #[cfg(feature = "dev")] use crate::dev::dev_editor::DevEditorWindow; +use crate::level_instantiation::spawning::objects::npc; use crate::movement::general_movement::{apply_walking, reset_movement_components, Walking}; use crate::player_control::player_embodiment::Player; use crate::util::log_error::log_errors; @@ -8,7 +9,6 @@ use crate::GameState; use anyhow::{Context, Result}; use bevy::prelude::*; use bevy_prototype_debug_lines::DebugLines; -use bevy_rapier3d::prelude::*; use oxidized_navigation::{ query::{find_path, perform_string_pulling_on_path}, NavMesh, NavMeshGenerationState, NavMeshSettings, OxidizedNavigationPlugin, @@ -19,25 +19,27 @@ use serde::{Deserialize, Serialize}; /// Currently only one navmesh is supported. It is loaded automagically from any entity whose name contains `"[navmesh]"`. pub struct NavigationPlugin; +const CELL_WIDTH: f32 = 0.5 * npc::RADIUS * 2.; + impl Plugin for NavigationPlugin { fn build(&self, app: &mut App) { app.add_plugin(OxidizedNavigationPlugin { starting_state: NavMeshGenerationState::Running, // Generate tile updates. }) .insert_resource(NavMeshSettings { - cell_width: 0.25, - cell_height: 0.1, - tile_width: 100, + cell_width: CELL_WIDTH, + cell_height: 0.5 * CELL_WIDTH, + tile_width: 150, world_half_extents: 250.0, world_bottom_bound: -100.0, max_traversable_slope_radians: (40.0_f32 - 0.1).to_radians(), - walkable_height: 20, - walkable_radius: 1, + walkable_height: 25, + walkable_radius: 2, step_height: 3, - min_region_area: 100, + min_region_area: 50, merge_region_area: 500, max_contour_simplification_error: 1.1, - max_edge_length: 80, + max_edge_length: 70, }) .add_system_set( SystemSet::on_update(GameState::Playing).with_system( @@ -56,48 +58,25 @@ pub struct Follower; #[allow(clippy::type_complexity)] fn query_mesh( - mut with_follower: Query<(Entity, &Transform, &mut Walking), (With, Without)>, - with_player: Query<(Entity, &Transform), (With, Without)>, + mut with_follower: Query<(&Transform, &mut Walking), (With, Without)>, + with_player: Query<&Transform, (With, Without)>, nav_mesh_settings: Res, nav_mesh: Res, mut lines: ResMut, - rapier_context: Res, #[cfg(feature = "dev")] editor_state: Res, ) -> Result<()> { if let Ok(nav_mesh) = nav_mesh.get().read() { - for (follower_entity, follower_transform, mut walking) in &mut with_follower { - for (player_entity, player_transform) in &with_player { + for (follower_transform, mut walking) in &mut with_follower { + for player_transform in &with_player { let from = follower_transform.translation; let to = player_transform.translation; if (to - from).length_squared() < 3.0f32.squared() { continue; } - let max_toi = 50.; - let solid = false; - let filter = QueryFilter::new() - .exclude_sensors() - .exclude_collider(follower_entity); - let path = if let Some((entity, _toi)) = - rapier_context.cast_ray(from, to - from, max_toi, solid, filter) - && entity == player_entity - { - Some(vec![from, to]) - } else if let Ok(path) = find_path( - &nav_mesh, - &nav_mesh_settings, - from, - to, - None, - None, - ) { - let string_path = perform_string_pulling_on_path(&nav_mesh, from, to, &path) + if let Ok(path) = find_path(&nav_mesh, &nav_mesh_settings, from, to, None, None) { + let path = perform_string_pulling_on_path(&nav_mesh, from, to, &path) .map_err(|e| anyhow::Error::msg(format!("{e:?}")))?; - Some(string_path) - } else { - None - }; - if let Some(path) = path { #[cfg(feature = "dev")] if editor_state .window_state::() @@ -108,12 +87,13 @@ fn query_mesh( } let dir = path .into_iter() - .filter_map(|next_point| { + .map(|next_point| { (next_point - from) .split(follower_transform.up()) .horizontal - .try_normalize() }) + .filter(|dir| dir.length_squared() > 1e-3f32.squared()) + .filter_map(|dir| dir.try_normalize()) .next(); walking.direction = dir; }