mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Address MR 2439 review comments.
- Round properly. - Fix calculation of the x coordinate bounds. - Use LineSegment2 in the signature. - Use `in_swept_circle` for voxel colliders too.
This commit is contained in:
parent
7f093c2a5d
commit
0f8493bf60
@ -101,29 +101,33 @@ impl SpatialGrid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get an iterator over the entities in cells that overlap with a circle of
|
/// Get an iterator over the entities in cells that overlap with a circle of
|
||||||
/// the given radius whose center is swept across the line from p0 to p1
|
/// the given radius whose center is swept across the given line segment
|
||||||
/// NOTE: for best optimization of the iterator use `for_each`
|
/// NOTE: for best optimization of the iterator use `for_each`
|
||||||
/// rather than a for loop
|
/// rather than a for loop
|
||||||
pub fn in_swept_circle<'a>(
|
pub fn in_swept_circle<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
p0: Vec2<f32>,
|
line: LineSegment2<f32>,
|
||||||
p1: Vec2<f32>,
|
|
||||||
radius: f32,
|
radius: f32,
|
||||||
) -> impl Iterator<Item = specs::Entity> + 'a {
|
) -> impl Iterator<Item = specs::Entity> + 'a {
|
||||||
let iter = |max_entity_radius, grid: &'a hashbrown::HashMap<_, _>, lg2_cell_size| {
|
let iter = |max_entity_radius: f32, grid: &'a hashbrown::HashMap<_, _>, lg2_cell_size| {
|
||||||
|
let min = line.start.map2(line.end, f32::min);
|
||||||
|
let max = line.start.map2(line.end, f32::max);
|
||||||
// Add buffer for other entity radius
|
// Add buffer for other entity radius
|
||||||
let ylo = (p0.y.min(p1.y) - radius - max_entity_radius) as i32;
|
let ylo = (min.y - radius - max_entity_radius).floor() as i32;
|
||||||
let yhi = (p0.y.max(p1.y) + radius + max_entity_radius) as i32;
|
let yhi = (max.y + radius + max_entity_radius).ceil() as i32;
|
||||||
// Convert to cells
|
// Convert to cells
|
||||||
let ylo = ylo >> lg2_cell_size;
|
let ylo = ylo >> lg2_cell_size;
|
||||||
let yhi = (yhi + (1 << lg2_cell_size) - 1) >> lg2_cell_size;
|
let yhi = (yhi + (1 << lg2_cell_size) - 1) >> lg2_cell_size;
|
||||||
|
|
||||||
(ylo..=yhi)
|
(ylo..=yhi)
|
||||||
.flat_map(move |y| {
|
.flat_map(move |y| {
|
||||||
let mid = LineSegment2 { start: p0, end: p1 }
|
// 1. project points from outside the line onto the line
|
||||||
.projected_point(Vec2::new(p0.x, y as f32));
|
let xlo = line.projected_point(Vec2::new(min.x, y as f32)).x;
|
||||||
let xlo = (mid.x - radius - max_entity_radius) as i32;
|
let xhi = line.projected_point(Vec2::new(max.x, y as f32)).x;
|
||||||
let xhi = (mid.x + radius + max_entity_radius) as i32;
|
// 2. subtract/add the radius to create a gap around the line
|
||||||
|
let xlo = (xlo - radius - max_entity_radius).floor() as i32;
|
||||||
|
let xhi = (xhi + radius + max_entity_radius).ceil() as i32;
|
||||||
|
// 3. convert from voxel coordinates to cell coordinates
|
||||||
let xlo = xlo >> lg2_cell_size;
|
let xlo = xlo >> lg2_cell_size;
|
||||||
let xhi = (xhi + (1 << lg2_cell_size) - 1) >> lg2_cell_size;
|
let xhi = (xhi + (1 << lg2_cell_size) - 1) >> lg2_cell_size;
|
||||||
(xlo..=xhi).map(move |x| Vec2::new(x, y))
|
(xlo..=xhi).map(move |x| Vec2::new(x, y))
|
||||||
|
@ -342,12 +342,14 @@ impl<'a> PhysicsData<'a> {
|
|||||||
|
|
||||||
let mut vel_delta = Vec3::zero();
|
let mut vel_delta = Vec3::zero();
|
||||||
|
|
||||||
let query_p0 = pos.0.xy();
|
let query_line = LineSegment2 {
|
||||||
let query_p1 = (pos.0 + previous_cache.velocity_dt).xy();
|
start: pos.0.xy(),
|
||||||
|
end: (pos.0 + previous_cache.velocity_dt).xy(),
|
||||||
|
};
|
||||||
let query_radius = previous_cache.scaled_radius;
|
let query_radius = previous_cache.scaled_radius;
|
||||||
|
|
||||||
spatial_grid
|
spatial_grid
|
||||||
.in_swept_circle(query_p0, query_p1, query_radius)
|
.in_swept_circle(query_line, query_radius)
|
||||||
.filter_map(|entity| {
|
.filter_map(|entity| {
|
||||||
read.uids
|
read.uids
|
||||||
.get(entity)
|
.get(entity)
|
||||||
@ -920,7 +922,7 @@ impl<'a> PhysicsData<'a> {
|
|||||||
|
|
||||||
// Compute center and radius of tick path bounding sphere for the entity
|
// Compute center and radius of tick path bounding sphere for the entity
|
||||||
// for broad checks of whether it will collide with a voxel collider
|
// for broad checks of whether it will collide with a voxel collider
|
||||||
let path_sphere = {
|
let (path_sphere, query_line, query_radius) = {
|
||||||
// TODO: duplicated with maintain_pushback_cache, make a common function
|
// TODO: duplicated with maintain_pushback_cache, make a common function
|
||||||
// to call to compute all this info?
|
// to call to compute all this info?
|
||||||
let z_limits = calc_z_limit(character_state, Some(collider));
|
let z_limits = calc_z_limit(character_state, Some(collider));
|
||||||
@ -934,16 +936,20 @@ impl<'a> PhysicsData<'a> {
|
|||||||
let radius = (flat_radius.powi(2) + half_height.powi(2)).sqrt();
|
let radius = (flat_radius.powi(2) + half_height.powi(2)).sqrt();
|
||||||
let path_bounding_radius = radius + (pos_delta / 2.0).magnitude();
|
let path_bounding_radius = radius + (pos_delta / 2.0).magnitude();
|
||||||
|
|
||||||
Sphere {
|
let path_sphere = Sphere {
|
||||||
center: path_center,
|
center: path_center,
|
||||||
radius: path_bounding_radius,
|
radius: path_bounding_radius,
|
||||||
}
|
};
|
||||||
|
let query_line = LineSegment2 {
|
||||||
|
start: pos.0.xy(),
|
||||||
|
end: (pos.0 + pos_delta).xy(),
|
||||||
|
};
|
||||||
|
let query_radius = flat_radius;
|
||||||
|
(path_sphere, query_line, query_radius)
|
||||||
};
|
};
|
||||||
// Collide with terrain-like entities
|
// Collide with terrain-like entities
|
||||||
let query_center = path_sphere.center.xy();
|
|
||||||
let query_radius = path_sphere.radius;
|
|
||||||
voxel_collider_spatial_grid
|
voxel_collider_spatial_grid
|
||||||
.in_circle_aabr(query_center, query_radius)
|
.in_swept_circle(query_line, query_radius)
|
||||||
.filter_map(|entity| {
|
.filter_map(|entity| {
|
||||||
positions
|
positions
|
||||||
.get(entity)
|
.get(entity)
|
||||||
|
Loading…
Reference in New Issue
Block a user