Skip to content

Commit

Permalink
Improve picking in 2D views (#8404)
Browse files Browse the repository at this point in the history
### 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.
  • Loading branch information
emilk authored Dec 11, 2024
1 parent 704438f commit 07b8825
Showing 1 changed file with 29 additions and 6 deletions.
35 changes: 29 additions & 6 deletions crates/viewer/re_view_spatial/src/picking_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,13 @@ pub fn picking(
);
state.previous_picking_result = Some(picking_result.clone());

let mut hovered_items = Vec::new();
let mut hovered_image_items = Vec::new();
let mut hovered_non_image_items = Vec::new();

// Depth at pointer used for projecting rays from a hovered 2D view to corresponding 3D view(s).
// TODO(#1818): Depth at pointer only works for depth images so far.
let mut depth_at_pointer = None;

for (hit_idx, hit) in picking_result.hits.iter().enumerate() {
let Some(mut instance_path) = hit.instance_path_hash.resolve(ctx.recording()) else {
// Entity no longer exists in db.
Expand Down Expand Up @@ -161,14 +163,35 @@ pub fn picking(
})
};

hovered_items.push(Item::DataResult(query.view_id, instance_path.clone()));
}
let item = Item::DataResult(query.view_id, instance_path.clone());

if hovered_items.is_empty() {
// If we hover nothing, we are hovering the view itself.
hovered_items.push(Item::View(query.view_id));
if hit.hit_type == PickingHitType::TexturedRect {
hovered_image_items.push(item);
} else {
hovered_non_image_items.push(item);
}
}

let hovered_items: Vec<Item> = {
// Due to how our picking works, if we are hovering a point on top of an RGB and segmentation image,
// we are actually hovering all three things (RGB, segmentation, point).
// For the hovering preview (handled above) this is desierable: we want to zoom in on the
// underlying image(s), even if the mouse slips over a point or some other geometric primitive.
// However, when clicking we assume the users wants to only select the top-most thing.
//
// So we apply the following logic: if the hovered items are a mix of images and non-images,
// then we only select the non-images on click.

if !hovered_non_image_items.is_empty() {
hovered_non_image_items
} else if !hovered_image_items.is_empty() {
hovered_image_items
} else {
// If we aren't hovering anything, we are hovering the view itself.
vec![Item::View(query.view_id)]
}
};

// Associate the hovered space with the first item in the hovered item list.
// If we were to add several, views might render unnecessary additional hints.
// TODO(andreas): Should there be context if no item is hovered at all? There's no usecase for that today it seems.
Expand Down

0 comments on commit 07b8825

Please sign in to comment.