Use AABB intersection rather than point containment.
This commit is contained in:
parent
a0ca6a9f55
commit
d19048c4a8
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user