@@ -396,6 +396,9 @@ impl TransformForest {
396
396
// Query type of target's root for later.
397
397
let target_root_info = self . roots . get ( & target. root ) ;
398
398
399
+ // Local cache for connecting pinhole spaces with their parent 3D space.
400
+ let mut pinhole_tree_connector_cache = IntMap :: default ( ) ;
401
+
399
402
itertools:: Either :: Right ( sources. map ( move |source| {
400
403
let Some ( root_from_source) = self . root_from_entity . get ( & source) else {
401
404
return (
@@ -423,7 +426,12 @@ impl TransformForest {
423
426
// There might be a connection via a pinhole making this 3D in 2D.
424
427
else if let Some ( TransformTreeRootInfo :: Pinhole ( pinhole_tree_root) ) = target_root_info
425
428
{
426
- from_3d_source_to_2d_target ( & target, & source, pinhole_tree_root)
429
+ from_3d_source_to_2d_target (
430
+ & target,
431
+ & source,
432
+ pinhole_tree_root,
433
+ & mut pinhole_tree_connector_cache,
434
+ )
427
435
}
428
436
// There might be a connection via a pinhole making this 2D in 3D.
429
437
else if let Some ( TransformTreeRootInfo :: Pinhole ( pinhole_tree_root) ) =
@@ -434,6 +442,7 @@ impl TransformForest {
434
442
& source,
435
443
pinhole_tree_root,
436
444
lookup_image_plane_distance,
445
+ & mut pinhole_tree_connector_cache,
437
446
)
438
447
}
439
448
// Disconnected, we can't transform into the target space.
@@ -453,6 +462,7 @@ fn from_2d_source_to_3d_target(
453
462
source : & SourceInfo < ' _ > ,
454
463
source_pinhole_tree_root : & PinholeTreeRoot ,
455
464
lookup_image_plane_distance : & dyn Fn ( EntityPathHash ) -> f32 ,
465
+ target_from_image_plane_cache : & mut IntMap < EntityPathHash , glam:: Affine3A > ,
456
466
) -> Result < TransformInfo , TransformFromToError > {
457
467
let PinholeTreeRoot {
458
468
parent_tree_root,
@@ -471,24 +481,24 @@ fn from_2d_source_to_3d_target(
471
481
// Rename for clarification:
472
482
let image_plane_from_source = source. root_from_source ;
473
483
474
- // There's a connection via a pinhole making this 2D in 3D.
475
- // We can transform into the target space!
476
- let pinhole_image_plane_distance = lookup_image_plane_distance ( source. root ) ;
477
-
478
- // TODO: Locally cache pinhole transform?
479
- let pinhole3d_from_image_plane =
480
- pinhole3d_from_image_plane ( pinhole_projection, pinhole_image_plane_distance) ;
481
- let target_from_image_plane =
482
- target. target_from_root * root_from_pinhole3d * pinhole3d_from_image_plane;
484
+ let target_from_image_plane = target_from_image_plane_cache
485
+ . entry ( source. root )
486
+ . or_insert_with ( || {
487
+ let pinhole_image_plane_distance = lookup_image_plane_distance ( source. root ) ;
488
+ let pinhole3d_from_image_plane =
489
+ pinhole3d_from_image_plane ( pinhole_projection, pinhole_image_plane_distance) ;
490
+ target. target_from_root * root_from_pinhole3d * pinhole3d_from_image_plane
491
+ } ) ;
483
492
484
493
// target_from_source = target_from_image_plane * image_plane_from_source
485
- Ok ( image_plane_from_source. left_multiply ( target_from_image_plane) )
494
+ Ok ( image_plane_from_source. left_multiply ( * target_from_image_plane) )
486
495
}
487
496
488
497
fn from_3d_source_to_2d_target (
489
498
target : & TargetInfo ,
490
499
source : & SourceInfo < ' _ > ,
491
500
target_pinhole_tree_root : & PinholeTreeRoot ,
501
+ target_from_source_root_cache : & mut IntMap < EntityPathHash , glam:: Affine3A > ,
492
502
) -> Result < TransformInfo , TransformFromToError > {
493
503
let PinholeTreeRoot {
494
504
parent_tree_root,
@@ -507,25 +517,28 @@ fn from_3d_source_to_2d_target(
507
517
// Rename for clarification:
508
518
let target_from_image_plane = target. target_from_root ;
509
519
510
- // TODO(#1025):
511
- // There's no meaningful image plane distance for 3D->2D views.
512
- let pinhole_image_plane_distance = 500.0 ;
513
- // Currently our 2D views require us to invert the `pinhole2d_image_plane_from_pinhole3d` matrix.
514
- // This builds a relationship between the 2D plane and the 3D world, when actually the 2D plane
515
- // should have infinite depth!
516
- // The inverse of this matrix *is* working for this, but quickly runs into precision issues.
517
- // See also `ui_2d.rs#setup_target_config`
518
-
519
- // TODO: Locally cache pinhole transform?
520
- let pinhole3d_from_image_plane =
521
- pinhole3d_from_image_plane ( pinhole_projection, pinhole_image_plane_distance) ;
522
- let image_plane_from_pinhole3d = pinhole3d_from_image_plane. inverse ( ) ;
523
- let pinhole3d_from_root = root_from_pinhole3d. inverse ( ) ;
524
- let target_from_root =
525
- target_from_image_plane * image_plane_from_pinhole3d * pinhole3d_from_root;
520
+ let target_from_root = target_from_source_root_cache
521
+ . entry ( source. root )
522
+ . or_insert_with ( || {
523
+ // TODO(#1025):
524
+ // There's no meaningful image plane distance for 3D->2D views.
525
+ let pinhole_image_plane_distance = 500.0 ;
526
+ // Currently our 2D views require us to invert the `pinhole2d_image_plane_from_pinhole3d` matrix.
527
+ // This builds a relationship between the 2D plane and the 3D world, when actually the 2D plane
528
+ // should have infinite depth!
529
+ // The inverse of this matrix *is* working for this, but quickly runs into precision issues.
530
+ // See also `ui_2d.rs#setup_target_config`
531
+
532
+ // TODO: Locally cache pinhole transform?
533
+ let pinhole3d_from_image_plane =
534
+ pinhole3d_from_image_plane ( pinhole_projection, pinhole_image_plane_distance) ;
535
+ let image_plane_from_pinhole3d = pinhole3d_from_image_plane. inverse ( ) ;
536
+ let pinhole3d_from_root = root_from_pinhole3d. inverse ( ) ;
537
+ target_from_image_plane * image_plane_from_pinhole3d * pinhole3d_from_root
538
+ } ) ;
526
539
527
540
// target_from_source = target_from_root * root_from_source
528
- Ok ( source. root_from_source . left_multiply ( target_from_root) )
541
+ Ok ( source. root_from_source . left_multiply ( * target_from_root) )
529
542
}
530
543
531
544
fn left_multiply_smallvec1_of_transforms (
0 commit comments