From e8caa58b08819b668d865f0386feb881174434af Mon Sep 17 00:00:00 2001 From: Nolan Darilek Date: Tue, 28 Sep 2021 14:36:21 -0500 Subject: [PATCH] Optimize visibility. --- src/visibility.rs | 63 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/src/visibility.rs b/src/visibility.rs index 305277b..440e820 100644 --- a/src/visibility.rs +++ b/src/visibility.rs @@ -3,7 +3,7 @@ use std::{ collections::{HashMap, HashSet}, }; -use bevy::prelude::*; +use bevy::{core::FixedTimestep, prelude::*}; use bevy_rapier2d::{na, na::UnitComplex}; use coord_2d::{Coord, Size}; use derive_more::{Deref, DerefMut}; @@ -241,10 +241,10 @@ fn update_viewshed_for_coordinates( if !config.query_pipeline_active { return; } - for (visible_entity, coordinates) in visible.iter() { + for (visible_entity, visible_coordinates) in visible.iter() { for (viewer_entity, mut viewshed, mut visible_entities, start) in viewers.iter_mut() { if viewer_entity == visible_entity - || coordinates.distance(start) > viewshed.range as f32 + || start.distance(&visible_coordinates) > viewshed.range as f32 { continue; } @@ -265,10 +265,20 @@ fn update_viewshed_for_coordinates( } } +#[derive(Clone, Debug, Deref, DerefMut)] +struct LastStart((i32, i32)); + fn update_viewshed_for_start( + mut commands: Commands, config: Res, mut viewers: Query< - (Entity, &mut Viewshed, &mut VisibleEntities, &Coordinates), + ( + Entity, + &mut Viewshed, + &mut VisibleEntities, + &Coordinates, + Option<&LastStart>, + ), Changed, >, map: Query<&Map>, @@ -280,19 +290,30 @@ fn update_viewshed_for_start( if !config.query_pipeline_active { return; } - for (viewer_entity, mut viewshed, mut visible_entities, start) in viewers.iter_mut() { - if let Ok(map) = map.single() { - update_viewshed( - &viewer_entity, - &mut viewshed, - &mut visible_entities, - start, - &*query_pipeline, - &collider_query, - map, - &visible, - &mut changed, - ); + for (viewer_entity, mut viewshed, mut visible_entities, start, last_start) in viewers.iter_mut() + { + let should_update = if let Some(last) = last_start { + start.i32() != **last + } else { + true + }; + commands + .entity(viewer_entity) + .insert(LastStart(start.i32())); + if should_update { + if let Ok(map) = map.single() { + update_viewshed( + &viewer_entity, + &mut viewshed, + &mut visible_entities, + start, + &*query_pipeline, + &collider_query, + map, + &visible, + &mut changed, + ); + } } } } @@ -403,8 +424,12 @@ impl Plugin for VisibilityPlugin { app.add_event::() .add_system(add_visibility_indices.system()) .add_system_to_stage(CoreStage::PostUpdate, viewshed_removed.system()) - .add_system(update_viewshed_for_coordinates.system()) - .add_system(update_viewshed_for_start.system()) + .add_system_set( + SystemSet::new() + .with_run_criteria(FixedTimestep::step(0.25)) + .with_system(update_viewshed_for_coordinates.system()) + .with_system(update_viewshed_for_start.system()), + ) .add_system_to_stage(CoreStage::PostUpdate, remove_visible.system()) .add_system_to_stage(CoreStage::PostUpdate, update_revealed_tiles.system()) .add_system_to_stage(CoreStage::PostUpdate, log_visible.system());