@@ -29,6 +29,7 @@ use crate::{
2929
3030use super :: {
3131 eye:: { Eye , OrbitEye } ,
32+ scene:: SceneSpatialPrimitives ,
3233 ViewSpatialState ,
3334} ;
3435
@@ -454,13 +455,29 @@ pub fn view_3d(
454455 . resolve ( & ctx. log_db . entity_db )
455456 . map ( |instance_path| Item :: InstancePath ( Some ( space_view_id) , instance_path) )
456457 } ) ) ;
457- state. state_3d . hovered_point = picking_result
458+
459+ let hovered_point = picking_result
458460 . opaque_hit
459461 . as_ref ( )
460462 . or_else ( || picking_result. transparent_hits . last ( ) )
461463 . map ( |hit| picking_result. space_position ( hit) ) ;
462464
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+ } ) ;
464481 } else {
465482 state. previous_picking_result = None ;
466483 }
@@ -516,7 +533,12 @@ pub fn view_3d(
516533 view_builder. schedule_screenshot ( ctx. render_ctx , space_view_id. gpu_readback_id ( ) , mode) ;
517534 }
518535
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+ ) ;
520542
521543 if state. state_3d . show_axes {
522544 let axis_length = 1.0 ; // The axes are also a measuring stick
@@ -591,13 +613,16 @@ pub fn view_3d(
591613fn show_projections_from_2d_space (
592614 ctx : & mut ViewerContext < ' _ > ,
593615 scene : & mut SceneSpatial ,
616+ tracked_space_camera : & Option < InstancePath > ,
594617 scene_bbox_accum : & BoundingBox ,
595618) {
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+ {
601626 if let Some ( ray) = cam. unproject_as_ray ( glam:: vec2 ( pos. x , pos. y ) ) {
602627 // Render a thick line to the actual z value if any and a weaker one as an extension
603628 // If we don't have a z value, we only render the thick one.
@@ -607,54 +632,72 @@ fn show_projections_from_2d_space(
607632 cam. picture_plane_distance
608633 } ;
609634
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+ ) ;
634641 }
635642 }
636643 }
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+ _ => { }
637666 }
638667}
639668
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 > ,
645674) {
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 ) ) ;
652700 }
653- ctx. selection_state_mut ( )
654- . set_hovered_space ( HoveredSpace :: ThreeD {
655- space_3d : space. clone ( ) ,
656- target_spaces,
657- } ) ;
658701}
659702
660703fn default_eye ( scene_bbox : & macaw:: BoundingBox , space_specs : & SpaceSpecs ) -> OrbitEye {
0 commit comments