Use AABB intersection rather than point containment.

This commit is contained in:
Nolan Darilek 2022-07-20 10:12:14 -05:00
parent a0ca6a9f55
commit d19048c4a8

View File

@ -6,7 +6,10 @@ use std::{
use bevy::prelude::*; use bevy::prelude::*;
use bevy_rapier2d::na::{Isometry2, Point2, Vector2}; use bevy_rapier2d::{
na::{Isometry2, Vector2},
parry::bounding_volume::BoundingVolume,
};
use coord_2d::{Coord, Size}; use coord_2d::{Coord, Size};
use shadowcast::{vision_distance, Context, InputGrid}; use shadowcast::{vision_distance, Context, InputGrid};
@ -21,10 +24,6 @@ use crate::{
#[reflect(Component)] #[reflect(Component)]
pub struct DontLogWhenVisible; pub struct DontLogWhenVisible;
#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect)]
#[reflect(Component)]
struct LastCoordinates((i32, i32));
#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect)] #[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect)]
#[reflect(Component)] #[reflect(Component)]
pub struct RevealedTiles(pub Vec<bool>); pub struct RevealedTiles(pub Vec<bool>);
@ -75,7 +74,11 @@ impl Viewshed {
Vector2::new(transform.translation.x, transform.translation.y), Vector2::new(transform.translation.x, transform.translation.y),
0., 0.,
); );
// println!("Pushing {:?}", collider.raw.compute_aabb(&position)); // println!(
// "Hit {:?}, pushing {:?}",
// entity,
// collider.raw.compute_aabb(&position)
// );
boxes.push(collider.raw.compute_aabb(&position)); boxes.push(collider.raw.compute_aabb(&position));
} }
true true
@ -95,38 +98,53 @@ impl Viewshed {
// println!("Out of range"); // println!("Out of range");
return u8::MAX; return u8::MAX;
} }
let point = Point2::new(shape_pos.x, shape_pos.y); let result = if let Some((opacity, coord_entities)) = cache.get(&(coord.x, coord.y))
let mut hit = false; {
for b in &boxes { Some((*opacity, coord_entities.clone()))
if b.contains_local_point(&point) { } else {
// println!("Hit at {:?}", b); let position = Isometry2::new(Vector2::new(shape_pos.x, shape_pos.y), 0.);
hit = true; let aabb = shape.raw.compute_aabb(&position);
break; let mut hit = false;
for b in &boxes {
if b.intersects(&aabb) {
// println!("Hit at {:?}", b);
hit = true;
break;
}
} }
} if hit {
if hit { // println!("Hit test");
// println!("Hit test"); let mut opacity = 0;
let mut opacity = 0; let mut coord_entities = HashSet::new();
let mut coord_entities = HashSet::new(); rapier_context.intersections_with_shape(
rapier_context.intersections_with_shape( shape_pos,
shape_pos, 0.,
0., &shape,
&shape, QueryFilter::new().predicate(&|v| visible_query.get(v).is_ok()),
QueryFilter::new().predicate(&|v| visible_query.get(v).is_ok()), |entity| {
|entity| { // println!("{:?}", entity);
// println!("{:?}", entity); let obstruction = obstructions_query.get(entity).is_ok();
let obstruction = obstructions_query.get(entity).is_ok(); if obstruction {
if obstruction { // println!("Obstruction");
// println!("Obstruction"); coord_entities.clear();
coord_entities.clear(); }
} coord_entities.insert(entity);
coord_entities.insert(entity); if let Ok((visible, _, _)) = visible_query.get(entity) {
if let Ok((visible, _, _)) = visible_query.get(entity) { opacity = opacity.max(**visible);
opacity = opacity.max(**visible); }
} !obstruction
!obstruction },
}, );
); cache.insert((coord.x, coord.y), (opacity, coord_entities.clone()));
Some((opacity, coord_entities))
} else {
// println!("No hits, 0");
let coord_entities = HashSet::new();
cache.insert((coord.x, coord.y), (0, coord_entities.clone()));
Some((0, coord_entities))
}
};
if let Some((opacity, coord_entities)) = result {
for e in &coord_entities { for e in &coord_entities {
new_visible_entities.insert(*e); new_visible_entities.insert(*e);
} }
@ -138,7 +156,6 @@ impl Viewshed {
opacity opacity
} }
} else { } else {
// println!("No hits, 0");
0 0
} }
})), })),
@ -159,12 +176,19 @@ impl Viewshed {
} }
if new_visible_entities != **visible_entities { if new_visible_entities != **visible_entities {
for lost in visible_entities.difference(&new_visible_entities) { for lost in visible_entities.difference(&new_visible_entities) {
if let Ok((_, _, transform)) = visible_query.get(*lost) {
// println!(
// "transition: {:?} loses {:?} at {:?}",
// viewer_entity, lost, transform.translation
// );
}
events.send(VisibilityChanged::Lost { events.send(VisibilityChanged::Lost {
viewer: *viewer_entity, viewer: *viewer_entity,
viewed: *lost, viewed: *lost,
}); });
} }
for gained in new_visible_entities.difference(visible_entities) { for gained in new_visible_entities.difference(visible_entities) {
// println!("transition: {:?} gains {:?}", viewer_entity, gained);
events.send(VisibilityChanged::Gained { events.send(VisibilityChanged::Gained {
viewer: *viewer_entity, viewer: *viewer_entity,
viewed: *gained, viewed: *gained,