From cd08e36a4905a515e9cb8ae36152c920793ed998 Mon Sep 17 00:00:00 2001 From: yuni Date: Fri, 29 Nov 2024 17:38:27 +0100 Subject: [PATCH] add a black box around the player that changes opacity based on altitude --- src/common.rs | 10 +++++++++ src/visual.rs | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/world.rs | 8 +------ 3 files changed, 72 insertions(+), 7 deletions(-) diff --git a/src/common.rs b/src/common.rs index dcf3d02..ade281a 100644 --- a/src/common.rs +++ b/src/common.rs @@ -12,6 +12,7 @@ use crate::prelude::*; use bevy::prelude::*; +use bevy::render::mesh::Indices; pub use bevy::math::{DQuat, DVec3}; pub use std::f32::consts::PI as PI32; @@ -125,3 +126,12 @@ pub fn look_at_quat(from: DVec3, to: DVec3, up: DVec3) -> DQuat { DQuat::from_mat3(&mat3) } + +pub fn mesh_invert_triangles(mesh: &mut Mesh) { + if let Some(Indices::U32(indices)) = mesh.indices_mut() { + // Reverse the order of each triangle to avoid backface culling + for slice in indices.chunks_mut(3) { + slice.reverse(); + } + } +} diff --git a/src/visual.rs b/src/visual.rs index a293a07..b6ac47a 100644 --- a/src/visual.rs +++ b/src/visual.rs @@ -11,6 +11,7 @@ // This module manages visual effects. use crate::prelude::*; +use bevy::pbr::{NotShadowCaster, NotShadowReceiver}; use bevy::prelude::*; use bevy_xpbd_3d::prelude::*; use std::time::Duration; @@ -32,6 +33,7 @@ impl Plugin for VisualPlugin { app.add_systems(Update, update_fadeout.run_if(game_running)); app.add_systems(Update, update_fade_material.run_if(game_running)); app.add_systems(Update, update_grow.run_if(game_running)); + app.add_systems(Update, update_atmosphere.run_if(game_running)); app.add_systems(Update, play_animations.run_if(game_running)); // Blackout disabled for now //app.add_systems(Update, update_blackout); @@ -52,6 +54,8 @@ pub enum Effects { #[derive(Component)] pub struct IsEffect; #[derive(Component)] +pub struct InnerAtmosphereBox; +#[derive(Component)] pub struct FadeInSprite; #[derive(Component)] pub struct FadeOutSprite; @@ -93,6 +97,8 @@ pub fn setup( mut commands: Commands, mut ew_effect: EventWriter, mut graphs: ResMut>, + mut materials: ResMut>, + mut meshes: ResMut>, ) { if !settings.dev_mode { ew_effect.send(SpawnEffectEvent { @@ -111,6 +117,27 @@ pub fn setup( let graph = graphs.add(graph); commands.insert_resource(SuitAnimation { index, graph }); + let box_material_handle = materials.add(StandardMaterial { + base_color: Color::srgba(0.0, 0.0, 0.0, 1.0), + alpha_mode: AlphaMode::Blend, + unlit: true, + ..default() + }); + let mut mesh = Mesh::from(Cuboid::new(100.0, 100.0, 100.0).mesh()); + let mut mesh_inside = Mesh::from(Cuboid::new(100.0, 100.0, 100.0).mesh()); + mesh_invert_triangles(&mut mesh_inside); + mesh.merge(&mesh_inside); + let box_handle = meshes.add(mesh); + commands.spawn(( + InnerAtmosphereBox, + NotShadowReceiver, + PbrBundle { + mesh: box_handle, + material: box_material_handle, + ..default() + }, + )); + // Blackout disabled for now // commands.spawn(( // BlackOutOverlay, @@ -331,3 +358,37 @@ fn play_animations( // bgcolor.0.set_alpha(alpha as f32); // } //} + +fn update_atmosphere( + settings: Res, + mut q_atmo: Query< + (&mut Transform, &Handle, &mut Visibility), + With, + >, + q_player: Query<&Transform, (With, Without)>, + mut materials: ResMut>, +) { + let player_trans = if let Ok(trans) = q_player.get_single() { + trans + } else { + return; + }; + for (mut trans, material_handle, mut vis) in &mut q_atmo { + if let Some(x) = settings.atmo_altitude { + *vis = Visibility::Inherited; + trans.translation = player_trans.translation; + let opacity = if x < -20000.0 { + 1.0 + } else if x > 300000.0 { + 0.0 + } else { + (-(1.14583e-11) * x * x + (8.33333e-8) * x + 1.00625) as f32 + }; + if let Some(material) = materials.get_mut(material_handle) { + material.base_color = Color::srgba(0.0, 0.0, 0.0, opacity); + } + } else { + *vis = Visibility::Hidden; + } + } +} diff --git a/src/world.rs b/src/world.rs index 642a7e5..b776c58 100644 --- a/src/world.rs +++ b/src/world.rs @@ -13,7 +13,6 @@ use crate::prelude::*; use bevy::math::I64Vec3; use bevy::prelude::*; -use bevy::render::mesh::Indices; use bevy::scene::{InstanceId, SceneInstance}; use bevy_xpbd_3d::prelude::*; use fastrand; @@ -173,12 +172,7 @@ pub fn setup( if SKYBOX { let mut mesh = Mesh::from(Sphere::new(1e10).mesh().uv(5, 5)); //let mut mesh = Mesh::from(Cuboid::from_size(Vec3::splat(2e10))); - if let Some(Indices::U32(indices)) = mesh.indices_mut() { - // Reverse the order of each triangle to avoid backface culling - for slice in indices.chunks_mut(3) { - slice.reverse(); - } - } + mesh_invert_triangles(&mut mesh); commands.spawn(MaterialMeshBundle { mesh: meshes.add(mesh), material: materials_skybox.add(load::SkyBox {}),