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 });
#[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 {
world: Option<World>,
#[cfg(feature = "render")]
pub map_image_handle_id: Option<HandleId>,
#[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,
pub render_settings: WorldRenderSettings,
}
impl WorldManager {
#[must_use]
pub fn new() -> WorldManager {
Self {
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,
}
default()
}
pub fn save_world<P: AsRef<Path>>(&self, path: P) -> Result<(), SaveError> {
@ -190,7 +222,8 @@ impl WorldManager {
#[cfg(feature = "render")]
{
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"),
);
images
@ -208,54 +241,16 @@ impl WorldManager {
}
}
#[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];
}
#[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;
}
// #[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]
pub fn get_world(&self) -> Option<&World> {
@ -278,15 +273,16 @@ impl WorldManager {
#[cfg(feature = "render")]
#[must_use]
fn generate_color(&self, cell: &TerrainCell) -> Color {
if self.view == PlanetView::Biomes {
if self.render_settings.view == PlanetView::Biomes {
return WorldManager::biome_color(cell);
}
let altitude_color = if self.contours {
WorldManager::altitude_contour_color(cell.altitude)
} else {
WorldManager::altitude_color(cell.altitude)
};
let altitude_color = WorldManager::altitude_contour_color(cell.altitude);
// let altitude_color = if self.contours {
// WorldManager::altitude_contour_color(cell.altitude)
// } else {
// WorldManager::altitude_color(cell.altitude)
// };
let mut layer_count = 1.0;
@ -294,7 +290,7 @@ impl WorldManager {
let mut green = altitude_color.g();
let mut blue = altitude_color.b();
if self.rainfall_visible {
if self.render_settings.rainfall_visible {
layer_count += 1.0;
let rainfall_color = self.rainfall_contour_color(cell.rainfall);
// if self.contours {
@ -308,7 +304,7 @@ impl WorldManager {
blue += rainfall_color.b();
}
if self.temperature_visible {
if self.render_settings.temperature_visible {
layer_count += 1.0;
let temperature_color = self.temperature_contour_color(cell.temperature);
// if self.contours {
@ -325,17 +321,17 @@ impl WorldManager {
Color::rgb(red / layer_count, green / layer_count, blue / layer_count)
}
#[cfg(feature = "render")]
#[must_use]
fn altitude_color(altitude: f32) -> Color {
if altitude < 0.0 {
Color::rgb(0.0, 0.0, (2.0 - altitude / World::MIN_ALTITUDE) / 2.0)
} else {
let mult = (1.0 + altitude / World::MAX_ALTITUDE) / 2.0;
// #[cfg(feature = "render")]
// #[must_use]
// fn altitude_color(altitude: f32) -> Color {
// if altitude < 0.0 {
// Color::rgb(0.0, 0.0, (2.0 - altitude / World::MIN_ALTITUDE) / 2.0)
// } else {
// 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")]
#[must_use]

View file

@ -5,3 +5,33 @@ pub(crate) use window::*;
pub(crate) mod widgets;
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 {
crate::{
gui::{open_window, windows::Overlay, WidgetId, WidgetSystem},
gui::{open_window, update_textures, windows::Overlay, WidgetId, WidgetSystem},
macros::iterable_enum,
resources::OpenedWindows,
},
@ -22,7 +22,7 @@ use {
world::World,
},
log::debug,
render::{render_resource::Extent3d, texture::Image},
render::texture::Image,
},
bevy_egui::egui::{Layout, Ui},
planet::WorldManager,
@ -34,41 +34,19 @@ iterable_enum!(ToolbarButton {
GenerateWorld,
SaveWorld,
LoadWorld,
Rainfall,
Temperature,
Overlays,
ToggleBiomes,
Contours,
});
#[cfg(feature = "globe_view")]
iterable_enum!(ToolbarButton {
GenerateWorld,
SaveWorld,
LoadWorld,
Rainfall,
Temperature,
Overlays,
ToggleBiomes,
Contours,
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 {
fn clicked(self, world: &mut World) {
world.resource_scope(|world, mut world_manager: Mut<'_, WorldManager>| {
@ -93,23 +71,11 @@ impl ToolbarButton {
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 => {
open_window::<Overlay>(&mut world.resource_mut::<OpenedWindows>());
},
ToolbarButton::ToggleBiomes => {
world_manager.cycle_view();
update_textures(&world_manager, &mut world.resource_mut::<Assets<Image>>());
},
ToolbarButton::Contours => {
world_manager.toggle_contours();
world_manager.render_settings.cycle_view();
update_textures(&world_manager, &mut world.resource_mut::<Assets<Image>>());
},
#[cfg(feature = "globe_view")]
@ -132,9 +98,6 @@ impl ToolbarButton {
impl From<ToolbarButton> for &'static str {
fn from(button: ToolbarButton) -> Self {
match button {
ToolbarButton::Rainfall => "Toggle rainfall",
ToolbarButton::Temperature => "Toggle temperature",
ToolbarButton::Contours => "Toggle contours",
ToolbarButton::Overlays => "Overlays",
ToolbarButton::ToggleBiomes => "Toggle biome view",
ToolbarButton::GenerateWorld => "Generate new world",

View file

@ -31,6 +31,7 @@ use {
system::{Commands, IntoExclusiveSystem, Query, Res},
world::World,
},
input::{keyboard::KeyCode, Input},
prelude::Vec2,
render::{
camera::{Camera, RenderTarget},
@ -53,7 +54,7 @@ use {
EguiContext,
},
components::panning::Pan2d,
gui::{render_windows, widget, widgets::ToolbarWidget},
gui::{render_windows, widget, widgets::ToolbarWidget, window::open_window, windows::TileInfo},
resources::{CursorMapPosition, OpenedWindows},
};
#[cfg(all(feature = "render", feature = "globe_view"))]
@ -170,14 +171,14 @@ fn generate_graphics(
},
..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
.spawn_bundle(Camera2dBundle::default())
.insert(Pan2d::new());
// TODO: Switch to egui
_ = 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 {
custom_size: Some(custom_sprite_size),
..default()
@ -206,7 +207,7 @@ fn generate_graphics(
},
..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 {
camera: Camera {
@ -224,10 +225,10 @@ fn generate_graphics(
let globe_material_handle = materials.add(
images
.get_handle(world_manager.globe_image_handle_id.unwrap())
.get_handle(world_manager.render_settings.globe_image_handle_id.unwrap())
.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.
_ = 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")]
fn update_gui(world: &mut World) {
world.resource_scope(|world, mut ctx: Mut<'_, EguiContext>| {
@ -307,7 +315,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.insert_resource(OpenedWindows::default())
.add_startup_system(generate_graphics)
.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"))]
{
_ = app.add_system(rotate_globe);