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
use bevy::{
    core_pipeline::fxaa::Fxaa,
    pbr::ScreenSpaceReflectionsBundle,
    prelude::*,
    render::render_resource::{
        Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
    },
    window::PrimaryWindow,
};
use bevy_lunex::{
    prelude::*, Base, PackageLayout, PickingPortal, UiImage2dBundle, UiLayout, UiLink,
};

use super::components::{Hud, SurfaceHud};
use crate::components::MainCam;

pub fn build_hud(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
    primary_window: Query<&Window, With<PrimaryWindow>>,
    query: Query<Entity, Added<Hud>>,
) {
    for route_entity in &query {
        if let Ok(window) = primary_window.get_single() {
            let (env_pth, env_suffix) = ("images/environment_maps/pisa_", "_rgb9e5_zstd.ktx2");
            let resolution = &window.resolution;
            let w_size = (resolution.width(), resolution.height());
            let size = Extent3d {
                width: w_size.0 as u32,
                height: w_size.1 as u32,
                ..default()
            };

            let mut image = Image {
                texture_descriptor: TextureDescriptor {
                    label: None,
                    size,
                    dimension: TextureDimension::D2,
                    format: TextureFormat::Bgra8UnormSrgb,
                    mip_level_count: 1,
                    sample_count: 1,
                    usage: TextureUsages::TEXTURE_BINDING
                        | TextureUsages::COPY_DST
                        | TextureUsages::RENDER_ATTACHMENT,
                    view_formats: &[],
                },
                ..default()
            };
            image.resize(size);

            // Spawn the route
            commands
                .entity(route_entity)
                .insert(SpatialBundle::default())
                .with_children(|route| {
                    let render_image = asset_server.add(image);
                    route.spawn((
                        MainCam,
                        Camera3dBundle {
                            camera: Camera {
                                order: -1,
                                target: render_image.clone().into(),
                                clear_color: ClearColorConfig::Custom(Color::srgba(
                                    0.0, 0.0, 0.0, 0.0,
                                )),
                                ..default()
                            },
                            projection: Projection::Perspective(PerspectiveProjection {
                                fov: 60.0_f32.to_radians(),
                                ..default()
                            }),
                            ..default()
                        },
                        VisibilityBundle::default(),
                        ScreenSpaceReflectionsBundle::default(),
                        Fxaa::default(),
                        EnvironmentMapLight {
                            diffuse_map: asset_server
                                .load(env_pth.to_string() + "diffuse" + env_suffix),
                            specular_map: asset_server
                                .load(env_pth.to_string() + "specular" + env_suffix),
                            intensity: 400.0,
                        },
                    ));

                    // Spawn the background
                    route
                        .spawn((
                            UiTreeBundle::<MainUi>::from(UiTree::new2d("HUD")),
                            UiLayout::window().size(Rl(w_size)).pack::<Base>(),
                            MovableByCamera,
                        ))
                        .with_children(|ui| {
                            // Spawn 3D camera view
                            ui.spawn((
                                UiLink::<MainUi>::path("Camera"),
                                UiLayout::window().size(Rl(100.0)).pack::<Base>(), // Make this resizable
                                UiImage2dBundle::from(render_image),
                                PickingPortal,
                            ));
                            ui.spawn((
                                UiLink::<MainUi>::path("Camera/Hud"),
                                UiLayout::window_full().pack::<Base>(),
                                Pickable::IGNORE,
                                SurfaceHud
                            ));
                        });
                });
        }
    }
}