use crate::{actor, camera, starchart, nature}; use bevy::prelude::*; //use bevy::core_pipeline::Skybox; //use bevy::asset::LoadState; //use bevy::render::render_resource::{TextureViewDescriptor, TextureViewDimension}; use bevy::pbr::CascadeShadowConfigBuilder; use bevy::core_pipeline::bloom::{BloomCompositeMode, BloomSettings}; use std::f32::consts::PI; const ASTEROID_SIZE: f32 = 100.0; const MOON_SIZE: f32 = 50.0; const MARS_SIZE: f32 = 10.0; const ASTRONAUT_SIZE: f32 = 5.0; //const SKYBOX_BRIGHTNESS: f32 = 300.0; //const SKYBOX_BRIGHTNESS_AR: f32 = 100.0; //const ASSET_CUBEMAP: &str = "textures/cubemap-fs8.png"; //const ASSET_CUBEMAP_AR: &str = "textures/out.png"; const ASSET_ASTRONAUT: &str = "tmp/alien.glb#Scene0"; pub struct WorldPlugin; impl Plugin for WorldPlugin { fn build(&self, app: &mut App) { app.add_systems(Startup, setup); //app.add_systems(Update, asset_loaded.after(load_cubemap_asset)); //app.add_systems(Update, swap_world_on_ar_toggle); app.insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0))); } } #[derive(Component)] pub struct Star; //#[derive(Resource)] //pub struct WorldState { // is_loaded: bool, // entities_viewn_through_ar: bool, // cubemap_handle: Handle, // cubemap_ar_handle: Handle, //} //impl WorldState { // pub fn get_cubemap_handle(&self) -> Handle { // if self.entities_viewn_through_ar { // self.cubemap_ar_handle.clone() // } else { // self.cubemap_handle.clone() // } // } //} pub fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, mut ambient_light: ResMut, // settings: Res, asset_server: Res, ) { // let cubemap_handle = asset_server.load(ASSET_CUBEMAP); // commands.insert_resource(WorldState { // is_loaded: false, // entities_viewn_through_ar: settings.hud_active, // cubemap_handle: asset_server.load(ASSET_CUBEMAP), // cubemap_ar_handle: asset_server.load(ASSET_CUBEMAP_AR), // }); // Add player commands.spawn(( actor::Player, actor::Actor::default(), actor::LifeForm::default(), actor::Suit { oxygen: actor::OXY_M, ..default() } )); commands.spawn(( Camera3dBundle { camera: Camera { hdr: true, // HDR is required for bloom ..default() }, transform: Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y), ..default() }, camera::CameraController::default(), // Skybox { // image: cubemap_handle, // brightness: SKYBOX_BRIGHTNESS, // }, BloomSettings { composite_mode: BloomCompositeMode::EnergyConserving, ..default() }, )); // Add some hand-placed asteroids let sphere_handle = meshes.add(Sphere::new(1.0)); let gray_handle = materials.add(StandardMaterial { base_color: Color::GRAY, perceptual_roughness: 1.0, ..default() }); let brown_handle = materials.add(StandardMaterial { base_color: Color::Rgba { alpha: 1.0, red: 0.8, green: 0.5, blue: 0.1 }, perceptual_roughness: 1.0, ..default() }); commands.spawn(( actor::Actor::default(), PbrBundle { mesh: sphere_handle.clone(), material: gray_handle.clone(), transform: Transform::from_xyz( 0.0, 0.0, -500.0, ).with_scale(Vec3::splat(MOON_SIZE)), ..default() }, )); commands.spawn(( actor::Actor::default(), PbrBundle { mesh: sphere_handle.clone(), material: brown_handle.clone(), transform: Transform::from_xyz( 300.0, 40.0, 250.0, ).with_scale(Vec3::splat(MARS_SIZE)), ..default() }, )); // Generate a bunch of asteriods let asteroid_color_handle = materials.add(StandardMaterial { base_color: Color::rgb(0.25, 0.2, 0.2), perceptual_roughness: 1.0, ..default() }); let maxdist = 10; for i in -maxdist..maxdist { for j in -maxdist..maxdist { for k in -maxdist..maxdist { let offset = 500.0; let dist = 3e4; let wobble = dist/2.0; let (i, j, k) = (i as f32, j as f32, k as f32); commands.spawn(( actor::Actor::default(), PbrBundle { mesh: sphere_handle.clone(), material: asteroid_color_handle.clone(), transform: Transform::from_xyz( offset + dist * i + wobble * (j+k/PI).sin() * (k+j/PI).cos(), offset + dist * j + wobble * (k+i/PI).sin() * (i+k/PI).cos(), offset + dist * k + wobble * (i+j/PI).sin() * (j+i/PI).cos(), ).with_scale(Vec3::splat(ASTEROID_SIZE)), ..default() } )); } } } // Generate starmap for star in starchart::STARS { let brightness = star[3] * 2000.0; let (r, g, b) = nature::star_color_index_to_rgb(star[4]); let star_color_handle = materials.add(StandardMaterial { base_color: Color::rgb(r, g, b), emissive: Color::rgb_linear(r*brightness, g*brightness, b*brightness), ..default() }); let dist = 1e6; commands.spawn(( Star, PbrBundle { mesh: sphere_handle.clone(), material: star_color_handle.clone(), transform: Transform::from_xyz( dist * star[0], dist * star[1], dist * star[2], ) .with_scale(Vec3::splat((1000.0*star[3]).clamp(500.0, 2000.0))), ..default() } )); } // Add alien commands.spawn(SceneBundle { transform: Transform { translation: Vec3::new( 0.0, 0.0, 100.0, ), rotation: Quat::from_rotation_y(-PI / 3.), scale: Vec3::splat(ASTRONAUT_SIZE), }, scene: asset_server.load(ASSET_ASTRONAUT), ..default() }); // Space is DARK ambient_light.brightness = 0.0; // Add Light commands.spawn(DirectionalLightBundle { directional_light: DirectionalLight { illuminance: 1000.0, shadows_enabled: false, ..default() }, transform: Transform::from_rotation(Quat::from_euler( EulerRot::ZYX, 0.0, PI / 1.0, -PI / 7.0, )), cascade_shadow_config: CascadeShadowConfigBuilder { first_cascade_far_bound: 7.0, maximum_distance: 25.0, ..default() } .into(), ..default() }); } //pub fn swap_world_on_ar_toggle( // asset_server: Res, // mut images: ResMut>, // mut worldstate: ResMut, // mut skyboxes: Query<&mut Skybox>, // settings: Res, //) { // if settings.hud_active != worldstate.entities_viewn_through_ar { // worldstate.is_loaded = false; // worldstate.entities_viewn_through_ar = settings.hud_active; // } // if !worldstate.is_loaded && asset_server.load_state(&worldstate.get_cubemap_handle()) == LoadState::Loaded { // let cubemap_handle = &worldstate.get_cubemap_handle(); // let image = images.get_mut(cubemap_handle).unwrap(); // if image.texture_descriptor.array_layer_count() == 1 { // image.reinterpret_stacked_2d_as_array(image.height() / image.width()); // image.texture_view_descriptor = Some(TextureViewDescriptor { // dimension: Some(TextureViewDimension::Cube), // ..default() // }); // } // // for mut skybox in &mut skyboxes { // skybox.image = cubemap_handle.clone(); // skybox.brightness = if settings.hud_active { // SKYBOX_BRIGHTNESS_AR // } else { // SKYBOX_BRIGHTNESS // } // } // // worldstate.is_loaded = true; // } //}