diff --git a/engine/world_generation/src/heightmap.rs b/engine/world_generation/src/heightmap.rs index c8a6593..8eeee8b 100644 --- a/engine/world_generation/src/heightmap.rs +++ b/engine/world_generation/src/heightmap.rs @@ -29,7 +29,7 @@ pub fn generate_chunk(chunk_x: f64, chunk_z: f64, cfg: &GenerationConfig, seed: &cfg, &noise, ); - result[x + z * Chunk::SIZE] = sample; + result[x + z * Chunk::SIZE] = sample.floor(); } } return Chunk { diff --git a/engine/world_generation/src/lib.rs b/engine/world_generation/src/lib.rs index 32b401f..3722b68 100644 --- a/engine/world_generation/src/lib.rs +++ b/engine/world_generation/src/lib.rs @@ -28,7 +28,7 @@ pub mod prelude { } impl Chunk { - pub const SIZE: usize = 32; + pub const SIZE: usize = 64; } #[derive(Resource)] diff --git a/engine/world_generation/src/mesh_generator.rs b/engine/world_generation/src/mesh_generator.rs index 235cf3c..a3e4450 100644 --- a/engine/world_generation/src/mesh_generator.rs +++ b/engine/world_generation/src/mesh_generator.rs @@ -10,6 +10,7 @@ use bevy::{ render_asset::RenderAssetUsages, }, }; +use std::vec::Vec; const HEX_CORNERS: [Vec3; 6] = [ Vec3::new(0., 0., OUTER_RADIUS), @@ -35,7 +36,14 @@ pub fn generate_chunk_mesh(chunk: &Chunk, map: &Map) -> Mesh { IVec2::new(x as i32, z as i32) + (chunk.chunk_offset * Chunk::SIZE as i32), ); let n = map.get_neighbors(&coord); - create_tile(tile_pos, &n, &mut verts, &mut uvs, &mut indices, 0); + create_tile( + tile_pos, + &n, + &mut verts, + &mut uvs, + &mut indices, + ((x + z * Chunk::SIZE) % 32) as u32, + ); } } @@ -60,13 +68,23 @@ fn create_tile( indices: &mut Vec, texture_index: u32, ) { + let tex_x = texture_index % 11; + let tex_y = texture_index / 11; + let x_min = tex_x as f32 / 11.; + let x_max = (tex_x + 1) as f32 / 11.; + let y_min = tex_y as f32 / 8.; + let tx_unit = x_max - x_min; + + let uv_offset = Vec2::new(x_min + tx_unit / 2., y_min + tx_unit / 2.); + let idx = verts.len() as u32; - uvs.push(pos.xz()); + uvs.push(uv_offset); verts.push(pos); for i in 0..6 { let p = pos + HEX_CORNERS[i]; verts.push(p); - uvs.push(p.xz()); + let uv = (HEX_CORNERS[i].xz() * tx_unit / 2.) + uv_offset; + uvs.push(uv); indices.push(idx); indices.push(idx + 1 + i as u32); indices.push(idx + 1 + ((i as u32 + 1) % 6)); @@ -77,7 +95,16 @@ fn create_tile( match cur_n { Some(n_height) => { if n_height < pos.y { - create_tile_wall(pos, i, n_height, verts, uvs, indices, texture_index); + create_tile_wall( + pos, + i, + n_height, + verts, + uvs, + indices, + Vec2::new(x_min, y_min), + Vec2::new(x_min + tx_unit, y_min + tx_unit), + ); } } _ => {} @@ -92,7 +119,8 @@ fn create_tile_wall( verts: &mut Vec, uvs: &mut Vec, indices: &mut Vec, - _texture_index: u32, + tx_min: Vec2, + tx_max: Vec2, ) { let p1 = HEX_CORNERS[(dir) % 6] + pos; let p2 = HEX_CORNERS[(dir + 1) % 6] + pos; @@ -114,8 +142,9 @@ fn create_tile_wall( indices.push(idx + 2); indices.push(idx + 3); - uvs.push(Vec2::new(0., 0.)); - uvs.push(Vec2::new(1., 0.)); - uvs.push(Vec2::new(0., 1.)); - uvs.push(Vec2::new(1., 1.)); + //TODO: scale texture based on height + uvs.push(tx_min); + uvs.push(Vec2::new(tx_max.x, tx_min.y)); + uvs.push(Vec2::new(tx_min.x, tx_max.y)); + uvs.push(tx_max); } diff --git a/game/camera_system/src/lib.rs b/game/camera_system/src/lib.rs index cdf753e..af4d30a 100644 --- a/game/camera_system/src/lib.rs +++ b/game/camera_system/src/lib.rs @@ -33,7 +33,7 @@ fn setup(mut commands: Commands) { ..default() }, PhosCamera { - speed: 50., + speed: 100., ..default() }, )); diff --git a/game/main/assets/textures/world/test.png b/game/main/assets/textures/world/test.png new file mode 100644 index 0000000..f11c9bf Binary files /dev/null and b/game/main/assets/textures/world/test.png differ diff --git a/game/main/assets/textures/world/test2.png b/game/main/assets/textures/world/test2.png new file mode 100644 index 0000000..4b2ba3c Binary files /dev/null and b/game/main/assets/textures/world/test2.png differ diff --git a/game/main/src/main.rs b/game/main/src/main.rs index 20cd3c3..f173c1b 100644 --- a/game/main/src/main.rs +++ b/game/main/src/main.rs @@ -1,6 +1,8 @@ use bevy::prelude::*; use bevy_inspector_egui::quick::WorldInspectorPlugin; mod phos; +mod prelude; + use phos::PhosGamePlugin; fn main() { diff --git a/game/main/src/phos.rs b/game/main/src/phos.rs index 2e8f823..f47d556 100644 --- a/game/main/src/phos.rs +++ b/game/main/src/phos.rs @@ -6,13 +6,15 @@ use world_generation::{ heightmap::generate_heightmap, mesh_generator::generate_chunk_mesh, prelude::*, }; +use crate::prelude::*; + pub struct PhosGamePlugin; impl Plugin for PhosGamePlugin { fn build(&self, app: &mut App) { app.add_plugins(PhosCameraPlugin); app.add_systems(Startup, init_game) - .add_systems(Startup, create_map); + .add_systems(Startup, (load_textures, create_map).chain()); app.add_plugins(bevy::diagnostic::FrameTimeDiagnosticsPlugin) .add_plugins(bevy::diagnostic::EntityCountDiagnosticsPlugin) .add_plugins(bevy::diagnostic::SystemInformationDiagnosticsPlugin) @@ -38,11 +40,18 @@ fn init_game(mut commands: Commands) { bounds: vec![500., 1000., 2000., 5000.], ..default() }, - transform: Transform::from_xyz(500., 160.0, 500.).looking_at(Vec3::ZERO, Vec3::Y), + transform: Transform::from_xyz(500., 260.0, 500.).looking_at(Vec3::ZERO, Vec3::Y), ..default() }); } +fn load_textures(mut commands: Commands, asset_server: Res) { + let main_tex = asset_server.load("textures/world/test2.png"); + commands.insert_resource(ChunkAtlas { + handle: main_tex.clone(), + }); +} + fn draw_gizmos(mut gizmos: Gizmos, hm: Res) { gizmos.arrow(Vec3::ZERO, Vec3::Y * 1.5, Color::GREEN); gizmos.arrow(Vec3::ZERO, Vec3::Z * 1.5, Color::BLUE); @@ -77,6 +86,7 @@ fn create_map( mut commands: Commands, mut materials: ResMut>, mut meshes: ResMut>, + atlas: Res, ) { let heightmap = generate_heightmap( &GenerationConfig { @@ -133,13 +143,13 @@ fn create_map( noise_scale: 350., sea_level: 4., border_size: 64., - size: (32, 32).into(), + size: UVec2::splat(1024 / Chunk::SIZE as u32), }, 2, ); - let debug_material = materials.add(StandardMaterial { - // base_color_texture: Some(images.add(uv_debug_texture())), + let chunk_material = materials.add(StandardMaterial { + base_color_texture: Some(atlas.handle.clone()), ..default() }); @@ -148,7 +158,7 @@ fn create_map( let pos = offset_to_world(chunk.chunk_offset * Chunk::SIZE as i32, 0.); commands.spawn(PbrBundle { mesh: meshes.add(mesh), - material: debug_material.clone(), + material: chunk_material.clone(), transform: Transform::from_translation(pos), ..default() }); diff --git a/game/main/src/prelude.rs b/game/main/src/prelude.rs new file mode 100644 index 0000000..1ec9019 --- /dev/null +++ b/game/main/src/prelude.rs @@ -0,0 +1,7 @@ +use bevy::asset::Handle; +use bevy::prelude::{Image, Resource}; + +#[derive(Resource)] +pub struct ChunkAtlas { + pub handle: Handle, +}