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