From 0751cf344d239eddb7e26ff4ff2de7e6dd894a56 Mon Sep 17 00:00:00 2001 From: Nolan Darilek Date: Thu, 17 Mar 2022 12:15:30 -0500 Subject: [PATCH] Cache collision data when calculating visibility. --- src/visibility.rs | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/visibility.rs b/src/visibility.rs index de3d3d8..3275229 100644 --- a/src/visibility.rs +++ b/src/visibility.rs @@ -4,7 +4,10 @@ use std::{ marker::PhantomData, }; -use bevy::{core::FixedTimestep, prelude::*}; +use bevy::{ + core::{FixedTimestep, FloatOrd}, + prelude::*, +}; use bevy_rapier2d::{na, na::UnitComplex}; use coord_2d::{Coord, Size}; use derive_more::{Deref, DerefMut}; @@ -59,6 +62,7 @@ impl Viewshed { map: &Map, visible_query: &Query<&Visible>, events: &mut EventWriter, + cache: &mut HashMap<(FloatOrd, FloatOrd), (u8, HashSet)>, ) { let mut context: Context = Context::default(); let vision_distance = vision_distance::Circle::new(self.range); @@ -70,11 +74,22 @@ impl Viewshed { let visibility_grid = VisibilityGrid( map, RefCell::new(Box::new(|coord: Coord| { + let dest = point!(coord.x as f32 + 0.5, coord.y as f32 + 0.5); + if let Some((opacity, entities)) = cache.get(&(FloatOrd(dest.x), FloatOrd(dest.y))) + { + for e in entities { + new_visible_entities.insert(*e); + return *opacity; + } + } let tile = map.at(coord.x as usize, coord.y as usize); if tile.blocks_visibility() { + cache.insert( + (FloatOrd(dest.x), FloatOrd(dest.y)), + (u8::MAX, HashSet::new()), + ); return u8::MAX; } - let dest = point!(coord.x as f32 + 0.5, coord.y as f32 + 0.5); if na::distance(&origin, &dest) > self.range as f32 { return u8::MAX; } @@ -95,6 +110,10 @@ impl Viewshed { if let Ok(visible) = visible_query.get(entity) { opacity = **visible; } + cache.insert( + (FloatOrd(dest.x), FloatOrd(dest.y)), + (opacity, entities.clone()), + ); true }, ); @@ -297,6 +316,7 @@ fn update_viewshed( } } } + let mut cache = HashMap::new(); for entity in to_update.iter() { if let Ok((viewer_entity, mut viewshed, mut visible_entities, viewer_coordinates)) = viewers.get_mut(*entity) @@ -311,6 +331,7 @@ fn update_viewshed( map, &visible, &mut changed, + &mut cache, ); } } @@ -327,6 +348,7 @@ fn remove_visible( mut changed: EventWriter, ) { for removed in removed.iter() { + let mut cache = HashMap::new(); for (viewer_entity, mut viewshed, mut visible_entities, start) in viewers.iter_mut() { if !visible_entities.contains(&removed) { continue; @@ -342,6 +364,7 @@ fn remove_visible( map, &visible, &mut changed, + &mut cache, ); } }