@@ -77,11 +77,13 @@ pub fn picking(
77
77
) ;
78
78
state. previous_picking_result = Some ( picking_result. clone ( ) ) ;
79
79
80
- let mut hovered_items = Vec :: new ( ) ;
80
+ let mut hovered_image_items = Vec :: new ( ) ;
81
+ let mut hovered_non_image_items = Vec :: new ( ) ;
81
82
82
83
// Depth at pointer used for projecting rays from a hovered 2D view to corresponding 3D view(s).
83
84
// TODO(#1818): Depth at pointer only works for depth images so far.
84
85
let mut depth_at_pointer = None ;
86
+
85
87
for ( hit_idx, hit) in picking_result. hits . iter ( ) . enumerate ( ) {
86
88
let Some ( mut instance_path) = hit. instance_path_hash . resolve ( ctx. recording ( ) ) else {
87
89
// Entity no longer exists in db.
@@ -161,14 +163,35 @@ pub fn picking(
161
163
} )
162
164
} ;
163
165
164
- hovered_items. push ( Item :: DataResult ( query. view_id , instance_path. clone ( ) ) ) ;
165
- }
166
+ let item = Item :: DataResult ( query. view_id , instance_path. clone ( ) ) ;
166
167
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
+ }
170
173
}
171
174
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
+
172
195
// Associate the hovered space with the first item in the hovered item list.
173
196
// If we were to add several, views might render unnecessary additional hints.
174
197
// 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