add a black box around the player that changes opacity based on altitude

This commit is contained in:
yuni 2024-11-29 17:38:27 +01:00
parent 1fb469b195
commit cd08e36a49
3 changed files with 72 additions and 7 deletions

View file

@ -12,6 +12,7 @@
use crate::prelude::*; use crate::prelude::*;
use bevy::prelude::*; use bevy::prelude::*;
use bevy::render::mesh::Indices;
pub use bevy::math::{DQuat, DVec3}; pub use bevy::math::{DQuat, DVec3};
pub use std::f32::consts::PI as PI32; 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) 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();
}
}
}

View file

@ -11,6 +11,7 @@
// This module manages visual effects. // This module manages visual effects.
use crate::prelude::*; use crate::prelude::*;
use bevy::pbr::{NotShadowCaster, NotShadowReceiver};
use bevy::prelude::*; use bevy::prelude::*;
use bevy_xpbd_3d::prelude::*; use bevy_xpbd_3d::prelude::*;
use std::time::Duration; 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_fadeout.run_if(game_running));
app.add_systems(Update, update_fade_material.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_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)); app.add_systems(Update, play_animations.run_if(game_running));
// Blackout disabled for now // Blackout disabled for now
//app.add_systems(Update, update_blackout); //app.add_systems(Update, update_blackout);
@ -52,6 +54,8 @@ pub enum Effects {
#[derive(Component)] #[derive(Component)]
pub struct IsEffect; pub struct IsEffect;
#[derive(Component)] #[derive(Component)]
pub struct InnerAtmosphereBox;
#[derive(Component)]
pub struct FadeInSprite; pub struct FadeInSprite;
#[derive(Component)] #[derive(Component)]
pub struct FadeOutSprite; pub struct FadeOutSprite;
@ -93,6 +97,8 @@ pub fn setup(
mut commands: Commands, mut commands: Commands,
mut ew_effect: EventWriter<SpawnEffectEvent>, mut ew_effect: EventWriter<SpawnEffectEvent>,
mut graphs: ResMut<Assets<AnimationGraph>>, mut graphs: ResMut<Assets<AnimationGraph>>,
mut materials: ResMut<Assets<StandardMaterial>>,
mut meshes: ResMut<Assets<Mesh>>,
) { ) {
if !settings.dev_mode { if !settings.dev_mode {
ew_effect.send(SpawnEffectEvent { ew_effect.send(SpawnEffectEvent {
@ -111,6 +117,27 @@ pub fn setup(
let graph = graphs.add(graph); let graph = graphs.add(graph);
commands.insert_resource(SuitAnimation { index, 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 // Blackout disabled for now
// commands.spawn(( // commands.spawn((
// BlackOutOverlay, // BlackOutOverlay,
@ -331,3 +358,37 @@ fn play_animations(
// bgcolor.0.set_alpha(alpha as f32); // bgcolor.0.set_alpha(alpha as f32);
// } // }
//} //}
fn update_atmosphere(
settings: Res<Settings>,
mut q_atmo: Query<
(&mut Transform, &Handle<StandardMaterial>, &mut Visibility),
With<InnerAtmosphereBox>,
>,
q_player: Query<&Transform, (With<actor::PlayerCamera>, Without<InnerAtmosphereBox>)>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
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;
}
}
}

View file

@ -13,7 +13,6 @@
use crate::prelude::*; use crate::prelude::*;
use bevy::math::I64Vec3; use bevy::math::I64Vec3;
use bevy::prelude::*; use bevy::prelude::*;
use bevy::render::mesh::Indices;
use bevy::scene::{InstanceId, SceneInstance}; use bevy::scene::{InstanceId, SceneInstance};
use bevy_xpbd_3d::prelude::*; use bevy_xpbd_3d::prelude::*;
use fastrand; use fastrand;
@ -173,12 +172,7 @@ pub fn setup(
if SKYBOX { if SKYBOX {
let mut mesh = Mesh::from(Sphere::new(1e10).mesh().uv(5, 5)); let mut mesh = Mesh::from(Sphere::new(1e10).mesh().uv(5, 5));
//let mut mesh = Mesh::from(Cuboid::from_size(Vec3::splat(2e10))); //let mut mesh = Mesh::from(Cuboid::from_size(Vec3::splat(2e10)));
if let Some(Indices::U32(indices)) = mesh.indices_mut() { mesh_invert_triangles(&mut mesh);
// Reverse the order of each triangle to avoid backface culling
for slice in indices.chunks_mut(3) {
slice.reverse();
}
}
commands.spawn(MaterialMeshBundle { commands.spawn(MaterialMeshBundle {
mesh: meshes.add(mesh), mesh: meshes.add(mesh),
material: materials_skybox.add(load::SkyBox {}), material: materials_skybox.add(load::SkyBox {}),