Cache collision data when calculating visibility.
This commit is contained in:
parent
92b0a92a70
commit
0751cf344d
|
@ -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<D>,
|
||||
visible_query: &Query<&Visible>,
|
||||
events: &mut EventWriter<VisibilityChanged>,
|
||||
cache: &mut HashMap<(FloatOrd, FloatOrd), (u8, HashSet<Entity>)>,
|
||||
) {
|
||||
let mut context: Context<u8> = 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<D: 'static + Clone + Default + Send + Sync>(
|
|||
}
|
||||
}
|
||||
}
|
||||
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<D: 'static + Clone + Default + Send + Sync>(
|
|||
map,
|
||||
&visible,
|
||||
&mut changed,
|
||||
&mut cache,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -327,6 +348,7 @@ fn remove_visible<D: 'static + Clone + Default + Send + Sync>(
|
|||
mut changed: EventWriter<VisibilityChanged>,
|
||||
) {
|
||||
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<D: 'static + Clone + Default + Send + Sync>(
|
|||
map,
|
||||
&visible,
|
||||
&mut changed,
|
||||
&mut cache,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user