bevy_codex/hud/
systems.rs

1use bevy::{
2    core_pipeline::fxaa::Fxaa,
3    pbr::ScreenSpaceReflectionsBundle,
4    prelude::*,
5    render::render_resource::{
6        Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
7    },
8    window::PrimaryWindow,
9};
10use bevy_lunex::{
11    prelude::*, Base, PackageLayout, PickingPortal, UiImage2dBundle, UiLayout, UiLink,
12};
13
14use super::components::{Hud, SurfaceHud};
15use crate::components::MainCam;
16
17pub fn build_hud(
18    mut commands: Commands,
19    asset_server: Res<AssetServer>,
20    primary_window: Query<&Window, With<PrimaryWindow>>,
21    query: Query<Entity, Added<Hud>>,
22) {
23    for route_entity in &query {
24        if let Ok(window) = primary_window.get_single() {
25            let (env_pth, env_suffix) = ("images/environment_maps/pisa_", "_rgb9e5_zstd.ktx2");
26            let resolution = &window.resolution;
27            let w_size = (resolution.width(), resolution.height());
28            let size = Extent3d {
29                width: w_size.0 as u32,
30                height: w_size.1 as u32,
31                ..default()
32            };
33
34            let mut image = Image {
35                texture_descriptor: TextureDescriptor {
36                    label: None,
37                    size,
38                    dimension: TextureDimension::D2,
39                    format: TextureFormat::Bgra8UnormSrgb,
40                    mip_level_count: 1,
41                    sample_count: 1,
42                    usage: TextureUsages::TEXTURE_BINDING
43                        | TextureUsages::COPY_DST
44                        | TextureUsages::RENDER_ATTACHMENT,
45                    view_formats: &[],
46                },
47                ..default()
48            };
49            image.resize(size);
50
51            // Spawn the route
52            commands
53                .entity(route_entity)
54                .insert(SpatialBundle::default())
55                .with_children(|route| {
56                    let render_image = asset_server.add(image);
57                    route.spawn((
58                        MainCam,
59                        Camera3dBundle {
60                            camera: Camera {
61                                order: -1,
62                                target: render_image.clone().into(),
63                                clear_color: ClearColorConfig::Custom(Color::srgba(
64                                    0.0, 0.0, 0.0, 0.0,
65                                )),
66                                ..default()
67                            },
68                            projection: Projection::Perspective(PerspectiveProjection {
69                                fov: 60.0_f32.to_radians(),
70                                ..default()
71                            }),
72                            ..default()
73                        },
74                        VisibilityBundle::default(),
75                        ScreenSpaceReflectionsBundle::default(),
76                        Fxaa::default(),
77                        EnvironmentMapLight {
78                            diffuse_map: asset_server
79                                .load(env_pth.to_string() + "diffuse" + env_suffix),
80                            specular_map: asset_server
81                                .load(env_pth.to_string() + "specular" + env_suffix),
82                            intensity: 400.0,
83                        },
84                    ));
85
86                    // Spawn the background
87                    route
88                        .spawn((
89                            UiTreeBundle::<MainUi>::from(UiTree::new2d("HUD")),
90                            UiLayout::window().size(Rl(w_size)).pack::<Base>(),
91                            MovableByCamera,
92                        ))
93                        .with_children(|ui| {
94                            // Spawn 3D camera view
95                            ui.spawn((
96                                UiLink::<MainUi>::path("Camera"),
97                                UiLayout::window().size(Rl(100.0)).pack::<Base>(), // Make this resizable
98                                UiImage2dBundle::from(render_image),
99                                PickingPortal,
100                            ));
101                            ui.spawn((
102                                UiLink::<MainUi>::path("Camera/Hud"),
103                                UiLayout::window_full().pack::<Base>(),
104                                Pickable::IGNORE,
105                                SurfaceHud
106                            ));
107                        });
108                });
109        }
110    }
111}