@@ -29,6 +29,7 @@ use crate::{
29
29
30
30
use super :: {
31
31
eye:: { Eye , OrbitEye } ,
32
+ scene:: SceneSpatialPrimitives ,
32
33
ViewSpatialState ,
33
34
} ;
34
35
@@ -454,13 +455,29 @@ pub fn view_3d(
454
455
. resolve ( & ctx. log_db . entity_db )
455
456
. map ( |instance_path| Item :: InstancePath ( Some ( space_view_id) , instance_path) )
456
457
} ) ) ;
457
- state. state_3d . hovered_point = picking_result
458
+
459
+ let hovered_point = picking_result
458
460
. opaque_hit
459
461
. as_ref ( )
460
462
. or_else ( || picking_result. transparent_hits . last ( ) )
461
463
. map ( |hit| picking_result. space_position ( hit) ) ;
462
464
463
- project_onto_other_spaces ( ctx, & scene. space_cameras , & mut state. state_3d , space) ;
465
+ ctx. selection_state_mut ( )
466
+ . set_hovered_space ( HoveredSpace :: ThreeD {
467
+ space_3d : space. clone ( ) ,
468
+ pos : hovered_point,
469
+ tracked_space_camera : state. state_3d . tracked_camera . clone ( ) ,
470
+ point_in_space_cameras : scene
471
+ . space_cameras
472
+ . iter ( )
473
+ . map ( |cam| {
474
+ (
475
+ cam. instance_path_hash ,
476
+ hovered_point. and_then ( |pos| cam. project_onto_2d ( pos) ) ,
477
+ )
478
+ } )
479
+ . collect ( ) ,
480
+ } ) ;
464
481
} else {
465
482
state. previous_picking_result = None ;
466
483
}
@@ -516,7 +533,12 @@ pub fn view_3d(
516
533
view_builder. schedule_screenshot ( ctx. render_ctx , space_view_id. gpu_readback_id ( ) , mode) ;
517
534
}
518
535
519
- show_projections_from_2d_space ( ctx, & mut scene, & state. scene_bbox_accum ) ;
536
+ show_projections_from_2d_space (
537
+ ctx,
538
+ & mut scene,
539
+ & state. state_3d . tracked_camera ,
540
+ & state. scene_bbox_accum ,
541
+ ) ;
520
542
521
543
if state. state_3d . show_axes {
522
544
let axis_length = 1.0 ; // The axes are also a measuring stick
@@ -591,13 +613,16 @@ pub fn view_3d(
591
613
fn show_projections_from_2d_space (
592
614
ctx : & mut ViewerContext < ' _ > ,
593
615
scene : & mut SceneSpatial ,
616
+ tracked_space_camera : & Option < InstancePath > ,
594
617
scene_bbox_accum : & BoundingBox ,
595
618
) {
596
- if let HoveredSpace :: TwoD { space_2d, pos } = ctx. selection_state ( ) . hovered_space ( ) {
597
- let mut line_batch = scene. primitives . line_strips . batch ( "picking ray" ) ;
598
-
599
- for cam in & scene. space_cameras {
600
- if & cam. entity_path == space_2d {
619
+ match ctx. selection_state ( ) . hovered_space ( ) {
620
+ HoveredSpace :: TwoD { space_2d, pos } => {
621
+ if let Some ( cam) = scene
622
+ . space_cameras
623
+ . iter ( )
624
+ . find ( |cam| cam. instance_path_hash . entity_path_hash == space_2d. hash ( ) )
625
+ {
601
626
if let Some ( ray) = cam. unproject_as_ray ( glam:: vec2 ( pos. x , pos. y ) ) {
602
627
// Render a thick line to the actual z value if any and a weaker one as an extension
603
628
// If we don't have a z value, we only render the thick one.
@@ -607,54 +632,72 @@ fn show_projections_from_2d_space(
607
632
cam. picture_plane_distance
608
633
} ;
609
634
610
- let origin = ray. point_along ( 0.0 ) ;
611
- // No harm in making this ray _very_ long. (Infinite messes with things though!)
612
- let fallback_ray_end = ray. point_along ( scene_bbox_accum. size ( ) . length ( ) * 10.0 ) ;
613
-
614
- if let Some ( line_length) = thick_ray_length {
615
- let main_ray_end = ray. point_along ( line_length) ;
616
- line_batch
617
- . add_segment ( origin, main_ray_end)
618
- . color ( egui:: Color32 :: WHITE )
619
- . flags ( re_renderer:: renderer:: LineStripFlags :: NO_COLOR_GRADIENT )
620
- . radius ( Size :: new_points ( 1.0 ) ) ;
621
- line_batch
622
- . add_segment ( main_ray_end, fallback_ray_end)
623
- . color ( egui:: Color32 :: DARK_GRAY )
624
- // TODO(andreas): Make this dashed.
625
- . flags ( re_renderer:: renderer:: LineStripFlags :: NO_COLOR_GRADIENT )
626
- . radius ( Size :: new_points ( 0.5 ) ) ;
627
- } else {
628
- line_batch
629
- . add_segment ( origin, fallback_ray_end)
630
- . color ( egui:: Color32 :: WHITE )
631
- . flags ( re_renderer:: renderer:: LineStripFlags :: NO_COLOR_GRADIENT )
632
- . radius ( Size :: new_points ( 1.0 ) ) ;
633
- }
635
+ add_picking_ray (
636
+ & mut scene. primitives ,
637
+ ray,
638
+ scene_bbox_accum,
639
+ thick_ray_length,
640
+ ) ;
634
641
}
635
642
}
636
643
}
644
+ HoveredSpace :: ThreeD {
645
+ pos : Some ( pos) ,
646
+ tracked_space_camera : Some ( camera_path) ,
647
+ ..
648
+ } => {
649
+ if tracked_space_camera
650
+ . as_ref ( )
651
+ . map_or ( true , |tracked| tracked != camera_path)
652
+ {
653
+ if let Some ( cam) = scene
654
+ . space_cameras
655
+ . iter ( )
656
+ . find ( |cam| cam. instance_path_hash == camera_path. hash ( ) )
657
+ {
658
+ let cam_to_pos = * pos - cam. position ( ) ;
659
+ let distance = cam_to_pos. length ( ) ;
660
+ let ray = macaw:: Ray3 :: from_origin_dir ( cam. position ( ) , cam_to_pos / distance) ;
661
+ add_picking_ray ( & mut scene. primitives , ray, scene_bbox_accum, Some ( distance) ) ;
662
+ }
663
+ }
664
+ }
665
+ _ => { }
637
666
}
638
667
}
639
668
640
- fn project_onto_other_spaces (
641
- ctx : & mut ViewerContext < ' _ > ,
642
- space_cameras : & [ SpaceCamera3D ] ,
643
- state : & mut View3DState ,
644
- space : & EntityPath ,
669
+ fn add_picking_ray (
670
+ primitives : & mut SceneSpatialPrimitives ,
671
+ ray : macaw :: Ray3 ,
672
+ scene_bbox_accum : & BoundingBox ,
673
+ thick_ray_length : Option < f32 > ,
645
674
) {
646
- let mut target_spaces = vec ! [ ] ;
647
- for cam in space_cameras {
648
- let point_in_2d = state
649
- . hovered_point
650
- . and_then ( |hovered_point| cam. project_onto_2d ( hovered_point) ) ;
651
- target_spaces. push ( ( cam. entity_path . clone ( ) , point_in_2d) ) ;
675
+ let mut line_batch = primitives. line_strips . batch ( "picking ray" ) ;
676
+
677
+ let origin = ray. point_along ( 0.0 ) ;
678
+ // No harm in making this ray _very_ long. (Infinite messes with things though!)
679
+ let fallback_ray_end = ray. point_along ( scene_bbox_accum. size ( ) . length ( ) * 10.0 ) ;
680
+
681
+ if let Some ( line_length) = thick_ray_length {
682
+ let main_ray_end = ray. point_along ( line_length) ;
683
+ line_batch
684
+ . add_segment ( origin, main_ray_end)
685
+ . color ( egui:: Color32 :: WHITE )
686
+ . flags ( re_renderer:: renderer:: LineStripFlags :: NO_COLOR_GRADIENT )
687
+ . radius ( Size :: new_points ( 1.0 ) ) ;
688
+ line_batch
689
+ . add_segment ( main_ray_end, fallback_ray_end)
690
+ . color ( egui:: Color32 :: DARK_GRAY )
691
+ // TODO(andreas): Make this dashed.
692
+ . flags ( re_renderer:: renderer:: LineStripFlags :: NO_COLOR_GRADIENT )
693
+ . radius ( Size :: new_points ( 0.5 ) ) ;
694
+ } else {
695
+ line_batch
696
+ . add_segment ( origin, fallback_ray_end)
697
+ . color ( egui:: Color32 :: WHITE )
698
+ . flags ( re_renderer:: renderer:: LineStripFlags :: NO_COLOR_GRADIENT )
699
+ . radius ( Size :: new_points ( 1.0 ) ) ;
652
700
}
653
- ctx. selection_state_mut ( )
654
- . set_hovered_space ( HoveredSpace :: ThreeD {
655
- space_3d : space. clone ( ) ,
656
- target_spaces,
657
- } ) ;
658
701
}
659
702
660
703
fn default_eye ( scene_bbox : & macaw:: BoundingBox , space_specs : & SpaceSpecs ) -> OrbitEye {
0 commit comments