Move render settings to separate struct

Allow re-opening tile info with I key
This commit is contained in:
Tobias Berger 2022-11-07 10:43:18 +01:00
parent e09e75b6a9
commit 8c101386db
Signed by: toby
GPG key ID: 2D05EFAB764D6A88
4 changed files with 145 additions and 147 deletions

View file

@ -91,47 +91,79 @@ impl Display for SaveError {
iterable_enum!(PlanetView { Biomes, Altitude }); iterable_enum!(PlanetView { Biomes, Altitude });
#[derive(Debug)] #[cfg(feature = "render")]
#[derive(Debug, Default)]
pub struct WorldRenderSettings {
pub map_image_handle_id: Option<HandleId>,
#[cfg(feature = "globe_view")]
pub globe_image_handle_id: Option<HandleId>,
#[cfg(feature = "globe_view")]
pub globe_material_handle_id: Option<HandleId>,
rainfall_visible: bool,
temperature_visible: bool,
view: PlanetView,
}
#[cfg(feature = "render")]
impl WorldRenderSettings {
#[cfg(feature = "render")]
pub fn toggle_rainfall(&mut self) {
#[cfg(feature = "logging")]
if self.rainfall_visible {
debug!("Turning rainfall off");
} else {
debug!("Turning rainfall on");
}
self.rainfall_visible = !self.rainfall_visible;
}
#[cfg(feature = "render")]
pub fn toggle_temperature(&mut self) {
#[cfg(feature = "logging")]
if self.temperature_visible {
debug!("Turning temperature off");
} else {
debug!("Turning temperature on");
}
self.temperature_visible = !self.temperature_visible;
}
#[cfg(feature = "render")]
pub fn cycle_view(&mut self) {
let idx = (PlanetView::iterator()
.position(|view| *view == self.view)
.unwrap()
+ 1)
% PlanetView::ITEM_COUNT;
#[cfg(feature = "logging")]
debug!(
"Cycling view from {:#?} to {:#?}",
self.view,
PlanetView::ITEMS[idx]
);
self.view = PlanetView::ITEMS[idx];
}
}
impl Default for PlanetView {
fn default() -> Self {
PlanetView::Biomes
}
}
#[derive(Debug, Default)]
pub struct WorldManager { pub struct WorldManager {
world: Option<World>, world: Option<World>,
#[cfg(feature = "render")] #[cfg(feature = "render")]
pub map_image_handle_id: Option<HandleId>, pub render_settings: WorldRenderSettings,
#[cfg(all(feature = "render", feature = "globe_view"))]
pub globe_image_handle_id: Option<HandleId>,
#[cfg(all(feature = "render", feature = "globe_view"))]
pub globe_material_handle_id: Option<HandleId>,
#[cfg(feature = "render")]
rainfall_visible: bool,
#[cfg(feature = "render")]
temperature_visible: bool,
#[cfg(feature = "render")]
contours: bool,
#[cfg(feature = "render")]
view: PlanetView,
} }
impl WorldManager { impl WorldManager {
#[must_use] #[must_use]
pub fn new() -> WorldManager { pub fn new() -> WorldManager {
Self { default()
world: None,
#[cfg(feature = "render")]
map_image_handle_id: None,
#[cfg(all(feature = "render", feature = "globe_view"))]
globe_image_handle_id: None,
#[cfg(all(feature = "render", feature = "globe_view"))]
globe_material_handle_id: None,
#[cfg(feature = "render")]
rainfall_visible: false,
#[cfg(feature = "render")]
temperature_visible: false,
#[cfg(feature = "render")]
view: PlanetView::Biomes,
#[cfg(feature = "render")]
contours: false,
}
} }
pub fn save_world<P: AsRef<Path>>(&self, path: P) -> Result<(), SaveError> { pub fn save_world<P: AsRef<Path>>(&self, path: P) -> Result<(), SaveError> {
@ -190,7 +222,8 @@ impl WorldManager {
#[cfg(feature = "render")] #[cfg(feature = "render")]
{ {
let image_handle = &images.get_handle( let image_handle = &images.get_handle(
self.map_image_handle_id self.render_settings
.map_image_handle_id
.expect("Missing image handle, even though world is present"), .expect("Missing image handle, even though world is present"),
); );
images images
@ -208,54 +241,16 @@ impl WorldManager {
} }
} }
#[cfg(feature = "render")] // #[cfg(feature = "render")]
pub fn toggle_rainfall(&mut self) { // pub fn toggle_contours(&mut self) {
#[cfg(feature = "logging")] // #[cfg(feature = "logging")]
if self.rainfall_visible { // if self.contours {
debug!("Turning rainfall off"); // debug!("Turning terrain contours off");
} else { // } else {
debug!("Turning rainfall on"); // debug!("Turning terrain contours on");
} // }
self.rainfall_visible = !self.rainfall_visible; // self.contours = !self.contours;
} // }
#[cfg(feature = "render")]
pub fn toggle_temperature(&mut self) {
#[cfg(feature = "logging")]
if self.temperature_visible {
debug!("Turning temperature off");
} else {
debug!("Turning temperature on");
}
self.temperature_visible = !self.temperature_visible;
}
#[cfg(feature = "render")]
pub fn cycle_view(&mut self) {
let idx = (PlanetView::iterator()
.position(|view| *view == self.view)
.unwrap()
+ 1)
% PlanetView::ITEM_COUNT;
#[cfg(feature = "logging")]
debug!(
"Cycling view from {:#?} to {:#?}",
self.view,
PlanetView::ITEMS[idx]
);
self.view = PlanetView::ITEMS[idx];
}
#[cfg(feature = "render")]
pub fn toggle_contours(&mut self) {
#[cfg(feature = "logging")]
if self.contours {
debug!("Turning terrain contours off");
} else {
debug!("Turning terrain contours on");
}
self.contours = !self.contours;
}
#[must_use] #[must_use]
pub fn get_world(&self) -> Option<&World> { pub fn get_world(&self) -> Option<&World> {
@ -278,15 +273,16 @@ impl WorldManager {
#[cfg(feature = "render")] #[cfg(feature = "render")]
#[must_use] #[must_use]
fn generate_color(&self, cell: &TerrainCell) -> Color { fn generate_color(&self, cell: &TerrainCell) -> Color {
if self.view == PlanetView::Biomes { if self.render_settings.view == PlanetView::Biomes {
return WorldManager::biome_color(cell); return WorldManager::biome_color(cell);
} }
let altitude_color = if self.contours { let altitude_color = WorldManager::altitude_contour_color(cell.altitude);
WorldManager::altitude_contour_color(cell.altitude) // let altitude_color = if self.contours {
} else { // WorldManager::altitude_contour_color(cell.altitude)
WorldManager::altitude_color(cell.altitude) // } else {
}; // WorldManager::altitude_color(cell.altitude)
// };
let mut layer_count = 1.0; let mut layer_count = 1.0;
@ -294,7 +290,7 @@ impl WorldManager {
let mut green = altitude_color.g(); let mut green = altitude_color.g();
let mut blue = altitude_color.b(); let mut blue = altitude_color.b();
if self.rainfall_visible { if self.render_settings.rainfall_visible {
layer_count += 1.0; layer_count += 1.0;
let rainfall_color = self.rainfall_contour_color(cell.rainfall); let rainfall_color = self.rainfall_contour_color(cell.rainfall);
// if self.contours { // if self.contours {
@ -308,7 +304,7 @@ impl WorldManager {
blue += rainfall_color.b(); blue += rainfall_color.b();
} }
if self.temperature_visible { if self.render_settings.temperature_visible {
layer_count += 1.0; layer_count += 1.0;
let temperature_color = self.temperature_contour_color(cell.temperature); let temperature_color = self.temperature_contour_color(cell.temperature);
// if self.contours { // if self.contours {
@ -325,17 +321,17 @@ impl WorldManager {
Color::rgb(red / layer_count, green / layer_count, blue / layer_count) Color::rgb(red / layer_count, green / layer_count, blue / layer_count)
} }
#[cfg(feature = "render")] // #[cfg(feature = "render")]
#[must_use] // #[must_use]
fn altitude_color(altitude: f32) -> Color { // fn altitude_color(altitude: f32) -> Color {
if altitude < 0.0 { // if altitude < 0.0 {
Color::rgb(0.0, 0.0, (2.0 - altitude / World::MIN_ALTITUDE) / 2.0) // Color::rgb(0.0, 0.0, (2.0 - altitude / World::MIN_ALTITUDE) / 2.0)
} else { // } else {
let mult = (1.0 + altitude / World::MAX_ALTITUDE) / 2.0; // let mult = (1.0 + altitude / World::MAX_ALTITUDE) / 2.0;
Color::rgb(0.58 * mult, 0.29 * mult, 0.0) // Color::rgb(0.58 * mult, 0.29 * mult, 0.0)
} // }
} // }
#[cfg(feature = "render")] #[cfg(feature = "render")]
#[must_use] #[must_use]

View file

@ -5,3 +5,33 @@ pub(crate) use window::*;
pub(crate) mod widgets; pub(crate) mod widgets;
pub(crate) mod windows; pub(crate) mod windows;
use {
crate::gui::{open_window, WidgetId, WidgetSystem},
bevy::{
asset::Assets,
ecs::change_detection::Mut,
log::debug,
render::{render_resource::Extent3d, texture::Image},
},
planet::WorldManager,
};
fn update_textures(world_manager: &WorldManager, images: &mut Mut<Assets<Image>>) {
debug!("refreshing world texture");
let map_image_handle = images.get_handle(
world_manager
.render_settings
.map_image_handle_id
.expect("No map image handle"),
);
let map_image = images
.get_mut(&map_image_handle)
.expect("Map image handle pointing to non-existing image");
map_image.resize(Extent3d {
width: world_manager.world().width,
height: world_manager.world().height,
depth_or_array_layers: 1,
});
map_image.data = world_manager.map_color_bytes();
}

View file

@ -9,7 +9,7 @@ use {
}; };
use { use {
crate::{ crate::{
gui::{open_window, windows::Overlay, WidgetId, WidgetSystem}, gui::{open_window, update_textures, windows::Overlay, WidgetId, WidgetSystem},
macros::iterable_enum, macros::iterable_enum,
resources::OpenedWindows, resources::OpenedWindows,
}, },
@ -22,7 +22,7 @@ use {
world::World, world::World,
}, },
log::debug, log::debug,
render::{render_resource::Extent3d, texture::Image}, render::texture::Image,
}, },
bevy_egui::egui::{Layout, Ui}, bevy_egui::egui::{Layout, Ui},
planet::WorldManager, planet::WorldManager,
@ -34,41 +34,19 @@ iterable_enum!(ToolbarButton {
GenerateWorld, GenerateWorld,
SaveWorld, SaveWorld,
LoadWorld, LoadWorld,
Rainfall,
Temperature,
Overlays, Overlays,
ToggleBiomes, ToggleBiomes,
Contours,
}); });
#[cfg(feature = "globe_view")] #[cfg(feature = "globe_view")]
iterable_enum!(ToolbarButton { iterable_enum!(ToolbarButton {
GenerateWorld, GenerateWorld,
SaveWorld, SaveWorld,
LoadWorld, LoadWorld,
Rainfall,
Temperature,
Overlays, Overlays,
ToggleBiomes, ToggleBiomes,
Contours,
GlobeView, GlobeView,
}); });
fn update_textures(world_manager: &WorldManager, images: &mut Mut<Assets<Image>>) {
debug!("refreshing world texture");
let map_image_handle = images.get_handle(
world_manager
.map_image_handle_id
.expect("No map image handle"),
);
let map_image = images
.get_mut(&map_image_handle)
.expect("Map image handle pointing to non-existing image");
map_image.resize(Extent3d {
width: world_manager.world().width,
height: world_manager.world().height,
depth_or_array_layers: 1,
});
map_image.data = world_manager.map_color_bytes();
}
impl ToolbarButton { impl ToolbarButton {
fn clicked(self, world: &mut World) { fn clicked(self, world: &mut World) {
world.resource_scope(|world, mut world_manager: Mut<'_, WorldManager>| { world.resource_scope(|world, mut world_manager: Mut<'_, WorldManager>| {
@ -93,23 +71,11 @@ impl ToolbarButton {
update_textures(&world_manager, &mut images); update_textures(&world_manager, &mut images);
} }
}, },
ToolbarButton::Rainfall => {
world_manager.toggle_rainfall();
update_textures(&world_manager, &mut world.resource_mut::<Assets<Image>>());
},
ToolbarButton::Temperature => {
world_manager.toggle_temperature();
update_textures(&world_manager, &mut world.resource_mut::<Assets<Image>>());
},
ToolbarButton::Overlays => { ToolbarButton::Overlays => {
open_window::<Overlay>(&mut world.resource_mut::<OpenedWindows>()); open_window::<Overlay>(&mut world.resource_mut::<OpenedWindows>());
}, },
ToolbarButton::ToggleBiomes => { ToolbarButton::ToggleBiomes => {
world_manager.cycle_view(); world_manager.render_settings.cycle_view();
update_textures(&world_manager, &mut world.resource_mut::<Assets<Image>>());
},
ToolbarButton::Contours => {
world_manager.toggle_contours();
update_textures(&world_manager, &mut world.resource_mut::<Assets<Image>>()); update_textures(&world_manager, &mut world.resource_mut::<Assets<Image>>());
}, },
#[cfg(feature = "globe_view")] #[cfg(feature = "globe_view")]
@ -132,9 +98,6 @@ impl ToolbarButton {
impl From<ToolbarButton> for &'static str { impl From<ToolbarButton> for &'static str {
fn from(button: ToolbarButton) -> Self { fn from(button: ToolbarButton) -> Self {
match button { match button {
ToolbarButton::Rainfall => "Toggle rainfall",
ToolbarButton::Temperature => "Toggle temperature",
ToolbarButton::Contours => "Toggle contours",
ToolbarButton::Overlays => "Overlays", ToolbarButton::Overlays => "Overlays",
ToolbarButton::ToggleBiomes => "Toggle biome view", ToolbarButton::ToggleBiomes => "Toggle biome view",
ToolbarButton::GenerateWorld => "Generate new world", ToolbarButton::GenerateWorld => "Generate new world",

View file

@ -31,6 +31,7 @@ use {
system::{Commands, IntoExclusiveSystem, Query, Res}, system::{Commands, IntoExclusiveSystem, Query, Res},
world::World, world::World,
}, },
input::{keyboard::KeyCode, Input},
prelude::Vec2, prelude::Vec2,
render::{ render::{
camera::{Camera, RenderTarget}, camera::{Camera, RenderTarget},
@ -53,7 +54,7 @@ use {
EguiContext, EguiContext,
}, },
components::panning::Pan2d, components::panning::Pan2d,
gui::{render_windows, widget, widgets::ToolbarWidget}, gui::{render_windows, widget, widgets::ToolbarWidget, window::open_window, windows::TileInfo},
resources::{CursorMapPosition, OpenedWindows}, resources::{CursorMapPosition, OpenedWindows},
}; };
#[cfg(all(feature = "render", feature = "globe_view"))] #[cfg(all(feature = "render", feature = "globe_view"))]
@ -170,14 +171,14 @@ fn generate_graphics(
}, },
..default() ..default()
}); });
world_manager.map_image_handle_id = Some(map_image_handle.id); world_manager.render_settings.map_image_handle_id = Some(map_image_handle.id);
_ = commands _ = commands
.spawn_bundle(Camera2dBundle::default()) .spawn_bundle(Camera2dBundle::default())
.insert(Pan2d::new()); .insert(Pan2d::new());
// TODO: Switch to egui // TODO: Switch to egui
_ = commands.spawn_bundle(SpriteBundle { _ = commands.spawn_bundle(SpriteBundle {
texture: images.get_handle(world_manager.map_image_handle_id.unwrap()), texture: images.get_handle(world_manager.render_settings.map_image_handle_id.unwrap()),
sprite: Sprite { sprite: Sprite {
custom_size: Some(custom_sprite_size), custom_size: Some(custom_sprite_size),
..default() ..default()
@ -206,7 +207,7 @@ fn generate_graphics(
}, },
..default() ..default()
}); });
world_manager.globe_image_handle_id = Some(globe_image_handle.id); world_manager.render_settings.globe_image_handle_id = Some(globe_image_handle.id);
_ = commands.spawn_bundle(Camera3dBundle { _ = commands.spawn_bundle(Camera3dBundle {
camera: Camera { camera: Camera {
@ -224,10 +225,10 @@ fn generate_graphics(
let globe_material_handle = materials.add( let globe_material_handle = materials.add(
images images
.get_handle(world_manager.globe_image_handle_id.unwrap()) .get_handle(world_manager.render_settings.globe_image_handle_id.unwrap())
.into(), .into(),
); );
world_manager.globe_material_handle_id = Some(globe_material_handle.id); world_manager.render_settings.globe_material_handle_id = Some(globe_material_handle.id);
// TODO: Globe texture is mirrored east-to-west. // TODO: Globe texture is mirrored east-to-west.
_ = commands.spawn_bundle(PbrBundle { _ = commands.spawn_bundle(PbrBundle {
@ -251,6 +252,13 @@ fn generate_graphics(
} }
} }
#[cfg(feature = "render")]
fn open_tile_info(mut windows: ResMut<OpenedWindows>, keys: Res<Input<KeyCode>>) {
if keys.just_released(KeyCode::I) {
open_window::<TileInfo>(&mut windows);
}
}
#[cfg(feature = "render")] #[cfg(feature = "render")]
fn update_gui(world: &mut World) { fn update_gui(world: &mut World) {
world.resource_scope(|world, mut ctx: Mut<'_, EguiContext>| { world.resource_scope(|world, mut ctx: Mut<'_, EguiContext>| {
@ -307,7 +315,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.insert_resource(OpenedWindows::default()) .insert_resource(OpenedWindows::default())
.add_startup_system(generate_graphics) .add_startup_system(generate_graphics)
.add_system(update_gui.exclusive_system()) .add_system(update_gui.exclusive_system())
.add_system(update_cursor_map_position); .add_system(update_cursor_map_position)
.add_system(open_tile_info);
#[cfg(all(feature = "render", feature = "globe_view"))] #[cfg(all(feature = "render", feature = "globe_view"))]
{ {
_ = app.add_system(rotate_globe); _ = app.add_system(rotate_globe);