Skip to content

Commit

Permalink
Replace OverMap's inner BTreeMap with sorted Vec (#291)
Browse files Browse the repository at this point in the history
* replace OverMap's inner BTreeMap with sorted Vec

* Update changelog

---------

Co-authored-by: Aevyrie <[email protected]>
  • Loading branch information
bonsairobo and aevyrie authored Feb 23, 2024
1 parent f8e0484 commit ec249c3
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 12 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# UNRELEASED

- Fixed: entities with identical depth could be dropped due to the use of a BTreeMap to sort
entities by depth. This has been changed to use a sorted Vec, to allow entities with the same
depth to coexist.
- Fixed: Ray construction now respects DPI / window scale
- Added: `RayMap` resource that contains a `Ray` for every (camera, pointer) pair
- Changed: rapier and bevy_mod_raycast backends use the `RayMap` instead of constructing their own
Expand Down
23 changes: 11 additions & 12 deletions crates/bevy_picking_core/src/focus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@ use bevy_ecs::prelude::*;
use bevy_reflect::prelude::*;
use bevy_utils::{FloatOrd, HashMap};

/// A map of entities sorted by depth.
type DepthMap = BTreeMap<FloatOrd, (Entity, HitData)>;
type DepthSortedHits = Vec<(Entity, HitData)>;

/// Events returned from backends can be grouped with an order field. This allows picking to work
/// with multiple layers of rendered output to the same render target.
type PickLayer = FloatOrd;

/// Maps [`PickLayer`]s to the map of entities within that pick layer, sorted by depth.
type LayerMap = BTreeMap<PickLayer, DepthMap>;
type LayerMap = BTreeMap<PickLayer, DepthSortedHits>;

/// Maps Pointers to a [`LayerMap`]. Note this is much more complex than the [`HoverMap`] because
/// this data structure is used to sort entities by layer then depth for every pointer.
Expand Down Expand Up @@ -108,10 +107,14 @@ fn build_over_map(
.or_insert_with(BTreeMap::new);
for (entity, pick_data) in entities_under_pointer.picks.iter() {
let layer = entities_under_pointer.order;
let depth_map = layer_map
.entry(FloatOrd(layer))
.or_insert_with(BTreeMap::new);
depth_map.insert(FloatOrd(pick_data.depth), (*entity, pick_data.clone()));
let hits = layer_map.entry(FloatOrd(layer)).or_insert_with(Vec::new);
hits.push((*entity, pick_data.clone()));
}
}

for layers in pointer_over_map.values_mut() {
for hits in layers.values_mut() {
hits.sort_by_key(|(_, hit)| FloatOrd(hit.depth));
}
}
}
Expand All @@ -130,11 +133,7 @@ fn build_hover_map(
let pointer_entity_set = hover_map.entry(*pointer_id).or_insert_with(HashMap::new);
if let Some(layer_map) = over_map.get(pointer_id) {
// Note we reverse here to start from the highest layer first.
for (entity, pick_data) in layer_map
.values()
.rev()
.flat_map(|depth_map| depth_map.values())
{
for (entity, pick_data) in layer_map.values().rev().flatten() {
if let Ok(pickable) = pickable.get(*entity) {
if pickable.should_emit_events {
pointer_entity_set.insert(*entity, pick_data.clone());
Expand Down

0 comments on commit ec249c3

Please sign in to comment.