From e263ae6cde7945652fb72c7bee67f20c5ed513a8 Mon Sep 17 00:00:00 2001 From: Jeremy Leibs Date: Wed, 28 Aug 2024 09:12:26 -0400 Subject: [PATCH 1/5] Track which components are used by each transformed entity --- .../src/contexts/transform_context.rs | 51 ++++++------------ .../src/transform_component_tracker.rs | 53 ++++++++++++++----- 2 files changed, 57 insertions(+), 47 deletions(-) diff --git a/crates/viewer/re_space_view_spatial/src/contexts/transform_context.rs b/crates/viewer/re_space_view_spatial/src/contexts/transform_context.rs index f5ba0c709e28..ed9e6e171f39 100644 --- a/crates/viewer/re_space_view_spatial/src/contexts/transform_context.rs +++ b/crates/viewer/re_space_view_spatial/src/contexts/transform_context.rs @@ -530,27 +530,17 @@ fn query_and_resolve_tree_transform_at_entity( entity_db: &EntityDb, query: &LatestAtQuery, ) -> Option { - if !TransformComponentTracker::access(entity_db.store_id(), |tracker| { - tracker.is_potentially_transformed_transform3d(entity_path) - }) - .unwrap_or(false) - { + let Some(transform3d_components) = + TransformComponentTracker::access(entity_db.store_id(), |tracker| { + tracker.transform3d_components(entity_path).cloned() + }) + .flatten() + else { return None; - } + }; // TODO(#6743): Doesn't take into account overrides. - let result = entity_db.latest_at( - query, - entity_path, - [ - Translation3D::name(), - RotationAxisAngle::name(), - RotationQuat::name(), - Scale3D::name(), - TransformMat3x3::name(), - TransformRelation::name(), - ], - ); + let result = entity_db.latest_at(query, entity_path, transform3d_components); if result.components.is_empty() { return None; } @@ -586,26 +576,17 @@ fn query_and_resolve_instance_poses_at_entity( entity_db: &EntityDb, query: &LatestAtQuery, ) -> Vec { - if !TransformComponentTracker::access(entity_db.store_id(), |tracker| { - tracker.is_potentially_transformed_pose3d(entity_path) - }) - .unwrap_or(false) - { + let Some(pose3d_components) = + TransformComponentTracker::access(entity_db.store_id(), |tracker| { + tracker.pose3d_components(entity_path).cloned() + }) + .flatten() + else { return Vec::new(); - } + }; // TODO(#6743): Doesn't take into account overrides. - let result = entity_db.latest_at( - query, - entity_path, - [ - PoseTranslation3D::name(), - PoseRotationAxisAngle::name(), - PoseRotationQuat::name(), - PoseScale3D::name(), - PoseTransformMat3x3::name(), - ], - ); + let result = entity_db.latest_at(query, entity_path, pose3d_components); let max_count = result .components diff --git a/crates/viewer/re_space_view_spatial/src/transform_component_tracker.rs b/crates/viewer/re_space_view_spatial/src/transform_component_tracker.rs index 1174aa99b3cc..4f5e2fcedfda 100644 --- a/crates/viewer/re_space_view_spatial/src/transform_component_tracker.rs +++ b/crates/viewer/re_space_view_spatial/src/transform_component_tracker.rs @@ -20,11 +20,13 @@ use re_types::ComponentName; /// This is a huge performance improvement in practice, especially in recordings with many entities. #[derive(Default)] pub struct TransformComponentTracker { - /// Which entities have had any `Transform3D` component at any point in time. - transform3d_entities: IntSet, + /// Which entities have had any `Transform3D` component at any point in time, and which + /// components they actually make use of. + transform3d_entities: HashMap>, - /// Which entities have had any `InstancePoses3D` components at any point in time. - pose3d_entities: IntSet, + /// Which entities have had any `InstancePoses3D` components at any point in time, and + /// which components they actually make use of. + pose3d_entities: HashMap>, } impl TransformComponentTracker { @@ -41,13 +43,16 @@ impl TransformComponentTracker { } #[inline] - pub fn is_potentially_transformed_transform3d(&self, entity_path: &EntityPath) -> bool { - self.transform3d_entities.contains(&entity_path.hash()) + pub fn transform3d_components( + &self, + entity_path: &EntityPath, + ) -> Option<&IntSet> { + self.transform3d_entities.get(&entity_path.hash()) } #[inline] - pub fn is_potentially_transformed_pose3d(&self, entity_path: &EntityPath) -> bool { - self.pose3d_entities.contains(&entity_path.hash()) + pub fn pose3d_components(&self, entity_path: &EntityPath) -> Option<&IntSet> { + self.pose3d_entities.get(&entity_path.hash()) } } @@ -119,15 +124,39 @@ impl ChunkStoreSubscriber for TransformComponentTrackerStoreSubscriber { let entity_path_hash = event.chunk.entity_path().hash(); for component_name in event.chunk.component_names() { - if self.transform_components.contains(&component_name) { + if self.transform_components.contains(&component_name) + && event + .chunk + .components() + .get(&component_name) + .map_or(false, |list_array| { + list_array + .iter() + .any(|list| !list.map_or(false, |list| list.is_empty())) + }) + { transform_component_tracker .transform3d_entities - .insert(entity_path_hash); + .entry(entity_path_hash) + .or_default() + .insert(component_name); } - if self.pose_components.contains(&component_name) { + if self.pose_components.contains(&component_name) + && event + .chunk + .components() + .get(&component_name) + .map_or(false, |list_array| { + list_array + .iter() + .any(|list| !list.map_or(false, |list| list.is_empty())) + }) + { transform_component_tracker .pose3d_entities - .insert(entity_path_hash); + .entry(entity_path_hash) + .or_default() + .insert(component_name); } } } From ffed78830f8f34f7d37eabfb03929f6ead6c5c79 Mon Sep 17 00:00:00 2001 From: Jeremy Leibs Date: Wed, 28 Aug 2024 09:28:14 -0400 Subject: [PATCH 2/5] Don't look for overrides on unused components --- .../src/visualizers/transform3d_arrows.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/crates/viewer/re_space_view_spatial/src/visualizers/transform3d_arrows.rs b/crates/viewer/re_space_view_spatial/src/visualizers/transform3d_arrows.rs index 758e0843ac77..955dd83bba1a 100644 --- a/crates/viewer/re_space_view_spatial/src/visualizers/transform3d_arrows.rs +++ b/crates/viewer/re_space_view_spatial/src/visualizers/transform3d_arrows.rs @@ -1,7 +1,7 @@ use egui::Color32; use nohash_hasher::IntSet; use re_log_types::{EntityPath, Instance}; -use re_space_view::DataResultQuery; +use re_space_view::{latest_at_with_blueprint_resolved_data, DataResultQuery}; use re_types::{ archetypes::{Pinhole, Transform3D}, components::{AxisLength, ImagePlaneDistance}, @@ -122,8 +122,17 @@ impl VisualizerSystem for Transform3DArrowsVisualizer { .single_entity_transform_required(&data_result.entity_path, "Transform3DArrows") }; - let results = data_result - .latest_at_with_blueprint_resolved_data::(ctx, &latest_at_query); + // Note, we use this interface instead of `data_result latest_at_with_blueprint_resolved_data` to avoid querying + // for a bunch of unused components. + let results = latest_at_with_blueprint_resolved_data( + ctx, + None, + &latest_at_query, + data_result, + std::iter::once(AxisLength::name()), + false, + ); + let axis_length: f32 = results.get_mono_with_fallback::().into(); if axis_length == 0.0 { From e0839fb0040dcb22c98489996a4822665d2ef46e Mon Sep 17 00:00:00 2001 From: Jeremy Leibs Date: Wed, 28 Aug 2024 09:36:57 -0400 Subject: [PATCH 3/5] Fix comment --- .../src/visualizers/transform3d_arrows.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/viewer/re_space_view_spatial/src/visualizers/transform3d_arrows.rs b/crates/viewer/re_space_view_spatial/src/visualizers/transform3d_arrows.rs index 955dd83bba1a..61a0ca8a3223 100644 --- a/crates/viewer/re_space_view_spatial/src/visualizers/transform3d_arrows.rs +++ b/crates/viewer/re_space_view_spatial/src/visualizers/transform3d_arrows.rs @@ -122,8 +122,9 @@ impl VisualizerSystem for Transform3DArrowsVisualizer { .single_entity_transform_required(&data_result.entity_path, "Transform3DArrows") }; - // Note, we use this interface instead of `data_result latest_at_with_blueprint_resolved_data` to avoid querying - // for a bunch of unused components. + // Note, we use this interface instead of `data_result.latest_at_with_blueprint_resolved_data` to avoid querying + // for a bunch of unused components. The actual transform data comes out of the context manager and can't be + // overridden via blueprint anyways. let results = latest_at_with_blueprint_resolved_data( ctx, None, From 9fbd1add962996f17f73b9b29dd4dbeca54e77d4 Mon Sep 17 00:00:00 2001 From: Jeremy Leibs Date: Wed, 28 Aug 2024 10:20:27 -0400 Subject: [PATCH 4/5] Use IntMap instead of HashMap --- .../src/transform_component_tracker.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/viewer/re_space_view_spatial/src/transform_component_tracker.rs b/crates/viewer/re_space_view_spatial/src/transform_component_tracker.rs index 4f5e2fcedfda..5879d91d7a27 100644 --- a/crates/viewer/re_space_view_spatial/src/transform_component_tracker.rs +++ b/crates/viewer/re_space_view_spatial/src/transform_component_tracker.rs @@ -1,7 +1,7 @@ use ahash::HashMap; use once_cell::sync::OnceCell; -use nohash_hasher::IntSet; +use nohash_hasher::{IntMap, IntSet}; use re_chunk_store::{ ChunkStore, ChunkStoreDiffKind, ChunkStoreEvent, ChunkStoreSubscriber, ChunkStoreSubscriberHandle, @@ -22,11 +22,11 @@ use re_types::ComponentName; pub struct TransformComponentTracker { /// Which entities have had any `Transform3D` component at any point in time, and which /// components they actually make use of. - transform3d_entities: HashMap>, + transform3d_entities: IntMap>, /// Which entities have had any `InstancePoses3D` components at any point in time, and /// which components they actually make use of. - pose3d_entities: HashMap>, + pose3d_entities: IntMap>, } impl TransformComponentTracker { From 8e77979d8a082b427ebf03ac24e93f3505a7a348 Mon Sep 17 00:00:00 2001 From: Jeremy Leibs Date: Wed, 28 Aug 2024 10:21:55 -0400 Subject: [PATCH 5/5] Cleaner non-empty check --- .../src/transform_component_tracker.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/crates/viewer/re_space_view_spatial/src/transform_component_tracker.rs b/crates/viewer/re_space_view_spatial/src/transform_component_tracker.rs index 5879d91d7a27..4e13e9c95217 100644 --- a/crates/viewer/re_space_view_spatial/src/transform_component_tracker.rs +++ b/crates/viewer/re_space_view_spatial/src/transform_component_tracker.rs @@ -130,9 +130,7 @@ impl ChunkStoreSubscriber for TransformComponentTrackerStoreSubscriber { .components() .get(&component_name) .map_or(false, |list_array| { - list_array - .iter() - .any(|list| !list.map_or(false, |list| list.is_empty())) + list_array.offsets().lengths().any(|len| len > 0) }) { transform_component_tracker @@ -147,9 +145,7 @@ impl ChunkStoreSubscriber for TransformComponentTrackerStoreSubscriber { .components() .get(&component_name) .map_or(false, |list_array| { - list_array - .iter() - .any(|list| !list.map_or(false, |list| list.is_empty())) + list_array.offsets().lengths().any(|len| len > 0) }) { transform_component_tracker