Skip to content

Commit d112216

Browse files
committed
Add option to specify target_frame to SpatialInformation
1 parent 00e9fb9 commit d112216

File tree

16 files changed

+223
-29
lines changed

16 files changed

+223
-29
lines changed

crates/store/re_types/definitions/rerun/blueprint/archetypes/spatial_information.fbs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ namespace rerun.blueprint.archetypes;
44
table SpatialInformation (
55
"attr.rerun.scope": "blueprint"
66
) {
7+
/// The target reference frame for all transformations.
8+
///
9+
/// Defaults to the coordinate frame used by the space origin entity.
10+
target_frame: rerun.components.TransformFrameId ("attr.rerun.component_optional", order: 50);
11+
712
/// Whether axes should be shown at the origin.
813
show_axes: rerun.blueprint.components.Enabled ("attr.rerun.component_optional", nullable, order: 100);
914

crates/store/re_types/src/blueprint/archetypes/spatial_information.rs

Lines changed: 58 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/store/re_types/src/reflection/mod.rs

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/viewer/re_component_ui/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ use re_types::components::{
4646
AggregationPolicy, AlbedoFactor, AxisLength, Color, DepthMeter, DrawOrder, FillMode, FillRatio,
4747
GammaCorrection, GraphType, ImagePlaneDistance, LinearSpeed, MagnificationFilter, MarkerSize,
4848
Name, Opacity, Position2D, Position3D, Range1D, Scale3D, SeriesVisible, ShowLabels,
49-
StrokeWidth, Text, Timestamp, TransformRelation, Translation3D, ValueRange, Vector3D,
50-
VideoCodec, Visible,
49+
StrokeWidth, Text, Timestamp, TransformFrameId, TransformRelation, Translation3D, ValueRange,
50+
Vector3D, VideoCodec, Visible,
5151
};
5252
use re_viewer_context::gpu_bridge::colormap_edit_or_view_ui;
5353

@@ -118,6 +118,7 @@ pub fn create_component_ui_registry() -> re_viewer_context::ComponentUiRegistry
118118
registry.add_multiline_edit_or_view::<Text>(edit_multiline_string);
119119
registry.add_singleline_edit_or_view::<Name>(edit_singleline_string);
120120
registry.add_multiline_edit_or_view::<Name>(edit_multiline_string);
121+
registry.add_singleline_edit_or_view::<TransformFrameId>(edit_singleline_string);
121122

122123
// Enums:
123124
// TODO(#6974): Enums editors trivial and always the same, provide them automatically!

crates/viewer/re_view_spatial/src/contexts/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use re_renderer::DepthOffset;
77
use re_types::ViewClassIdentifier;
88
use re_view::AnnotationSceneContext;
99
use re_viewer_context::{Annotations, ViewClassRegistryError};
10-
pub use transform_tree_context::{TransformInfo, TransformTreeContext};
10+
pub use transform_tree_context::{TransformInfo, TransformTreeContext, UNKNOWN_SPACE_ORIGIN};
1111

1212
/// Context objects for a single entity in a spatial scene.
1313
pub struct SpatialSceneEntityContext<'a> {

crates/viewer/re_view_spatial/src/contexts/transform_tree_context.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,23 @@ use re_chunk_store::LatestAtQuery;
55
use re_log_types::{EntityPath, EntityPathHash};
66
use re_tf::{TransformFrameId, TransformFrameIdHash, TreeTransform};
77
use re_types::components::ImagePlaneDistance;
8-
use re_types::{ArchetypeName, archetypes};
8+
use re_types::{ArchetypeName, archetypes, blueprint};
99
use re_view::{DataResultQuery as _, latest_at_with_blueprint_resolved_data};
1010
use re_viewer_context::{
1111
DataResult, IdentifiedViewSystem, TransformDatabaseStoreCache, ViewContext, ViewContextSystem,
1212
ViewContextSystemOncePerFrameResult, typed_fallback_for,
1313
};
14+
use re_viewport_blueprint::ViewProperty;
1415
use vec1::smallvec_v1::SmallVec1;
1516

1617
type FrameIdMapping = IntMap<TransformFrameIdHash, TransformFrameId>;
1718

19+
/// Currently, there is no straightforward way to retrieve the space origin
20+
/// when registering fallbacks. So, if unknown we set the target frame to a
21+
/// dummy string and rely on the view to supply that information after the
22+
/// first frame.
23+
pub const UNKNOWN_SPACE_ORIGIN: &str = "<unknown space origin>";
24+
1825
/// Details on how to transform an entity (!) to the origin of the view's space.
1926
#[derive(Clone, Debug, PartialEq)]
2027
pub struct TransformInfo {
@@ -186,8 +193,35 @@ impl ViewContextSystem for TransformTreeContext {
186193
// Currently, we don't keep it around during the frame, but we may do so in the future.
187194
self.entity_transform_id_mapping = EntityTransformIdMapping::new(ctx, query);
188195

189-
// Target frame is the coordinate frame of the space origin entity.
190-
self.target_frame = self.transform_frame_id_for(query.space_origin.hash());
196+
// Target frame - check for blueprint override first, otherwise use space origin's coordinate frame.
197+
self.target_frame = {
198+
let spatial_info_prop = ViewProperty::from_archetype::<
199+
blueprint::archetypes::SpatialInformation,
200+
>(
201+
ctx.blueprint_db(), ctx.blueprint_query(), ctx.view_id
202+
);
203+
204+
let target_frame_component = spatial_info_prop
205+
.component_or_fallback::<TransformFrameId>(
206+
ctx,
207+
blueprint::archetypes::SpatialInformation::descriptor_target_frame().component,
208+
);
209+
210+
match target_frame_component {
211+
Ok(target_frame) => {
212+
let target_frame_str = target_frame.as_str();
213+
if target_frame_str == UNKNOWN_SPACE_ORIGIN {
214+
self.transform_frame_id_for(query.space_origin.hash())
215+
} else {
216+
TransformFrameIdHash::from_str(target_frame.as_str())
217+
}
218+
}
219+
Err(err) => {
220+
re_log::error_once!("Failed to query target frame: {err}");
221+
self.transform_frame_id_for(query.space_origin.hash())
222+
}
223+
}
224+
};
191225

192226
let latest_at_query = query.latest_at_query();
193227

crates/viewer/re_view_spatial/src/ui.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ pub struct SpatialViewState {
6363
pub pinhole_at_origin: Option<Pinhole>,
6464

6565
pub visual_bounds_2d: Option<VisualBounds2D>,
66+
67+
/// The target frame, i.e., the coordinate frame that transforms are resolved to.
68+
/// Computed from the space origin via the transform tree.
69+
pub target_frame: Option<String>,
6670
}
6771

6872
impl ViewState for SpatialViewState {

crates/viewer/re_view_spatial/src/view_2d.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use re_viewer_context::{
1010
ViewSpawnHeuristics, ViewState, ViewStateExt as _, ViewSystemExecutionError, ViewerContext,
1111
};
1212

13-
use crate::contexts::register_spatial_contexts;
13+
use crate::contexts::{TransformTreeContext, register_spatial_contexts};
1414
use crate::heuristics::default_visualized_entities_for_visualizer_kind;
1515
use crate::max_image_dimension_subscriber::{ImageTypes, MaxDimensions};
1616
use crate::shared_fallbacks;
@@ -255,6 +255,11 @@ impl ViewClass for SpatialView2D {
255255
let state = state.downcast_mut::<SpatialViewState>()?;
256256
state.update_frame_statistics(ui, &system_output, SpatialViewKind::TwoD);
257257

258+
// Store the target frame for display in the selection panel
259+
if let Ok(transforms) = system_output.context_systems.get::<TransformTreeContext>() {
260+
state.target_frame = Some(transforms.format_frame(transforms.target_frame()));
261+
}
262+
258263
self.view_2d(ctx, ui, state, query, system_output)
259264
}
260265
}

crates/viewer/re_view_spatial/src/view_3d.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use itertools::Itertools as _;
44
use nohash_hasher::IntSet;
55
use re_entity_db::EntityDb;
66
use re_log_types::EntityPath;
7-
use re_tf::query_view_coordinates;
7+
use re_tf::{TransformFrameId, query_view_coordinates};
88
use re_types::blueprint::archetypes::{Background, EyeControls3D, LineGrid3D, SpatialInformation};
99
use re_types::blueprint::components::Eye3DKind;
1010
use re_types::components::{LinearSpeed, Plane3D, Position3D, Vector3D};
@@ -22,7 +22,7 @@ use re_viewer_context::{
2222
};
2323
use re_viewport_blueprint::ViewProperty;
2424

25-
use crate::contexts::register_spatial_contexts;
25+
use crate::contexts::{TransformTreeContext, UNKNOWN_SPACE_ORIGIN, register_spatial_contexts};
2626
use crate::heuristics::default_visualized_entities_for_visualizer_kind;
2727
use crate::shared_fallbacks;
2828
use crate::spatial_topology::{HeuristicHints, SpatialTopology, SubSpaceConnectionFlags};
@@ -244,6 +244,24 @@ impl ViewClass for SpatialView3D {
244244
},
245245
);
246246

247+
system_registry.register_fallback_provider(
248+
SpatialInformation::descriptor_target_frame().component,
249+
|ctx| {
250+
let unknown_space_origin = || TransformFrameId(UNKNOWN_SPACE_ORIGIN.into());
251+
252+
let Ok(state) = ctx.view_state().downcast_ref::<SpatialViewState>() else {
253+
return unknown_space_origin();
254+
};
255+
256+
// Return the computed target frame from the view state
257+
state
258+
.target_frame
259+
.as_ref()
260+
.map(|frame_str| TransformFrameId(frame_str.clone().into()))
261+
.unwrap_or_else(unknown_space_origin)
262+
},
263+
);
264+
247265
shared_fallbacks::register_fallbacks(system_registry);
248266

249267
// Ensure spatial topology is registered.
@@ -508,10 +526,10 @@ impl ViewClass for SpatialView3D {
508526

509527
re_ui::list_item::list_item_scope(ui, "spatial_view3d_selection_ui", |ui| {
510528
let view_ctx = self.view_context(ctx, view_id, state);
529+
view_property_ui::<SpatialInformation>(&view_ctx, ui);
511530
view_property_ui::<EyeControls3D>(&view_ctx, ui);
512531
view_property_ui::<Background>(&view_ctx, ui);
513532
view_property_ui_grid3d(&view_ctx, ui);
514-
view_property_ui::<SpatialInformation>(&view_ctx, ui);
515533
});
516534

517535
Ok(())
@@ -531,6 +549,11 @@ impl ViewClass for SpatialView3D {
531549
let state = state.downcast_mut::<SpatialViewState>()?;
532550
state.update_frame_statistics(ui, &system_output, SpatialViewKind::ThreeD);
533551

552+
// Store the target frame for display in the selection panel
553+
if let Ok(transforms) = system_output.context_systems.get::<TransformTreeContext>() {
554+
state.target_frame = Some(transforms.format_frame(transforms.target_frame()));
555+
}
556+
534557
self.view_3d(ctx, ui, state, query, system_output)
535558
}
536559
}

crates/viewer/re_viewer/src/default_views.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ mod tests {
6363
let mut did_run = false;
6464

6565
let mut harness = test_context
66-
.setup_kittest_for_rendering_ui([400.0, 640.0])
66+
.setup_kittest_for_rendering_ui([400.0, 700.0])
6767
.build_ui(|ui| {
6868
ui.ctx().set_theme(egui_theme);
6969

0 commit comments

Comments
 (0)