Major visibility system updates.
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
64fd169ba2
commit
615af720cb
|
@ -73,12 +73,19 @@ impl Viewshed {
|
||||||
map,
|
map,
|
||||||
RefCell::new(Box::new(|coord: Coord| {
|
RefCell::new(Box::new(|coord: Coord| {
|
||||||
let dest = Point2::new(coord.x as f32 + 0.5, coord.y as f32 + 0.5);
|
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)))
|
if let Some((opacity, entities)) = cache.get(&(FloatOrd(dest.x), FloatOrd(dest.y)))
|
||||||
{
|
{
|
||||||
for e in entities {
|
for e in entities {
|
||||||
new_visible_entities.insert(*e);
|
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);
|
let tile = map.at(coord.x as usize, coord.y as usize);
|
||||||
if tile.blocks_visibility() {
|
if tile.blocks_visibility() {
|
||||||
|
@ -88,34 +95,32 @@ impl Viewshed {
|
||||||
);
|
);
|
||||||
return u8::MAX;
|
return u8::MAX;
|
||||||
}
|
}
|
||||||
if na::distance(&origin, &dest) > self.range as f32 {
|
|
||||||
return u8::MAX;
|
|
||||||
}
|
|
||||||
let mut opacity = 0;
|
let mut opacity = 0;
|
||||||
let mut entities = HashSet::new();
|
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(
|
rapier_context.intersections_with_shape(
|
||||||
shape_pos,
|
shape_pos,
|
||||||
0.,
|
0.,
|
||||||
&shape,
|
&shape,
|
||||||
InteractionGroups::all(),
|
InteractionGroups::all(),
|
||||||
Some(&|v| v != *viewer_entity && visible_query.get(v).is_ok()),
|
Some(&|v| visible_query.get(v).is_ok()),
|
||||||
|entity| {
|
|entity| {
|
||||||
entities.insert(entity);
|
entities.insert(entity);
|
||||||
if let Ok(visible) = visible_query.get(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
|
true
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
for e in &entities {
|
for e in &entities {
|
||||||
new_visible_entities.insert(*e);
|
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();
|
let mut new_visible = HashSet::new();
|
||||||
|
@ -259,15 +264,12 @@ where
|
||||||
fn update_viewshed<D: 'static + Clone + Default + Send + Sync>(
|
fn update_viewshed<D: 'static + Clone + Default + Send + Sync>(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
config: Res<RapierConfiguration>,
|
config: Res<RapierConfiguration>,
|
||||||
positions: Query<(Entity, &Transform, Option<&LastCoordinates>), Changed<Transform>>,
|
positions: Query<
|
||||||
|
(Entity, &Transform, &Collider, Option<&LastCoordinates>),
|
||||||
|
Or<(Changed<Transform>, Changed<Visible>)>,
|
||||||
|
>,
|
||||||
visible: Query<&Visible>,
|
visible: Query<&Visible>,
|
||||||
mut viewers: Query<(
|
mut viewers: Query<(Entity, &mut Viewshed, &mut VisibleEntities, &Transform)>,
|
||||||
Entity,
|
|
||||||
&mut Viewshed,
|
|
||||||
&mut VisibleEntities,
|
|
||||||
&Transform,
|
|
||||||
Option<&LastCoordinates>,
|
|
||||||
)>,
|
|
||||||
map: Query<&Map<D>>,
|
map: Query<&Map<D>>,
|
||||||
rapier_context: Res<RapierContext>,
|
rapier_context: Res<RapierContext>,
|
||||||
mut changed: EventWriter<VisibilityChanged>,
|
mut changed: EventWriter<VisibilityChanged>,
|
||||||
|
@ -276,7 +278,7 @@ fn update_viewshed<D: 'static + Clone + Default + Send + Sync>(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut to_update = HashSet::new();
|
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) {
|
if to_update.contains(&entity) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -297,34 +299,26 @@ fn update_viewshed<D: 'static + Clone + Default + Send + Sync>(
|
||||||
if visible.get(entity).is_err() {
|
if visible.get(entity).is_err() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (
|
for (viewer_entity, viewshed, visible_entities, viewer_coordinates) in viewers.iter_mut() {
|
||||||
viewer_entity,
|
if viewer_entity != entity {
|
||||||
viewshed,
|
let forward = transform.local_x();
|
||||||
visible_entities,
|
let rotation = forward.y.atan2(forward.x);
|
||||||
viewer_coordinates,
|
let distance = collider.distance_to_point(
|
||||||
viewer_last_coordinates,
|
transform.translation.truncate(),
|
||||||
) in viewers.iter_mut()
|
rotation,
|
||||||
{
|
viewer_coordinates.translation.truncate(),
|
||||||
if let (Some(last_coordinates), Some(viewer_last_coordinates)) =
|
true,
|
||||||
(last_coordinates, viewer_last_coordinates)
|
);
|
||||||
{
|
if distance <= viewshed.range as f32 || visible_entities.contains(&entity) {
|
||||||
if viewer_coordinates.i32() == **viewer_last_coordinates
|
to_update.insert(viewer_entity);
|
||||||
&& coordinates.i32() == **last_coordinates
|
to_update.insert(entity);
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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();
|
let mut cache = HashMap::new();
|
||||||
for entity in to_update.iter() {
|
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)
|
viewers.get_mut(*entity)
|
||||||
{
|
{
|
||||||
if let Ok(map) = map.get_single() {
|
if let Ok(map) = map.get_single() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user