From 615af720cbd90747144de2b3e250c66737db6e2a Mon Sep 17 00:00:00 2001 From: Nolan Darilek Date: Tue, 17 May 2022 10:37:46 -0500 Subject: [PATCH] Major visibility system updates. --- src/visibility.rs | 80 ++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/src/visibility.rs b/src/visibility.rs index d3eef4b..8fa7d1f 100644 --- a/src/visibility.rs +++ b/src/visibility.rs @@ -73,12 +73,19 @@ impl Viewshed { map, RefCell::new(Box::new(|coord: Coord| { let dest = Point2::new(coord.x as f32 + 0.5, coord.y as f32 + 0.5); + if na::distance(&origin, &dest) > self.range as f32 { + return u8::MAX; + } if let Some((opacity, entities)) = cache.get(&(FloatOrd(dest.x), FloatOrd(dest.y))) { for e in entities { new_visible_entities.insert(*e); } - return *opacity; + if entities.contains(&viewer_entity) { + return 0; + } else { + return *opacity; + } } let tile = map.at(coord.x as usize, coord.y as usize); if tile.blocks_visibility() { @@ -88,34 +95,32 @@ impl Viewshed { ); return u8::MAX; } - if na::distance(&origin, &dest) > self.range as f32 { - return u8::MAX; - } let mut opacity = 0; let mut entities = HashSet::new(); - let shape_pos = Vec2::new(coord.x as f32 + 0.5, coord.y as f32 + 0.5); + let shape_pos = Vec2::new(dest.x, dest.y); rapier_context.intersections_with_shape( shape_pos, 0., &shape, InteractionGroups::all(), - Some(&|v| v != *viewer_entity && visible_query.get(v).is_ok()), + Some(&|v| visible_query.get(v).is_ok()), |entity| { entities.insert(entity); if let Ok(visible) = visible_query.get(entity) { - opacity = **visible; + opacity = opacity.max(**visible); } - cache.insert( - (FloatOrd(dest.x), FloatOrd(dest.y)), - (opacity, entities.clone()), - ); true }, ); for e in &entities { new_visible_entities.insert(*e); } - opacity + if entities.contains(&viewer_entity) { + 0 + } else { + cache.insert((FloatOrd(dest.x), FloatOrd(dest.y)), (opacity, entities)); + opacity + } })), ); let mut new_visible = HashSet::new(); @@ -259,15 +264,12 @@ where fn update_viewshed( mut commands: Commands, config: Res, - positions: Query<(Entity, &Transform, Option<&LastCoordinates>), Changed>, + positions: Query< + (Entity, &Transform, &Collider, Option<&LastCoordinates>), + Or<(Changed, Changed)>, + >, visible: Query<&Visible>, - mut viewers: Query<( - Entity, - &mut Viewshed, - &mut VisibleEntities, - &Transform, - Option<&LastCoordinates>, - )>, + mut viewers: Query<(Entity, &mut Viewshed, &mut VisibleEntities, &Transform)>, map: Query<&Map>, rapier_context: Res, mut changed: EventWriter, @@ -276,7 +278,7 @@ fn update_viewshed( return; } let mut to_update = HashSet::new(); - for (entity, transform, last_coordinates) in positions.iter() { + for (entity, transform, collider, last_coordinates) in positions.iter() { if to_update.contains(&entity) { continue; } @@ -297,34 +299,26 @@ fn update_viewshed( if visible.get(entity).is_err() { continue; } - for ( - viewer_entity, - viewshed, - visible_entities, - viewer_coordinates, - viewer_last_coordinates, - ) in viewers.iter_mut() - { - if let (Some(last_coordinates), Some(viewer_last_coordinates)) = - (last_coordinates, viewer_last_coordinates) - { - if viewer_coordinates.i32() == **viewer_last_coordinates - && coordinates.i32() == **last_coordinates - { - continue; + for (viewer_entity, viewshed, visible_entities, viewer_coordinates) in viewers.iter_mut() { + if viewer_entity != entity { + let forward = transform.local_x(); + let rotation = forward.y.atan2(forward.x); + let distance = collider.distance_to_point( + transform.translation.truncate(), + rotation, + viewer_coordinates.translation.truncate(), + true, + ); + if distance <= viewshed.range as f32 || visible_entities.contains(&entity) { + to_update.insert(viewer_entity); + to_update.insert(entity); } } - if viewer_entity != entity - && (viewer_coordinates.distance(&coordinates) <= viewshed.range as f32 - || visible_entities.contains(&entity)) - { - to_update.insert(viewer_entity); - } } } let mut cache = HashMap::new(); for entity in to_update.iter() { - if let Ok((viewer_entity, mut viewshed, mut visible_entities, viewer_coordinates, _)) = + if let Ok((viewer_entity, mut viewshed, mut visible_entities, viewer_coordinates)) = viewers.get_mut(*entity) { if let Ok(map) = map.get_single() {