Fix planet_view feature
40c19014c9774cdf8cc4e5003393de5e8363ef17
This commit is contained in:
parent
7662fcda50
commit
b064aa0dd9
10 changed files with 648509 additions and 103 deletions
15
.github/workflows/release.yaml
vendored
15
.github/workflows/release.yaml
vendored
|
@ -11,7 +11,7 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
os: [windows-2022, ubuntu-22.04, macos-12]
|
||||
features: ["debug,render", render, "debug", ""]
|
||||
features: ["debug,render", "render", "debug,planet_view", "planet_view", "debug", ""]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
@ -27,16 +27,23 @@ jobs:
|
|||
run: |
|
||||
cargo build --release --no-default-features --features=${{ matrix.features }}
|
||||
|
||||
- name: Upload full binary
|
||||
- name: Upload debug & render binary
|
||||
uses: actions/upload-artifact@v3
|
||||
if: ${{ matrix.features == 'debug,render' }}
|
||||
with:
|
||||
name: worlds-rs-${{ matrix.os }}-debug-render
|
||||
path: target/release/worlds-sim-rust*
|
||||
|
||||
- name: Upload partial-feature binary
|
||||
- name: Upload debug & planet_view binary
|
||||
uses: actions/upload-artifact@v3
|
||||
if: ${{ matrix.features != 'debug,render' && matrix.features != '' }}
|
||||
if: ${{ matrix.features == 'debug,planet_view' }}
|
||||
with:
|
||||
name: worlds-rs-${{ matrix.os }}-debug-planet_view
|
||||
path: target/release/worlds-sim-rust*
|
||||
|
||||
- name: Upload non-debug binary
|
||||
uses: actions/upload-artifact@v3
|
||||
if: ${{ !contains(matrix.features, ',') && matrix.features != '' }}
|
||||
with:
|
||||
name: worlds-rs-${{ matrix.os }}-${{ matrix.features }}
|
||||
path: target/release/worlds-sim-rust*
|
||||
|
|
|
@ -9,7 +9,7 @@ winit = { version = "0.26.1", features=["x11"] }
|
|||
|
||||
[features]
|
||||
debug = ["planet/debug"]
|
||||
planet_view = ["render"]
|
||||
planet_view = ["planet/planet_view", "render"]
|
||||
render = ["bevy/bevy_asset", "bevy/bevy_winit", "bevy/render", "planet/render", "dep:bevy_pancam"]
|
||||
default = ["render", "debug"]
|
||||
|
||||
|
|
648204
planet.ron
648204
planet.ron
File diff suppressed because one or more lines are too long
|
@ -5,8 +5,9 @@ edition = "2021"
|
|||
|
||||
[features]
|
||||
debug = []
|
||||
planet_view = ["render"]
|
||||
render = ["bevy/render"]
|
||||
default = ["render", "debug"]
|
||||
default = ["render", "debug", "planet_view"]
|
||||
|
||||
[dependencies.rand]
|
||||
version = "0.8.5"
|
||||
|
|
|
@ -6,7 +6,7 @@ use {
|
|||
};
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Biome {
|
||||
pub struct BiomeStats {
|
||||
pub name: String,
|
||||
#[cfg(feature = "render")]
|
||||
pub color: Color,
|
||||
|
@ -33,10 +33,10 @@ macro_rules! biome_enum {
|
|||
|
||||
biome_enum!(IceCap, Ocean, Grassland, Forest, Taiga, Tundra, Desert, Rainforest);
|
||||
|
||||
impl From<BiomeType> for Biome {
|
||||
fn from(biome_type: BiomeType) -> Biome {
|
||||
impl From<BiomeType> for BiomeStats {
|
||||
fn from(biome_type: BiomeType) -> BiomeStats {
|
||||
match biome_type {
|
||||
BiomeType::IceCap => Biome {
|
||||
BiomeType::IceCap => BiomeStats {
|
||||
name: "Ice Cap".into(),
|
||||
#[cfg(feature = "render")]
|
||||
color: Color::rgb_u8(253, 244, 235),
|
||||
|
@ -47,7 +47,7 @@ impl From<BiomeType> for Biome {
|
|||
min_temperature: World::MIN_TEMPERATURE,
|
||||
max_temperature: -15.0,
|
||||
},
|
||||
BiomeType::Ocean => Biome {
|
||||
BiomeType::Ocean => BiomeStats {
|
||||
name: "Ocean".into(),
|
||||
#[cfg(feature = "render")]
|
||||
color: Color::rgb_u8(28, 66, 84),
|
||||
|
@ -58,7 +58,7 @@ impl From<BiomeType> for Biome {
|
|||
min_temperature: -15.0,
|
||||
max_temperature: World::MAX_TEMPERATURE,
|
||||
},
|
||||
BiomeType::Grassland => Biome {
|
||||
BiomeType::Grassland => BiomeStats {
|
||||
name: "Grassland".into(),
|
||||
#[cfg(feature = "render")]
|
||||
color: Color::rgb_u8(167, 177, 84),
|
||||
|
@ -69,7 +69,7 @@ impl From<BiomeType> for Biome {
|
|||
min_temperature: -5.0,
|
||||
max_temperature: World::MAX_TEMPERATURE,
|
||||
},
|
||||
BiomeType::Forest => Biome {
|
||||
BiomeType::Forest => BiomeStats {
|
||||
name: "Forest".into(),
|
||||
#[cfg(feature = "render")]
|
||||
color: Color::rgb_u8(76, 132, 55),
|
||||
|
@ -80,7 +80,7 @@ impl From<BiomeType> for Biome {
|
|||
min_temperature: -5.0,
|
||||
max_temperature: World::MAX_TEMPERATURE,
|
||||
},
|
||||
BiomeType::Taiga => Biome {
|
||||
BiomeType::Taiga => BiomeStats {
|
||||
name: "Taiga".into(),
|
||||
#[cfg(feature = "render")]
|
||||
color: Color::rgb_u8(43, 63, 40),
|
||||
|
@ -91,7 +91,7 @@ impl From<BiomeType> for Biome {
|
|||
min_temperature: -15.0,
|
||||
max_temperature: -0.0,
|
||||
},
|
||||
BiomeType::Tundra => Biome {
|
||||
BiomeType::Tundra => BiomeStats {
|
||||
name: "Tundra ".into(),
|
||||
#[cfg(feature = "render")]
|
||||
color: Color::rgb_u8(139, 139, 128),
|
||||
|
@ -102,7 +102,7 @@ impl From<BiomeType> for Biome {
|
|||
min_temperature: -20.0,
|
||||
max_temperature: -0.0,
|
||||
},
|
||||
BiomeType::Desert => Biome {
|
||||
BiomeType::Desert => BiomeStats {
|
||||
name: "Desert ".into(),
|
||||
#[cfg(feature = "render")]
|
||||
color: Color::rgb_u8(253, 225, 171),
|
||||
|
@ -113,7 +113,7 @@ impl From<BiomeType> for Biome {
|
|||
min_temperature: -5.0,
|
||||
max_temperature: World::MAX_TEMPERATURE,
|
||||
},
|
||||
BiomeType::Rainforest => Biome {
|
||||
BiomeType::Rainforest => BiomeStats {
|
||||
name: "Rainforest".into(),
|
||||
#[cfg(feature = "render")]
|
||||
color: Color::rgb_u8(59, 103, 43),
|
||||
|
@ -128,8 +128,8 @@ impl From<BiomeType> for Biome {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<&BiomeType> for Biome {
|
||||
fn from(biome_type: &BiomeType) -> Biome {
|
||||
impl From<&BiomeType> for BiomeStats {
|
||||
fn from(biome_type: &BiomeType) -> BiomeStats {
|
||||
(*biome_type).into()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ impl<'de> Deserialize<'de> for World {
|
|||
Seed,
|
||||
Terrain,
|
||||
ContinentOffsets,
|
||||
ContinentWidths,
|
||||
ContinentSizes,
|
||||
}
|
||||
|
||||
struct WorldVisitor;
|
||||
|
@ -117,7 +117,7 @@ impl<'de> Deserialize<'de> for World {
|
|||
seed,
|
||||
terrain,
|
||||
continent_offsets,
|
||||
continent_widths,
|
||||
continent_sizes: continent_widths,
|
||||
|
||||
max_altitude: world_attributes.max_altitude,
|
||||
min_altitude: world_attributes.min_altitude,
|
||||
|
@ -173,7 +173,7 @@ impl<'de> Deserialize<'de> for World {
|
|||
}
|
||||
continent_offsets = Some(map.next_value()?);
|
||||
},
|
||||
Field::ContinentWidths => {
|
||||
Field::ContinentSizes => {
|
||||
if continent_widths.is_some() {
|
||||
return Err(Error::duplicate_field("continent_widths"));
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ impl<'de> Deserialize<'de> for World {
|
|||
seed,
|
||||
terrain,
|
||||
continent_offsets,
|
||||
continent_widths,
|
||||
continent_sizes: continent_widths,
|
||||
|
||||
max_altitude: world_attributes.max_altitude,
|
||||
min_altitude: world_attributes.min_altitude,
|
||||
|
|
|
@ -5,7 +5,7 @@ use {
|
|||
mix_values,
|
||||
perlin,
|
||||
random_point_in_sphere,
|
||||
Biome,
|
||||
BiomeStats,
|
||||
BiomeType,
|
||||
CartesianError,
|
||||
RepeatNum,
|
||||
|
@ -55,7 +55,7 @@ pub struct World {
|
|||
|
||||
pub terrain: Vec<Vec<TerrainCell>>,
|
||||
pub continent_offsets: [Vec2; World::NUM_CONTINENTS as usize],
|
||||
pub continent_widths: [f32; World::NUM_CONTINENTS as usize],
|
||||
pub continent_sizes: [Vec2; World::NUM_CONTINENTS as usize],
|
||||
#[serde(skip)]
|
||||
pub max_altitude: f32,
|
||||
#[serde(skip)]
|
||||
|
@ -90,7 +90,7 @@ impl World {
|
|||
pub(crate) const MAX_TEMPERATURE: f32 = 30.0;
|
||||
pub(crate) const MIN_ALTITUDE: f32 = -15000.0;
|
||||
pub(crate) const MIN_RAINFALL: f32 = 0.0;
|
||||
pub(crate) const MIN_TEMPERATURE: f32 = -60.0;
|
||||
pub(crate) const MIN_TEMPERATURE: f32 = -35.0;
|
||||
const MOUNTAIN_RANGE_MIX_FACTOR: f32 = 0.075;
|
||||
const MOUNTAIN_RANGE_WIDTH_FACTOR: f32 = 25.0;
|
||||
const NUM_CONTINENTS: u8 = 7;
|
||||
|
@ -114,7 +114,7 @@ impl World {
|
|||
height.try_into().unwrap()
|
||||
],
|
||||
continent_offsets: [default(); World::NUM_CONTINENTS as usize],
|
||||
continent_widths: [default(); World::NUM_CONTINENTS as usize],
|
||||
continent_sizes: [default(); World::NUM_CONTINENTS as usize],
|
||||
max_altitude: World::MIN_ALTITUDE,
|
||||
min_altitude: World::MAX_ALTITUDE,
|
||||
max_rainfall: World::MIN_RAINFALL,
|
||||
|
@ -156,9 +156,14 @@ impl World {
|
|||
self.continent_offsets[i as usize].y =
|
||||
self.rng.gen_range(height * 1.0 / 6.0..height * 5.0 / 6.0);
|
||||
|
||||
self.continent_widths[i as usize] = self
|
||||
.rng
|
||||
.gen_range(World::CONTINENT_MIN_WIDTH_FACTOR..World::CONTINENT_MAX_WIDTH_FACTOR);
|
||||
self.continent_sizes[i as usize] = Vec2 {
|
||||
x: self.rng.gen_range(
|
||||
World::CONTINENT_MIN_WIDTH_FACTOR..World::CONTINENT_MAX_WIDTH_FACTOR,
|
||||
),
|
||||
y: self.rng.gen_range(
|
||||
World::CONTINENT_MIN_WIDTH_FACTOR..World::CONTINENT_MAX_WIDTH_FACTOR,
|
||||
),
|
||||
};
|
||||
}
|
||||
info!("Done generating continents");
|
||||
}
|
||||
|
@ -175,20 +180,25 @@ impl World {
|
|||
for i in 0..World::NUM_CONTINENTS {
|
||||
let idx = i as usize;
|
||||
let Vec2 {
|
||||
x: continent_x,
|
||||
y: continent_y,
|
||||
x: offset_x,
|
||||
y: offset_y,
|
||||
} = self.continent_offsets[idx];
|
||||
let Vec2 {
|
||||
x: continent_width,
|
||||
y: continent_height,
|
||||
} = self.continent_sizes[idx];
|
||||
|
||||
let distance_x = f32::min(
|
||||
f32::min(f32::abs(continent_x - x), f32::abs(width + continent_x - x)),
|
||||
f32::abs(continent_x - x - width),
|
||||
) * beta_factor;
|
||||
f32::min(f32::abs(offset_x - x), f32::abs(width + offset_x - x)),
|
||||
f32::abs(offset_x - x - width),
|
||||
) * beta_factor
|
||||
* continent_width;
|
||||
|
||||
let distance_y = f32::abs(continent_y - y);
|
||||
let distance_y = f32::abs(offset_y - y) * continent_height;
|
||||
|
||||
let distance = f32::sqrt((distance_x * distance_x) + (distance_y * distance_y));
|
||||
|
||||
let value = f32::max(0.0, 1.0 - self.continent_widths[idx] * distance / width);
|
||||
let value = f32::max(0.0, 1.0 - distance / width);
|
||||
|
||||
if value > max_value {
|
||||
max_value = value;
|
||||
|
@ -464,7 +474,7 @@ impl World {
|
|||
}
|
||||
}
|
||||
|
||||
fn biome_presence(&self, cell: &TerrainCell, biome: &Biome) -> f32 {
|
||||
fn biome_presence(&self, cell: &TerrainCell, biome: &BiomeStats) -> f32 {
|
||||
let mut presence = 0.0;
|
||||
let altitude_diff = cell.altitude - biome.min_altitude;
|
||||
if altitude_diff < 0.0 {
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
use bevy::log::debug;
|
||||
#[cfg(feature = "debug")]
|
||||
use bevy::utils::default;
|
||||
#[cfg(all(feature = "render", feature = "planet_view"))]
|
||||
use std::f32::consts::PI;
|
||||
#[cfg(feature = "render")]
|
||||
use {
|
||||
crate::{Biome, TerrainCell},
|
||||
crate::{BiomeStats, TerrainCell},
|
||||
bevy::{
|
||||
asset::{Assets, HandleId},
|
||||
render::render_resource::Extent3d,
|
||||
|
@ -89,9 +91,15 @@ impl Display for SaveError {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct WorldManager {
|
||||
world: Option<World>,
|
||||
world: Option<World>,
|
||||
|
||||
#[cfg(feature = "render")]
|
||||
pub image_handle_id: Option<HandleId>,
|
||||
pub map_image_handle_id: Option<HandleId>,
|
||||
#[cfg(all(feature = "render", feature = "planet_view"))]
|
||||
pub planet_image_handle_id: Option<HandleId>,
|
||||
#[cfg(all(feature = "render", feature = "planet_view"))]
|
||||
pub planet_material_handle_id: Option<HandleId>,
|
||||
|
||||
#[cfg(feature = "render")]
|
||||
rainfall_visible: bool,
|
||||
#[cfg(feature = "render")]
|
||||
|
@ -105,17 +113,21 @@ pub struct WorldManager {
|
|||
impl WorldManager {
|
||||
pub fn new() -> WorldManager {
|
||||
Self {
|
||||
#[cfg(feature = "render")]
|
||||
image_handle_id: None,
|
||||
world: None,
|
||||
#[cfg(feature = "render")]
|
||||
map_image_handle_id: None,
|
||||
#[cfg(all(feature = "render", feature = "planet_view"))]
|
||||
planet_image_handle_id: None,
|
||||
#[cfg(all(feature = "render", feature = "planet_view"))]
|
||||
planet_material_handle_id: None,
|
||||
#[cfg(feature = "render")]
|
||||
rainfall_visible: false,
|
||||
#[cfg(feature = "render")]
|
||||
temperature_visible: false,
|
||||
#[cfg(feature = "render")]
|
||||
biomes_visible: false,
|
||||
biomes_visible: true,
|
||||
#[cfg(feature = "render")]
|
||||
contours: true,
|
||||
contours: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,7 +187,7 @@ impl WorldManager {
|
|||
#[cfg(feature = "render")]
|
||||
{
|
||||
let image_handle = &images.get_handle(
|
||||
self.image_handle_id
|
||||
self.map_image_handle_id
|
||||
.expect("Missing image handle, even though world is present"),
|
||||
);
|
||||
images
|
||||
|
@ -359,7 +371,7 @@ impl WorldManager {
|
|||
cell.biome_presences
|
||||
.iter()
|
||||
.fold(Color::BLACK, |color, (biome_type, presence)| {
|
||||
let biome: Biome = (*biome_type).into();
|
||||
let biome: BiomeStats = (*biome_type).into();
|
||||
let biome_color = biome.color;
|
||||
|
||||
Color::rgb(
|
||||
|
@ -370,24 +382,67 @@ impl WorldManager {
|
|||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "render")]
|
||||
pub fn world_colors(&self) -> Vec<Color> {
|
||||
match self.get_world() {
|
||||
None => panic!("Called world_colors before generating world"),
|
||||
Some(world) => {
|
||||
let terrain_cells: Vec<_> = world.terrain.iter().rev().flatten().collect();
|
||||
// #[cfg(feature = "render")]
|
||||
// #[must_use]
|
||||
// fn map_colors(&self) -> Vec<Color> {
|
||||
// self.world()
|
||||
// .terrain
|
||||
// .iter()
|
||||
// .rev()
|
||||
// .flatten()
|
||||
// .map(|cell| self.generate_color(cell))
|
||||
// .collect()
|
||||
// }
|
||||
|
||||
terrain_cells
|
||||
#[cfg(feature = "render")]
|
||||
#[must_use]
|
||||
pub fn map_color_bytes(&self) -> Vec<u8> {
|
||||
self.world()
|
||||
.terrain
|
||||
.iter()
|
||||
.rev()
|
||||
.flatten()
|
||||
.flat_map(|cell| {
|
||||
self.generate_color(cell)
|
||||
.as_rgba_f32()
|
||||
.iter()
|
||||
.map(|cell| self.generate_color(cell))
|
||||
.collect()
|
||||
},
|
||||
}
|
||||
.flat_map(|num| num.to_le_bytes())
|
||||
.collect::<Vec<u8>>()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(feature = "render")]
|
||||
pub fn world_color_bytes(&self) -> Vec<u8> {
|
||||
self.world_colors()
|
||||
#[cfg(all(feature = "render", feature = "planet_view"))]
|
||||
#[must_use]
|
||||
fn planet_colors(&self) -> Vec<Color> {
|
||||
let world = self.world();
|
||||
let width = world.width as usize;
|
||||
let height = world.height as usize;
|
||||
|
||||
let mut colors = vec![Color::PINK; height * width];
|
||||
|
||||
for y in 0..world.height as usize * 2 {
|
||||
for x in 0..world.width as usize {
|
||||
let factor_y = (1.0 - f32::cos(PI * y as f32 / (world.height * 2) as f32)) / 2.0;
|
||||
let real_y = f32::floor(world.height as f32 * factor_y) as usize;
|
||||
#[cfg(feature = "debug")]
|
||||
assert!(
|
||||
real_y < world.height as usize,
|
||||
"Trying to get cell off of planet. {}/{}",
|
||||
real_y,
|
||||
world.height
|
||||
);
|
||||
|
||||
colors[real_y * width + x] = self.generate_color(&world.terrain[real_y][x]);
|
||||
}
|
||||
}
|
||||
colors
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "render", feature = "planet_view"))]
|
||||
#[must_use]
|
||||
pub fn planet_color_bytes(&self) -> Vec<u8> {
|
||||
self.planet_colors()
|
||||
.iter()
|
||||
.flat_map(|color| {
|
||||
color
|
||||
|
|
|
@ -15,7 +15,7 @@ macro_rules! toolbar_enum {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "render")]
|
||||
#[cfg(all(feature = "render", not(feature = "planet_view")))]
|
||||
toolbar_enum!(
|
||||
GenerateWorld,
|
||||
SaveWorld,
|
||||
|
@ -25,6 +25,17 @@ toolbar_enum!(
|
|||
Biomes,
|
||||
Contours,
|
||||
);
|
||||
#[cfg(all(feature = "render", feature = "planet_view"))]
|
||||
toolbar_enum!(
|
||||
GenerateWorld,
|
||||
SaveWorld,
|
||||
LoadWorld,
|
||||
Rainfall,
|
||||
Temperature,
|
||||
Biomes,
|
||||
Contours,
|
||||
PlanetView,
|
||||
);
|
||||
|
||||
#[cfg(feature = "render")]
|
||||
impl From<ToolbarButton> for &'static str {
|
||||
|
@ -37,6 +48,8 @@ impl From<ToolbarButton> for &'static str {
|
|||
ToolbarButton::GenerateWorld => "Generate new world",
|
||||
ToolbarButton::SaveWorld => "Save",
|
||||
ToolbarButton::LoadWorld => "Load",
|
||||
#[cfg(feature = "planet_view")]
|
||||
ToolbarButton::PlanetView => "Toggle planet view",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
198
src/main.rs
198
src/main.rs
|
@ -37,16 +37,6 @@ mod plugins;
|
|||
mod resources;
|
||||
mod ui_helpers;
|
||||
|
||||
#[cfg(all(feature = "render", feature = "planet_view"))]
|
||||
use bevy::{
|
||||
asset::Handle,
|
||||
core_pipeline::core_3d::Camera3dBundle,
|
||||
pbr::{PbrBundle, PointLight, PointLightBundle, StandardMaterial},
|
||||
prelude::Vec3,
|
||||
render::camera::OrthographicProjection,
|
||||
render::mesh::{shape::Icosphere, Mesh},
|
||||
transform::components::Transform,
|
||||
};
|
||||
#[cfg(all(feature = "debug", feature = "render"))]
|
||||
use bevy::{
|
||||
diagnostic::{Diagnostics, FrameTimeDiagnosticsPlugin},
|
||||
|
@ -100,7 +90,7 @@ use {
|
|||
markers::{InfoPanel, ToolbarButton},
|
||||
third_party::PanCam,
|
||||
},
|
||||
planet::Biome,
|
||||
planet::BiomeStats,
|
||||
resources::CursorMapPosition,
|
||||
ui_helpers::{toolbar_button, toolbar_button_text},
|
||||
};
|
||||
|
@ -113,24 +103,72 @@ use {
|
|||
planet::WorldManager,
|
||||
plugins::WorldPlugins,
|
||||
};
|
||||
#[cfg(all(feature = "render", feature = "planet_view"))]
|
||||
use {
|
||||
bevy::{
|
||||
asset::Handle,
|
||||
core_pipeline::core_3d::{Camera3d, Camera3dBundle},
|
||||
ecs::query::Without,
|
||||
pbr::{PbrBundle, PointLight, PointLightBundle, StandardMaterial},
|
||||
prelude::{Quat, Vec3},
|
||||
render::camera::OrthographicProjection,
|
||||
render::mesh::{shape::UVSphere, Mesh},
|
||||
transform::components::Transform,
|
||||
},
|
||||
std::f32::consts::FRAC_PI_2,
|
||||
};
|
||||
|
||||
#[cfg(feature = "render")]
|
||||
fn refresh_world_texture(images: &mut Assets<Image>, world_manager: &WorldManager) {
|
||||
fn refresh_map_texture(
|
||||
images: &mut Assets<Image>,
|
||||
#[cfg(feature = "planet_view")] materials: &mut Assets<StandardMaterial>,
|
||||
world_manager: &WorldManager,
|
||||
) {
|
||||
let world = world_manager.world();
|
||||
#[cfg(feature = "debug")]
|
||||
debug!("refreshing world texture");
|
||||
let image_handle = images.get_handle(world_manager.image_handle_id.expect("No image handle"));
|
||||
let world_image = images
|
||||
.get_mut(&image_handle)
|
||||
.expect("Image handle pointing to non-existing texture");
|
||||
world_image.resize(Extent3d {
|
||||
width: world_manager.world().width,
|
||||
height: world_manager.world().height,
|
||||
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.width,
|
||||
height: world.height,
|
||||
depth_or_array_layers: 1,
|
||||
});
|
||||
world_image.data = world_manager.world_color_bytes();
|
||||
map_image.data = world_manager.map_color_bytes();
|
||||
|
||||
// TODO: Update Icosphere material. Try to find out why it doesn't
|
||||
// automatically
|
||||
#[cfg(feature = "planet_view")]
|
||||
{
|
||||
let planet_image_handle = images.get_handle(
|
||||
world_manager
|
||||
.planet_image_handle_id
|
||||
.expect("No planet image handle"),
|
||||
);
|
||||
let planet_image = images
|
||||
.get_mut(&planet_image_handle)
|
||||
.expect("Planet image handle pointing to non-existing image");
|
||||
planet_image.resize(Extent3d {
|
||||
width: world.width,
|
||||
height: world.height,
|
||||
depth_or_array_layers: 1,
|
||||
});
|
||||
planet_image.data = world_manager.planet_color_bytes();
|
||||
|
||||
let planet_material_handle = materials.get_handle(
|
||||
world_manager
|
||||
.planet_material_handle_id
|
||||
.expect("No planet material handle"),
|
||||
);
|
||||
let planet_material = materials
|
||||
.get_mut(&planet_material_handle)
|
||||
.expect("Planet material handle pointing to non-existing material");
|
||||
planet_material.base_color_texture = Some(planet_image_handle);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "render")]
|
||||
|
@ -150,6 +188,19 @@ fn handle_toolbar_button(
|
|||
mut windows: ResMut<'_, Windows>,
|
||||
mut images: ResMut<'_, Assets<Image>>,
|
||||
mut world_manager: ResMut<'_, WorldManager>,
|
||||
#[cfg(feature = "planet_view")] mut camera_3d_query: Query<
|
||||
'_,
|
||||
'_,
|
||||
&mut Camera,
|
||||
(With<Camera3d>, Without<Camera2d>),
|
||||
>,
|
||||
#[cfg(feature = "planet_view")] mut camera_2d_query: Query<
|
||||
'_,
|
||||
'_,
|
||||
&mut Camera,
|
||||
(With<Camera2d>, Without<Camera3d>),
|
||||
>,
|
||||
#[cfg(feature = "planet_view")] mut materials: ResMut<'_, Assets<StandardMaterial>>,
|
||||
) {
|
||||
for (interaction, mut color, toolbar_button) in &mut interaction_query {
|
||||
match *interaction {
|
||||
|
@ -161,25 +212,45 @@ fn handle_toolbar_button(
|
|||
#[cfg(feature = "debug")]
|
||||
debug!("Toggling rainfall");
|
||||
world_manager.toggle_rainfall();
|
||||
refresh_world_texture(&mut images, &world_manager);
|
||||
refresh_map_texture(
|
||||
&mut images,
|
||||
#[cfg(feature = "planet_view")]
|
||||
&mut materials,
|
||||
&world_manager,
|
||||
);
|
||||
},
|
||||
ToolbarButton::Temperature => {
|
||||
#[cfg(feature = "debug")]
|
||||
debug!("Toggling temperature");
|
||||
world_manager.toggle_temperature();
|
||||
refresh_world_texture(&mut images, &world_manager);
|
||||
refresh_map_texture(
|
||||
&mut images,
|
||||
#[cfg(feature = "planet_view")]
|
||||
&mut materials,
|
||||
&world_manager,
|
||||
);
|
||||
},
|
||||
ToolbarButton::Biomes => {
|
||||
#[cfg(feature = "debug")]
|
||||
debug!("Toggling biomes");
|
||||
world_manager.toggle_biomes();
|
||||
refresh_world_texture(&mut images, &world_manager);
|
||||
refresh_map_texture(
|
||||
&mut images,
|
||||
#[cfg(feature = "planet_view")]
|
||||
&mut materials,
|
||||
&world_manager,
|
||||
);
|
||||
},
|
||||
ToolbarButton::Contours => {
|
||||
#[cfg(feature = "debug")]
|
||||
debug!("Toggling contours");
|
||||
world_manager.toggle_contours();
|
||||
refresh_world_texture(&mut images, &world_manager);
|
||||
refresh_map_texture(
|
||||
&mut images,
|
||||
#[cfg(feature = "planet_view")]
|
||||
&mut materials,
|
||||
&world_manager,
|
||||
);
|
||||
},
|
||||
ToolbarButton::GenerateWorld => {
|
||||
#[cfg(feature = "debug")]
|
||||
|
@ -187,7 +258,12 @@ fn handle_toolbar_button(
|
|||
_ = world_manager
|
||||
.new_world()
|
||||
.expect("Failed to generate new world");
|
||||
refresh_world_texture(&mut images, &world_manager);
|
||||
refresh_map_texture(
|
||||
&mut images,
|
||||
#[cfg(feature = "planet_view")]
|
||||
&mut materials,
|
||||
&world_manager,
|
||||
);
|
||||
},
|
||||
ToolbarButton::SaveWorld => {
|
||||
#[cfg(feature = "debug")]
|
||||
|
@ -198,7 +274,21 @@ fn handle_toolbar_button(
|
|||
#[cfg(feature = "debug")]
|
||||
debug!("Loading world");
|
||||
_ = world_manager.load_world("planet.ron", &mut images);
|
||||
refresh_world_texture(&mut images, &world_manager);
|
||||
refresh_map_texture(
|
||||
&mut images,
|
||||
#[cfg(feature = "planet_view")]
|
||||
&mut materials,
|
||||
&world_manager,
|
||||
);
|
||||
},
|
||||
#[cfg(feature = "planet_view")]
|
||||
ToolbarButton::PlanetView => {
|
||||
#[cfg(feature = "debug")]
|
||||
debug!("Toggling planet view");
|
||||
let mut camera_3d = camera_3d_query.single_mut();
|
||||
camera_3d.is_active = !camera_3d.is_active;
|
||||
let mut camera_2d = camera_2d_query.single_mut();
|
||||
camera_2d.is_active = !camera_2d.is_active;
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -285,7 +375,7 @@ fn update_info_panel(
|
|||
.map(|(biome_type, presence)| {
|
||||
format!(
|
||||
"Biome: {} ({:.2}%)",
|
||||
(<Biome>::from(biome_type).name),
|
||||
(<BiomeStats>::from(biome_type).name),
|
||||
presence * 100.0
|
||||
)
|
||||
})
|
||||
|
@ -307,7 +397,7 @@ fn update_info_panel(
|
|||
.map(|(biome_type, presence)| {
|
||||
format!(
|
||||
"Biome: {} ({:.2}%)",
|
||||
(<Biome>::from(biome_type).name),
|
||||
(<BiomeStats>::from(biome_type).name),
|
||||
presence * 100.0
|
||||
)
|
||||
})
|
||||
|
@ -354,8 +444,8 @@ fn generate_graphics(
|
|||
y: (WORLD_SCALE * world.height as i32) as f32,
|
||||
};
|
||||
|
||||
let image_handle = images.add(Image {
|
||||
data: world_manager.world_color_bytes(),
|
||||
let map_image_handle = images.add(Image {
|
||||
data: world_manager.map_color_bytes(),
|
||||
texture_descriptor: TextureDescriptor {
|
||||
label: None,
|
||||
size: Extent3d {
|
||||
|
@ -371,10 +461,30 @@ fn generate_graphics(
|
|||
},
|
||||
..default()
|
||||
});
|
||||
world_manager.image_handle_id = Some(image_handle.id);
|
||||
world_manager.map_image_handle_id = Some(map_image_handle.id);
|
||||
|
||||
#[cfg(feature = "planet_view")]
|
||||
{
|
||||
let world = world_manager.world();
|
||||
let planet_image_handle = images.add(Image {
|
||||
data: world_manager.planet_color_bytes(),
|
||||
texture_descriptor: TextureDescriptor {
|
||||
label: None,
|
||||
size: Extent3d {
|
||||
width: world.width,
|
||||
height: world.height,
|
||||
..default()
|
||||
},
|
||||
dimension: TextureDimension::D2,
|
||||
format: TextureFormat::Rgba32Float,
|
||||
mip_level_count: 1,
|
||||
sample_count: 1,
|
||||
usage: TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING,
|
||||
},
|
||||
..default()
|
||||
});
|
||||
world_manager.planet_image_handle_id = Some(planet_image_handle.id);
|
||||
|
||||
_ = commands.spawn_bundle(Camera3dBundle {
|
||||
camera: Camera {
|
||||
is_active: false,
|
||||
|
@ -388,17 +498,25 @@ fn generate_graphics(
|
|||
.into(),
|
||||
..default()
|
||||
});
|
||||
|
||||
let planet_material_handle = materials.add(
|
||||
images
|
||||
.get_handle(world_manager.planet_image_handle_id.unwrap())
|
||||
.into(),
|
||||
);
|
||||
world_manager.planet_material_handle_id = Some(planet_material_handle.id);
|
||||
|
||||
_ = commands.spawn_bundle(PbrBundle {
|
||||
mesh: meshes.add(Mesh::from(Icosphere {
|
||||
radius: 2.0,
|
||||
subdivisions: 9,
|
||||
mesh: meshes.add(Mesh::from(UVSphere {
|
||||
radius: 2.0,
|
||||
..default()
|
||||
})),
|
||||
material: materials.add(images.get_handle(world_manager.image_handle_id).into()),
|
||||
transform: Transform::from_translation(default()),
|
||||
material: planet_material_handle,
|
||||
transform: Transform::from_rotation(Quat::from_rotation_x(FRAC_PI_2)),
|
||||
..default()
|
||||
});
|
||||
_ = commands.spawn_bundle(PointLightBundle {
|
||||
transform: Transform::from_xyz(-20.0, 20.0, 50.0),
|
||||
transform: Transform::from_xyz(-20.0, 0.0, 50.0),
|
||||
point_light: PointLight {
|
||||
intensity: 600000.,
|
||||
range: 100.,
|
||||
|
@ -415,7 +533,7 @@ fn generate_graphics(
|
|||
..default()
|
||||
});
|
||||
_ = commands.spawn_bundle(SpriteBundle {
|
||||
texture: images.get_handle(world_manager.image_handle_id.unwrap()),
|
||||
texture: images.get_handle(world_manager.map_image_handle_id.unwrap()),
|
||||
sprite: Sprite {
|
||||
custom_size: Some(custom_sprite_size),
|
||||
..default()
|
||||
|
|
Loading…
Reference in a new issue