Skip to content

Commit fdb7a45

Browse files
committed
make source & target handling prettier
1 parent a7b838b commit fdb7a45

File tree

1 file changed

+94
-60
lines changed

1 file changed

+94
-60
lines changed

crates/store/re_tf/src/transform_forest.rs

Lines changed: 94 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,31 @@ pub enum TransformFromToError {
154154
},
155155
}
156156

157+
impl TransformFromToError {
158+
fn no_path_between_target_and_source(target: &TargetInfo, source: &SourceInfo<'_>) -> Self {
159+
Self::NoPathBetweenFrames {
160+
target: target.id,
161+
src: source.id,
162+
target_root: target.root,
163+
source_root: source.root,
164+
}
165+
}
166+
}
167+
168+
/// Private utility struct for working with a target frame.
169+
struct TargetInfo {
170+
id: EntityPathHash,
171+
root: EntityPathHash,
172+
target_from_root: glam::Affine3A,
173+
}
174+
175+
/// Private utility struct for working with a source frame.
176+
struct SourceInfo<'a> {
177+
id: EntityPathHash,
178+
root: EntityPathHash,
179+
root_from_source: &'a TransformInfo,
180+
}
181+
157182
/// Properties of a pinhole transform tree root.
158183
///
159184
/// Each pinhole forms its own subtree which may be embedded into a 3D space.
@@ -204,7 +229,7 @@ pub struct TransformForest {
204229
roots: IntMap<EntityPathHash, TransformTreeRootInfo>,
205230

206231
/// All entities reachable from one of the tree roots.
207-
transform_per_entity: IntMap<EntityPathHash, TransformInfo>,
232+
root_from_entity: IntMap<EntityPathHash, TransformInfo>,
208233
}
209234

210235
impl TransformForest {
@@ -226,7 +251,7 @@ impl TransformForest {
226251
let mut tree = Self {
227252
roots: std::iter::once((EntityPath::root().hash(), TransformTreeRootInfo::EntityRoot))
228253
.collect(),
229-
transform_per_entity: Default::default(),
254+
root_from_entity: Default::default(),
230255
};
231256
tree.gather_descendants_transforms(
232257
entity_tree,
@@ -254,7 +279,7 @@ impl TransformForest {
254279
let root_from_parent = transform_root_from_parent.target_from_entity;
255280

256281
let previous_transform = self
257-
.transform_per_entity
282+
.root_from_entity
258283
.insert(subtree.path.hash(), transform_root_from_parent);
259284
debug_assert!(previous_transform.is_none(), "Root was added already"); // TODO(andreas): Build out into cycle detection (cycles can't _yet_ happen)
260285

@@ -337,10 +362,10 @@ impl TransformForest {
337362
sources: impl Iterator<Item = EntityPathHash>,
338363
lookup_image_plane_distance: &dyn Fn(EntityPathHash) -> f32,
339364
) -> impl Iterator<Item = (EntityPathHash, Result<TransformInfo, TransformFromToError>)> {
340-
// We're looking for common root between source and target.
365+
// We're looking for a common root between source and target.
341366
// We start by looking up the target's tree root.
342367

343-
let Some(root_from_target) = self.transform_per_entity.get(&target) else {
368+
let Some(root_from_target) = self.root_from_entity.get(&target) else {
344369
return itertools::Either::Left(sources.map(move |source| {
345370
(
346371
source,
@@ -349,8 +374,8 @@ impl TransformForest {
349374
}));
350375
};
351376

352-
// Invert `root_from_target` to get `target_from_root`.
353-
let (target_root, target_from_root) = {
377+
// Invert `root_from_target` to get `target.from_root`.
378+
let target = {
354379
let TransformInfo {
355380
root: target_root,
356381
target_from_entity: root_from_entity,
@@ -360,83 +385,92 @@ impl TransformForest {
360385
target_from_archetype: _,
361386
} = &root_from_target;
362387

363-
(*target_root, root_from_entity.inverse())
388+
TargetInfo {
389+
id: target,
390+
root: *target_root,
391+
target_from_root: root_from_entity.inverse(),
392+
}
364393
};
365394

366395
itertools::Either::Right(sources.map(move |source| {
367-
let Some(root_from_source) = self.transform_per_entity.get(&source) else {
396+
let Some(root_from_source) = self.root_from_entity.get(&source) else {
368397
return (
369398
source,
370399
Err(TransformFromToError::UnknownSourceFrame(source)),
371400
);
372401
};
373402

374-
let source_root = root_from_source.root;
403+
let source = SourceInfo {
404+
id: source,
405+
root: root_from_source.root,
406+
root_from_source,
407+
};
375408

376409
// Common case: both source & target share the same root.
377-
if source_root == target_root {
410+
let result = if source.root == target.root {
378411
// TODO: fast track for root being target.
379412
// target_from_source = target_from_reference * root_from_source
380-
let target_from_source = root_from_source.left_multiply(target_from_root);
381-
(source, Ok(target_from_source))
413+
let target_from_source = root_from_source.left_multiply(target.target_from_root);
414+
Ok(target_from_source)
382415
}
383416
// There might be a connection via a pinhole making this 2D in 3D.
384417
else if let Some(TransformTreeRootInfo::Pinhole(pinhole_tree_root)) =
385-
self.roots.get(&source_root)
418+
self.roots.get(&source.root)
386419
{
387-
let PinholeTreeRoot {
388-
parent_tree_root,
389-
pinhole_projection,
390-
parent_root_from_pinhole_root: root_from_pinhole3d,
391-
} = pinhole_tree_root;
392-
393-
if *parent_tree_root != target_root {
394-
return (
395-
source,
396-
Err(TransformFromToError::NoPathBetweenFrames {
397-
target,
398-
src: source,
399-
target_root,
400-
source_root,
401-
}),
402-
);
403-
}
404-
405-
// Rename for clarification:
406-
let pinhole2d_from_source = root_from_source;
407-
408-
// There's a connection via a pinhole making this 2D in 3D.
409-
// We can transform into the target space!
410-
let pinhole_image_plane_distance = lookup_image_plane_distance(source_root);
411-
412-
// TODO: Locally cache pinhole transform?
413-
let pinhole3d_from_pinhole2d = pinhole2d_image_plane_from_pinhole3d(
414-
pinhole_projection,
415-
pinhole_image_plane_distance,
416-
);
417-
let target_from_pinhole2d =
418-
target_from_root * root_from_pinhole3d * pinhole3d_from_pinhole2d;
419-
420-
// target_from_source = target_from_pinhole2d * pinhole2d_from_source
421-
let target_from_source = pinhole2d_from_source.left_multiply(target_from_pinhole2d);
422-
(source, Ok(target_from_source))
420+
from_2d_source_to_3d_target(
421+
&target,
422+
&source,
423+
pinhole_tree_root,
424+
lookup_image_plane_distance,
425+
)
423426
}
424427
// Disconnected, we can't transform into the target space.
425428
else {
426-
(
427-
source,
428-
Err(TransformFromToError::NoPathBetweenFrames {
429-
target,
430-
src: source,
431-
target_root,
432-
source_root,
433-
}),
434-
)
435-
}
429+
Err(TransformFromToError::no_path_between_target_and_source(
430+
&target, &source,
431+
))
432+
};
433+
434+
(source.id, result)
436435
}))
437436
}
438437
}
439438

439+
fn from_2d_source_to_3d_target(
440+
target: &TargetInfo,
441+
source: &SourceInfo<'_>,
442+
pinhole_tree_root: &PinholeTreeRoot,
443+
lookup_image_plane_distance: &dyn Fn(EntityPathHash) -> f32,
444+
) -> Result<TransformInfo, TransformFromToError> {
445+
let PinholeTreeRoot {
446+
parent_tree_root,
447+
pinhole_projection,
448+
parent_root_from_pinhole_root: root_from_pinhole3d,
449+
} = pinhole_tree_root;
450+
451+
if *parent_tree_root != target.root {
452+
return Err(TransformFromToError::no_path_between_target_and_source(
453+
target, source,
454+
));
455+
}
456+
457+
// Rename for clarification:
458+
let pinhole2d_from_source = source.root_from_source;
459+
460+
// There's a connection via a pinhole making this 2D in 3D.
461+
// We can transform into the target space!
462+
let pinhole_image_plane_distance = lookup_image_plane_distance(source.root);
463+
464+
// TODO: Locally cache pinhole transform?
465+
let pinhole3d_from_pinhole2d =
466+
pinhole2d_image_plane_from_pinhole3d(pinhole_projection, pinhole_image_plane_distance);
467+
let target_from_pinhole2d =
468+
target.target_from_root * root_from_pinhole3d * pinhole3d_from_pinhole2d;
469+
470+
// target_from_source = target_from_pinhole2d * pinhole2d_from_source
471+
Ok(pinhole2d_from_source.left_multiply(target_from_pinhole2d))
472+
}
473+
440474
fn left_multiply_smallvec1_of_transforms(
441475
target_from_reference: glam::Affine3A,
442476
reference_from_source: &SmallVec1<[glam::Affine3A; 1]>,

0 commit comments

Comments
 (0)