Skip to content

Commit 07b8825

Browse files
authored
Improve picking in 2D views (#8404)
### Related * Closes #6761 ### What When clicking on a geometric primitive (e.g. a point or a box) you will now only select that primitive, and no images below it. Hovering acts the same as before.
1 parent 704438f commit 07b8825

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

crates/viewer/re_view_spatial/src/picking_ui.rs

+29-6
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,13 @@ pub fn picking(
7777
);
7878
state.previous_picking_result = Some(picking_result.clone());
7979

80-
let mut hovered_items = Vec::new();
80+
let mut hovered_image_items = Vec::new();
81+
let mut hovered_non_image_items = Vec::new();
8182

8283
// Depth at pointer used for projecting rays from a hovered 2D view to corresponding 3D view(s).
8384
// TODO(#1818): Depth at pointer only works for depth images so far.
8485
let mut depth_at_pointer = None;
86+
8587
for (hit_idx, hit) in picking_result.hits.iter().enumerate() {
8688
let Some(mut instance_path) = hit.instance_path_hash.resolve(ctx.recording()) else {
8789
// Entity no longer exists in db.
@@ -161,14 +163,35 @@ pub fn picking(
161163
})
162164
};
163165

164-
hovered_items.push(Item::DataResult(query.view_id, instance_path.clone()));
165-
}
166+
let item = Item::DataResult(query.view_id, instance_path.clone());
166167

167-
if hovered_items.is_empty() {
168-
// If we hover nothing, we are hovering the view itself.
169-
hovered_items.push(Item::View(query.view_id));
168+
if hit.hit_type == PickingHitType::TexturedRect {
169+
hovered_image_items.push(item);
170+
} else {
171+
hovered_non_image_items.push(item);
172+
}
170173
}
171174

175+
let hovered_items: Vec<Item> = {
176+
// Due to how our picking works, if we are hovering a point on top of an RGB and segmentation image,
177+
// we are actually hovering all three things (RGB, segmentation, point).
178+
// For the hovering preview (handled above) this is desierable: we want to zoom in on the
179+
// underlying image(s), even if the mouse slips over a point or some other geometric primitive.
180+
// However, when clicking we assume the users wants to only select the top-most thing.
181+
//
182+
// So we apply the following logic: if the hovered items are a mix of images and non-images,
183+
// then we only select the non-images on click.
184+
185+
if !hovered_non_image_items.is_empty() {
186+
hovered_non_image_items
187+
} else if !hovered_image_items.is_empty() {
188+
hovered_image_items
189+
} else {
190+
// If we aren't hovering anything, we are hovering the view itself.
191+
vec![Item::View(query.view_id)]
192+
}
193+
};
194+
172195
// Associate the hovered space with the first item in the hovered item list.
173196
// If we were to add several, views might render unnecessary additional hints.
174197
// TODO(andreas): Should there be context if no item is hovered at all? There's no usecase for that today it seems.

0 commit comments

Comments
 (0)