diff --git a/voxygen/src/session/interactable.rs b/voxygen/src/session/interactable.rs index 840a8b0d50..787f5d20ce 100644 --- a/voxygen/src/session/interactable.rs +++ b/voxygen/src/session/interactable.rs @@ -16,7 +16,7 @@ use common::{ terrain::{Block, TerrainGrid, UnlockKind}, uid::{Uid, UidAllocator}, util::find_dist::{Cube, Cylinder, FindDist}, - vol::ReadVol, + vol::ReadVol, CachedSpatialGrid, }; use common_base::span; @@ -197,8 +197,12 @@ pub(super) fn select_interactable( player_char_state, ); - let closest_interactable_entity = ( - &ecs.entities(), + + let spacial_grid = ecs.read_resource::(); + + let entities = ecs.entities(); + let mut entity_data = ( + &entities, &positions, &bodies, scales.maybe(), @@ -207,8 +211,11 @@ pub(super) fn select_interactable( !&is_mount, (stats.mask() | items.mask()).maybe(), ) - .join() - .filter(|&(e, _, _, _, _, _, _, _)| e != player_entity) // skip the player's entity + .join(); + + let closest_interactable_entity = spacial_grid.0.in_circle_aabr(player_pos.xy(), MAX_PICKUP_RANGE) + .filter(|&e| e != player_entity) // skip the player's entity + .filter_map(|e| entity_data.get(e, &entities)) .filter_map(|(e, p, b, s, c, cs, _, has_stats_or_item)| { // Note, if this becomes expensive to compute do it after the distance check! // @@ -245,15 +252,18 @@ pub(super) fn select_interactable( let voxel_colliders_manifest = VOXEL_COLLIDER_MANIFEST.read(); let volumes_data = ( - &ecs.entities(), + &entities, &ecs.read_storage::(), &ecs.read_storage::(), &ecs.read_storage::(), &ecs.read_storage::(), ); - let volumes = volumes_data - .join() + let mut volumes_data = volumes_data.join(); + + let volumes = spacial_grid.0.in_circle_aabr(player_pos.xy(), search_dist) + .filter(|&e| e != player_entity) // skip the player's entity + .filter_map(|e| volumes_data.get(e, &entities)) .filter_map(|(entity, uid, body, interpolated, collider)| { let vol = collider.get_vol(&voxel_colliders_manifest)?; let (blocks_of_interest, offset) =