1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//! Rerun Spatial Views
//!
//! Views that show entities in a 2D or 3D spatial relationship.

// TODO(#6330): remove unwrap()
#![allow(clippy::unwrap_used)]

mod contexts;
mod eye;
mod heuristics;
mod max_image_dimension_subscriber;
mod mesh_cache;
mod mesh_loader;
mod pickable_textured_rect;
mod picking;
mod picking_ui;
mod picking_ui_pixel;
mod pinhole;
mod proc_mesh;
mod scene_bounding_boxes;
mod space_camera_3d;
mod spatial_topology;
mod ui;
mod ui_2d;
mod ui_3d;
mod view_2d;
mod view_2d_properties;
mod view_3d;
mod view_3d_properties;
mod visualizers;

mod transform_cache;

pub use view_2d::SpatialView2D;
pub use view_3d::SpatialView3D;

pub(crate) use pickable_textured_rect::{PickableRectSourceData, PickableTexturedRect};
pub(crate) use pinhole::Pinhole;

// ---

use re_viewer_context::{ImageDecodeCache, ViewerContext};

use re_log_types::debug_assert_archetype_has_components;
use re_renderer::RenderContext;
use re_types::{
    blueprint::components::BackgroundKind,
    components::{Color, ImageFormat, MediaType, Resolution},
};
use re_viewport_blueprint::{ViewProperty, ViewPropertyQueryError};

mod view_kind {
    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
    pub enum SpatialViewKind {
        TwoD,
        ThreeD,
    }
}

fn resolution_of_image_at(
    ctx: &ViewerContext<'_>,
    query: &re_chunk_store::LatestAtQuery,
    entity_path: &re_log_types::EntityPath,
) -> Option<Resolution> {
    // First check assumptions:
    debug_assert_archetype_has_components!(re_types::archetypes::Image, format: re_types::components::ImageFormat);
    debug_assert_archetype_has_components!(re_types::archetypes::EncodedImage, blob: re_types::components::Blob);

    let db = ctx.recording();

    if let Some((_, image_format)) = db.latest_at_component::<ImageFormat>(entity_path, query) {
        // Normal `Image` archetype
        return Some(Resolution::from([
            image_format.width as f32,
            image_format.height as f32,
        ]));
    } else if let Some(((_time, row_id), blob)) =
        db.latest_at_component::<re_types::components::Blob>(entity_path, query)
    {
        // `archetypes.EncodedImage`

        let media_type = db
            .latest_at_component::<MediaType>(entity_path, query)
            .map(|(_, c)| c);

        let image = ctx
            .cache
            .entry(|c: &mut ImageDecodeCache| c.entry(row_id, &blob, media_type.as_ref()));

        if let Ok(image) = image {
            return Some(Resolution::from([
                image.format.width as f32,
                image.format.height as f32,
            ]));
        }
    }

    None
}

pub(crate) fn configure_background(
    ctx: &ViewerContext<'_>,
    background: &ViewProperty,
    render_ctx: &RenderContext,
    view_system: &dyn re_viewer_context::ComponentFallbackProvider,
    state: &dyn re_viewer_context::ViewState,
) -> Result<(Option<re_renderer::QueueableDrawData>, re_renderer::Rgba), ViewPropertyQueryError> {
    use re_renderer::renderer;

    let kind: BackgroundKind = background.component_or_fallback(ctx, view_system, state)?;

    match kind {
        BackgroundKind::GradientDark => Ok((
            Some(
                renderer::GenericSkyboxDrawData::new(
                    render_ctx,
                    renderer::GenericSkyboxType::GradientDark,
                )
                .into(),
            ),
            re_renderer::Rgba::TRANSPARENT, // All zero is slightly faster to clear usually.
        )),

        BackgroundKind::GradientBright => Ok((
            Some(
                renderer::GenericSkyboxDrawData::new(
                    render_ctx,
                    renderer::GenericSkyboxType::GradientBright,
                )
                .into(),
            ),
            re_renderer::Rgba::TRANSPARENT, // All zero is slightly faster to clear usually.
        )),

        BackgroundKind::SolidColor => {
            let color: Color = background.component_or_fallback(ctx, view_system, state)?;
            Ok((None, color.into()))
        }
    }
}