Separate viewshed updates based on coordinate and visibility_blocked.
This commit is contained in:
parent
3050235926
commit
3084d02f66
|
@ -23,7 +23,7 @@ pub struct DontLogWhenVisible;
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub struct RevealedTiles(pub Vec<bool>);
|
pub struct RevealedTiles(pub Vec<bool>);
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct Viewshed {
|
pub struct Viewshed {
|
||||||
pub visible: HashSet<(i32, i32)>,
|
pub visible: HashSet<(i32, i32)>,
|
||||||
pub range: u32,
|
pub range: u32,
|
||||||
|
@ -100,11 +100,11 @@ pub(crate) fn set_visibility_blocked(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Deref, DerefMut)]
|
#[derive(Default, Deref, DerefMut)]
|
||||||
struct PreviousIndex(HashMap<Entity, usize>);
|
struct PrevIndex(HashMap<Entity, usize>);
|
||||||
|
|
||||||
fn map_visibility_indexing(
|
fn map_visibility_indexing(
|
||||||
mut map: Query<(&Map, &mut VisibilityBlocked)>,
|
mut map: Query<(&Map, &mut VisibilityBlocked)>,
|
||||||
mut prev_index: ResMut<PreviousIndex>,
|
mut prev_index: ResMut<PrevIndex>,
|
||||||
query: Query<
|
query: Query<
|
||||||
(Entity, &Coordinates),
|
(Entity, &Coordinates),
|
||||||
(
|
(
|
||||||
|
@ -135,7 +135,7 @@ fn map_visibility_indexing(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_blocks_visibility(
|
fn remove_blocks_visibility(
|
||||||
mut prev_index: ResMut<PreviousIndex>,
|
mut prev_index: ResMut<PrevIndex>,
|
||||||
mut map: Query<(&Map, &mut VisibilityBlocked)>,
|
mut map: Query<(&Map, &mut VisibilityBlocked)>,
|
||||||
removed: RemovedComponents<BlocksVisibility>,
|
removed: RemovedComponents<BlocksVisibility>,
|
||||||
coordinates: Query<&Coordinates>,
|
coordinates: Query<&Coordinates>,
|
||||||
|
@ -184,33 +184,89 @@ impl InputGrid for VisibilityGrid {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_viewshed(
|
fn update_viewshed(
|
||||||
mut viewers: Query<
|
viewshed: &mut Viewshed,
|
||||||
(&mut Viewshed, &Coordinates),
|
start: &Coordinates,
|
||||||
Or<(Changed<VisibilityBlocked>, Changed<Coordinates>)>,
|
map: &Map,
|
||||||
>,
|
visibility_blocked: &VisibilityBlocked,
|
||||||
|
) {
|
||||||
|
let mut context: Context<u8> = Context::default();
|
||||||
|
let vision_distance = vision_distance::Circle::new(viewshed.range);
|
||||||
|
let coord = Coord::new(start.x_i32(), start.y_i32());
|
||||||
|
viewshed.visible.clear();
|
||||||
|
let visibility_grid = VisibilityGrid(map.clone(), visibility_blocked.clone());
|
||||||
|
context.for_each_visible(
|
||||||
|
coord,
|
||||||
|
&visibility_grid,
|
||||||
|
&visibility_grid,
|
||||||
|
vision_distance,
|
||||||
|
255,
|
||||||
|
|coord, _directions, _visibility| {
|
||||||
|
viewshed.visible.insert((coord.x, coord.y));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_viewshed_for_coordinates(
|
||||||
|
mut viewers: Query<(&mut Viewshed, &Coordinates), Changed<Coordinates>>,
|
||||||
map: Query<(&Map, &VisibilityBlocked)>,
|
map: Query<(&Map, &VisibilityBlocked)>,
|
||||||
) {
|
) {
|
||||||
for (mut viewshed, start) in viewers.iter_mut() {
|
for (mut viewshed, start) in viewers.iter_mut() {
|
||||||
for (map, visibility_blocked) in map.iter() {
|
for (map, visibility_blocked) in map.iter() {
|
||||||
let mut context: Context<u8> = Context::default();
|
update_viewshed(&mut viewshed, start, &map, &visibility_blocked);
|
||||||
let vision_distance = vision_distance::Circle::new(viewshed.range);
|
|
||||||
let coord = Coord::new(start.x_i32(), start.y_i32());
|
|
||||||
viewshed.visible.clear();
|
|
||||||
let visibility_grid = VisibilityGrid(map.clone(), visibility_blocked.clone());
|
|
||||||
context.for_each_visible(
|
|
||||||
coord,
|
|
||||||
&visibility_grid,
|
|
||||||
&visibility_grid,
|
|
||||||
vision_distance,
|
|
||||||
255,
|
|
||||||
|coord, _directions, _visibility| {
|
|
||||||
viewshed.visible.insert((coord.x, coord.y));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, Deref, DerefMut)]
|
||||||
|
struct PrevVisibilityBlocked(Vec<bool>);
|
||||||
|
|
||||||
|
fn visibility_blocked_added(mut prev_visibility_blocked: ResMut<PrevVisibilityBlocked>, added: Query<&VisibilityBlocked, Added<VisibilityBlocked>>) {
|
||||||
|
for visibility_blocked in added.iter() {
|
||||||
|
**prev_visibility_blocked = visibility_blocked.to_vec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visibility_blocked_removed(mut prev_visibility_blocked: ResMut<PrevVisibilityBlocked>, removed: RemovedComponents<VisibilityBlocked>) {
|
||||||
|
for _ in removed.iter() {
|
||||||
|
prev_visibility_blocked.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_viewshed_for_visibility_blocked(
|
||||||
|
mut prev_visibility_blocked: ResMut<PrevVisibilityBlocked>,
|
||||||
|
map: Query<(&Map, &VisibilityBlocked), Changed<VisibilityBlocked>>,
|
||||||
|
mut queryset: QuerySet<(
|
||||||
|
Query<(Entity, &Viewshed)>,
|
||||||
|
Query<(&mut Viewshed, &Coordinates)>,
|
||||||
|
)>,
|
||||||
|
) {
|
||||||
|
for (map, visibility_blocked) in map.iter() {
|
||||||
|
let mut to_check = vec![];
|
||||||
|
for (index, new) in visibility_blocked.iter().enumerate() {
|
||||||
|
let changed = if let Some(prev) = prev_visibility_blocked.get(index) {
|
||||||
|
prev != new
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
};
|
||||||
|
if changed {
|
||||||
|
let coords = (index % map.width(), index / map.width());
|
||||||
|
for (entity, viewshed) in queryset.q0().iter() {
|
||||||
|
if viewshed.is_visible(&coords) {
|
||||||
|
to_check.push(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
to_check.dedup();
|
||||||
|
for entity in to_check {
|
||||||
|
if let Ok((mut viewshed, coordinates)) = queryset.q1_mut().get_mut(entity) {
|
||||||
|
update_viewshed(&mut viewshed, coordinates, &map, &visibility_blocked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
**prev_visibility_blocked = visibility_blocked.to_vec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn update_visible_and_revealed_tiles(
|
fn update_visible_and_revealed_tiles(
|
||||||
mut map: Query<
|
mut map: Query<
|
||||||
(&Map, &mut RevealedTiles, &mut VisibleTiles),
|
(&Map, &mut RevealedTiles, &mut VisibleTiles),
|
||||||
|
@ -301,7 +357,10 @@ impl Plugin for VisibilityPlugin {
|
||||||
const UPDATE_VISIBILITY_INDEX: &str = "UPDATE_VISIBILITY_INDEX";
|
const UPDATE_VISIBILITY_INDEX: &str = "UPDATE_VISIBILITY_INDEX";
|
||||||
const UPDATE_VIEWSHED: &str = "UPDATE_VIEWSHED";
|
const UPDATE_VIEWSHED: &str = "UPDATE_VIEWSHED";
|
||||||
const MAP_VISIBILITY: &str = "MAP_VISIBILITY";
|
const MAP_VISIBILITY: &str = "MAP_VISIBILITY";
|
||||||
app.insert_resource(PreviousIndex::default())
|
app.init_resource::<PrevVisibilityBlocked>()
|
||||||
|
.init_resource::<PrevIndex>()
|
||||||
|
.add_system(visibility_blocked_added.system())
|
||||||
|
.add_system_to_stage(CoreStage::PostUpdate, visibility_blocked_removed.system())
|
||||||
.add_system(add_visibility_indices.system())
|
.add_system(add_visibility_indices.system())
|
||||||
.add_system_to_stage(
|
.add_system_to_stage(
|
||||||
CoreStage::PostUpdate,
|
CoreStage::PostUpdate,
|
||||||
|
@ -324,7 +383,14 @@ impl Plugin for VisibilityPlugin {
|
||||||
)
|
)
|
||||||
.add_system_to_stage(
|
.add_system_to_stage(
|
||||||
CoreStage::PostUpdate,
|
CoreStage::PostUpdate,
|
||||||
update_viewshed
|
update_viewshed_for_coordinates
|
||||||
|
.system()
|
||||||
|
.label(UPDATE_VIEWSHED)
|
||||||
|
.after(UPDATE_VISIBILITY_INDEX),
|
||||||
|
)
|
||||||
|
.add_system_to_stage(
|
||||||
|
CoreStage::PostUpdate,
|
||||||
|
update_viewshed_for_visibility_blocked
|
||||||
.system()
|
.system()
|
||||||
.label(UPDATE_VIEWSHED)
|
.label(UPDATE_VIEWSHED)
|
||||||
.after(UPDATE_VISIBILITY_INDEX),
|
.after(UPDATE_VISIBILITY_INDEX),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user