Skip to content

Commit 0a38698

Browse files
committed
fix temporal gaps in gpu picking report
1 parent a1669ac commit 0a38698

File tree

5 files changed

+44
-4
lines changed

5 files changed

+44
-4
lines changed

crates/re_viewer/src/ui/view_spatial/scene/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -247,10 +247,12 @@ impl SceneSpatial {
247247
SpatialNavigationMode::ThreeD
248248
}
249249

250+
#[allow(clippy::too_many_arguments)]
250251
pub fn picking(
251252
&self,
252253
render_ctx: &re_renderer::RenderContext,
253254
gpu_readback_identifier: re_renderer::GpuReadbackIdentifier,
255+
previous_picking_result: &Option<PickingResult>,
254256
pointer_in_ui: glam::Vec2,
255257
ui_rect: &egui::Rect,
256258
eye: &Eye,
@@ -259,6 +261,7 @@ impl SceneSpatial {
259261
picking::picking(
260262
render_ctx,
261263
gpu_readback_identifier,
264+
previous_picking_result,
262265
pointer_in_ui,
263266
ui_rect,
264267
eye,

crates/re_viewer/src/ui/view_spatial/scene/picking.rs

+23-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::{
1010
ui::view_spatial::eye::Eye,
1111
};
1212

13+
#[derive(Clone)]
1314
pub enum AdditionalPickingInfo {
1415
/// No additional picking information.
1516
None,
@@ -21,6 +22,7 @@ pub enum AdditionalPickingInfo {
2122
GuiOverlay,
2223
}
2324

25+
#[derive(Clone)]
2426
pub struct PickingRayHit {
2527
/// What entity or instance got hit by the picking ray.
2628
///
@@ -34,6 +36,9 @@ pub struct PickingRayHit {
3436

3537
/// Any additional information about the picking hit.
3638
pub info: AdditionalPickingInfo,
39+
40+
/// True if this picking result came from a GPU picking pass.
41+
pub used_gpu_picking: bool,
3742
}
3843

3944
impl PickingRayHit {
@@ -43,10 +48,12 @@ impl PickingRayHit {
4348
ray_t: t,
4449
info: AdditionalPickingInfo::None,
4550
depth_offset: 0,
51+
used_gpu_picking: false,
4652
}
4753
}
4854
}
4955

56+
#[derive(Clone)]
5057
pub struct PickingResult {
5158
/// Picking ray hit for an opaque object (if any).
5259
pub opaque_hit: Option<PickingRayHit>,
@@ -131,11 +138,11 @@ impl PickingState {
131138
}
132139
}
133140

134-
// TODO(andreas): This should be temporary. As we switch over (almost) everything over to gpu based picking this should go away.
135141
#[allow(clippy::too_many_arguments)]
136142
pub fn picking(
137143
render_ctx: &re_renderer::RenderContext,
138144
gpu_readback_identifier: re_renderer::GpuReadbackIdentifier,
145+
previous_picking_result: &Option<PickingResult>,
139146
pointer_in_ui: glam::Vec2,
140147
ui_rect: &egui::Rect,
141148
eye: &Eye,
@@ -160,6 +167,7 @@ pub fn picking(
160167
ray_t: f32::INFINITY,
161168
info: AdditionalPickingInfo::None,
162169
depth_offset: 0,
170+
used_gpu_picking: false,
163171
},
164172
// Combined, sorted (and partially "hidden") by opaque results later.
165173
transparent_hits: Vec::new(),
@@ -206,9 +214,20 @@ pub fn picking(
206214

207215
// TODO(andreas): We're lacking depth information!
208216
state.closest_opaque_pick.instance_path_hash = picked_object;
217+
state.closest_opaque_pick.used_gpu_picking = true;
209218
} else {
210-
// TODO(andreas): It is *possible* that some frames we don't get a picking result and the frame after we get several.
219+
// It is possible that some frames we don't get a picking result and the frame after we get several.
211220
// We need to cache the last picking result and use it until we get a new one or the mouse leaves the screen.
221+
// (Andreas: On my mac this *actually* happens in very simple scenes, I get occasional frames with 0 and then with 2 picking results!)
222+
if let Some(PickingResult {
223+
opaque_hit: Some(previous_opaque_hit),
224+
..
225+
}) = previous_picking_result
226+
{
227+
if previous_opaque_hit.used_gpu_picking {
228+
state.closest_opaque_pick = previous_opaque_hit.clone();
229+
}
230+
}
212231
}
213232
}
214233

@@ -368,6 +387,7 @@ fn picking_textured_rects(
368387
ray_t: t,
369388
info: AdditionalPickingInfo::TexturedRect(glam::vec2(u, v)),
370389
depth_offset: rect.depth_offset,
390+
used_gpu_picking: false,
371391
};
372392
state.check_hit(0.0, picking_hit, rect.multiplicative_tint.a() < 1.0);
373393
}
@@ -391,6 +411,7 @@ fn picking_ui_rects(
391411
ray_t: 0.0,
392412
info: AdditionalPickingInfo::GuiOverlay,
393413
depth_offset: 0,
414+
used_gpu_picking: false,
394415
},
395416
false,
396417
);

crates/re_viewer/src/ui/view_spatial/ui.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ use crate::{
1818
};
1919

2020
use super::{
21-
eye::Eye, scene::SceneSpatialUiData, ui_2d::View2DState, ui_3d::View3DState, SceneSpatial,
22-
SpaceSpecs,
21+
eye::Eye,
22+
scene::{PickingResult, SceneSpatialUiData},
23+
ui_2d::View2DState,
24+
ui_3d::View3DState,
25+
SceneSpatial, SpaceSpecs,
2326
};
2427

2528
/// Describes how the scene is navigated, determining if it is a 2D or 3D experience.
@@ -77,6 +80,10 @@ pub struct ViewSpatialState {
7780
#[serde(skip)]
7881
pub scene_num_primitives: usize,
7982

83+
/// Last frame's picking result.
84+
#[serde(skip)]
85+
pub previous_picking_result: Option<PickingResult>,
86+
8087
pub(super) state_2d: View2DState,
8188
pub(super) state_3d: View3DState,
8289

@@ -97,6 +104,7 @@ impl Default for ViewSpatialState {
97104
point_radius: re_renderer::Size::AUTO, // let re_renderer decide
98105
line_radius: re_renderer::Size::AUTO, // let re_renderer decide
99106
},
107+
previous_picking_result: None,
100108
}
101109
}
102110
}

crates/re_viewer/src/ui/view_spatial/ui_2d.rs

+4
Original file line numberDiff line numberDiff line change
@@ -367,11 +367,13 @@ fn view_2d_scrollable(
367367
let picking_result = scene.picking(
368368
ctx.render_ctx,
369369
space_view_id.gpu_readback_id(),
370+
&state.previous_picking_result,
370371
glam::vec2(pointer_pos_space.x, pointer_pos_space.y),
371372
&scene_rect_accum,
372373
&eye,
373374
hover_radius,
374375
);
376+
state.previous_picking_result = Some(picking_result.clone());
375377

376378
for hit in picking_result.iter_hits() {
377379
let Some(instance_path) = hit.instance_path_hash.resolve(&ctx.log_db.entity_db)
@@ -462,6 +464,8 @@ fn view_2d_scrollable(
462464
.map(|instance_path| Item::InstancePath(Some(space_view_id), instance_path))
463465
}));
464466
}
467+
} else {
468+
state.previous_picking_result = None;
465469
}
466470

467471
ctx.select_hovered_on_click(&response);

crates/re_viewer/src/ui/view_spatial/ui_3d.rs

+4
Original file line numberDiff line numberDiff line change
@@ -377,11 +377,13 @@ pub fn view_3d(
377377
let picking_result = scene.picking(
378378
ctx.render_ctx,
379379
space_view_id.gpu_readback_id(),
380+
&state.previous_picking_result,
380381
glam::vec2(pointer_pos.x, pointer_pos.y),
381382
&rect,
382383
&eye,
383384
5.0,
384385
);
386+
state.previous_picking_result = Some(picking_result.clone());
385387

386388
for hit in picking_result.iter_hits() {
387389
let Some(instance_path) = hit.instance_path_hash.resolve(&ctx.log_db.entity_db)
@@ -459,6 +461,8 @@ pub fn view_3d(
459461
.map(|hit| picking_result.space_position(hit));
460462

461463
project_onto_other_spaces(ctx, &scene.space_cameras, &mut state.state_3d, space);
464+
} else {
465+
state.previous_picking_result = None;
462466
}
463467

464468
ctx.select_hovered_on_click(&response);

0 commit comments

Comments
 (0)