diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ad28d3149..30cc28e9cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Entity-entity pushback is no longer applied in forced movement states like rolling and leaping. - Updated audio library (rodio 0.13 -> 0.14). +- Improve entity-terrain physics performance by reducing the number of voxel lookups. ### Removed diff --git a/common/systems/src/phys.rs b/common/systems/src/phys.rs index 613431035c..5852454f5f 100644 --- a/common/systems/src/phys.rs +++ b/common/systems/src/phys.rs @@ -1283,11 +1283,22 @@ fn box_voxel_collision<'a, T: BaseVol + ReadVol>( near_iter.filter_map(move |(i, j, k)| { let block_pos = pos.map(|e| e.floor() as i32) + Vec3::new(i, j, k); + // `near_iter` could be a few blocks too large due to being integer aligned and + // rounding up, so skip points outside of the tighter bounds before looking them + // up in the terrain (which incurs a hashmap cost for volgrids) + let player_aabb = Aabb { + min: pos + Vec3::new(-radius, -radius, z_range.start), + max: pos + Vec3::new(radius, radius, z_range.end), + }; + let block_approx = Aabb { + min: block_pos.as_(), + max: block_pos.as_() + Vec3::new(1.0, 1.0, Block::MAX_HEIGHT), + }; + if !player_aabb.collides_with_aabb(block_approx) { + return None; + } + if let Some(block) = terrain.get(block_pos).ok().copied().filter(hit) { - let player_aabb = Aabb { - min: pos + Vec3::new(-radius, -radius, z_range.start), - max: pos + Vec3::new(radius, radius, z_range.end), - }; let block_aabb = Aabb { min: block_pos.map(|e| e as f32), max: block_pos.map(|e| e as f32) + Vec3::new(1.0, 1.0, height(&block)),