Refine visibility algorithm.
This commit is contained in:
parent
3994c1c744
commit
24db52abd9
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user