Refine visibility algorithm.

This commit is contained in:
Nolan Darilek 2021-06-09 17:42:04 -05:00
parent 3994c1c744
commit 24db52abd9

View File

@ -49,6 +49,16 @@ impl Viewshed {
#[reflect(Component)] #[reflect(Component)]
pub struct VisibleTiles(pub Vec<bool>); pub struct VisibleTiles(pub Vec<bool>);
impl PointLike for Coord {
fn x(&self) -> f32 {
self.x as f32
}
fn y(&self) -> f32 {
self.y as f32
}
}
fn add_visibility_indices( fn add_visibility_indices(
mut commands: Commands, mut commands: Commands,
query: Query<(Entity, &Map), (Added<Map>, Without<VisibleTiles>, Without<RevealedTiles>)>, query: Query<(Entity, &Map), (Added<Map>, Without<VisibleTiles>, Without<RevealedTiles>)>,
@ -85,13 +95,13 @@ where
} }
fn update_viewshed<'a>( fn update_viewshed<'a>(
mut viewers: Query<(&mut Viewshed, &Coordinates), Changed<Coordinates>>, mut viewers: Query<(Entity, &mut Viewshed, &Coordinates), Changed<Coordinates>>,
map: Query<&Map>, map: Query<&Map>,
query_pipeline: Res<QueryPipeline>, query_pipeline: Res<QueryPipeline>,
collider_query: QueryPipelineColliderComponentsQuery, collider_query: QueryPipelineColliderComponentsQuery,
blocks_visibility: Query<&BlocksVisibility>, blocks_visibility: Query<&BlocksVisibility>,
) { ) {
for (mut viewshed, start) in viewers.iter_mut() { for (viewer_entity, mut viewshed, start) in viewers.iter_mut() {
for map in map.iter() { for map in map.iter() {
let mut context: Context<u8> = Context::default(); let mut context: Context<u8> = Context::default();
let vision_distance = vision_distance::Circle::new(viewshed.range); let vision_distance = vision_distance::Circle::new(viewshed.range);
@ -99,7 +109,13 @@ fn update_viewshed<'a>(
viewshed.visible.clear(); viewshed.visible.clear();
let collider_set = QueryPipelineColliderComponentsSet(&collider_query); let collider_set = QueryPipelineColliderComponentsSet(&collider_query);
let shape = Cuboid::new(Vec2::new(0.5, 0.5).into()); let shape = Cuboid::new(Vec2::new(0.5, 0.5).into());
let range = viewshed.range as f32;
let visibility_grid = VisibilityGrid(map, |coord: Coord| { let visibility_grid = VisibilityGrid(map, |coord: Coord| {
if start.x_i32() == coord.x && start.y_i32() == coord.y {
return 0;
} else if coord.distance(start) > range {
return 255;
}
let shape_pos = (Vec2::new(coord.x as f32, coord.y as f32), 0.); let shape_pos = (Vec2::new(coord.x as f32, coord.y as f32), 0.);
let mut opacity = 0; let mut opacity = 0;
query_pipeline.intersections_with_shape( query_pipeline.intersections_with_shape(
@ -107,7 +123,9 @@ fn update_viewshed<'a>(
&shape_pos.into(), &shape_pos.into(),
&shape, &shape,
InteractionGroups::all(), InteractionGroups::all(),
Some(&|v| blocks_visibility.get(v.entity()).is_ok()), Some(&|v| {
v.entity() != viewer_entity && blocks_visibility.get(v.entity()).is_ok()
}),
|_| { |_| {
opacity = 255; opacity = 255;
false false