diff --git a/.gitignore b/.gitignore index 6985cf1..07db1ba 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ Cargo.lock # MSVC Windows builds of rustc generate these, which store debugging information *.pdb + +#old source +_src diff --git a/Cargo.toml b/Cargo.toml index 20a81de..0905424 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math"] hashbrown = "0.13" noise = "0.8" rayon = "1.6" -#ordered-float = "3.4" +specs = { version = "0.18", features = ["specs-derive"] } [features] default = [] diff --git a/src/game.rs b/src/game.rs deleted file mode 100644 index 3c9d308..0000000 --- a/src/game.rs +++ /dev/null @@ -1,162 +0,0 @@ -use glam::Vec2; -use glium::Surface; -use glium::glutin::{ - event::{Event, WindowEvent, DeviceEvent}, - event_loop::{EventLoop, ControlFlow}, -}; -use std::time::Instant; - -mod assets; -mod display; -mod shaders; -mod camera; -mod controller; -mod world; -mod blocks; -mod items; -mod options; -mod physics; -mod player; - -use assets::Assets; -use display::init_display; -use shaders::Programs; -use camera::Camera; -use controller::Controls; -use world::World; -use options::GameOptions; - -struct State { - pub camera: Camera, - pub first_draw: bool, - pub controls: Controls, - pub world: World -} -impl State { - pub fn init() -> Self { - Self { - first_draw: true, - camera: Camera::default(), - controls: Controls::default(), - world: World::new(), - } - } -} - -pub fn run() { - log::info!("starting up"); - let event_loop = EventLoop::new(); - log::info!("initializing display"); - let display = init_display(&event_loop); - log::info!("compiling shaders"); - let programs = Programs::compile_all(&display); - log::info!("loading assets"); - let assets = Assets::load_all_sync(&display); - log::info!("init game options"); - let options = GameOptions::default(); - log::info!("init game state"); - let mut state = State::init(); - state.camera.position = [0., 260., -1.]; - log::info!("game loaded"); - - //======================= - // let vertex1 = ChunkVertex { position: [-0.5, -0.5, 0.], uv: [0., 0.], normal: [0., 1., 0.] }; - // let vertex2 = ChunkVertex { position: [ 0.0, 0.5, 0.], uv: [0., 1.], normal: [0., 1., 0.] }; - // let vertex3 = ChunkVertex { position: [ 0.5, -0.5, 0.], uv: [1., 1.], normal: [0., 1., 0.] }; - // let shape = vec![vertex1, vertex2, vertex3]; - // let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap(); - //======================= - - let mut last_render = Instant::now(); - - event_loop.run(move |event, _, control_flow| { - *control_flow = ControlFlow::Poll; - match event { - // Mouse motion - Event::DeviceEvent { - event: DeviceEvent::MouseMotion{ delta, }, .. - } => { - state.controls.process_mouse_input(delta.0, delta.1); - return - } - // Keyboard input - Event::DeviceEvent { event: DeviceEvent::Key(input), .. } => { - if let Some(key) = input.virtual_keycode { - state.controls.process_keyboard_input(key, input.state); - } - return - } - // Window events - Event::WindowEvent { event, .. } => { - match event { - WindowEvent::CloseRequested => { - log::info!("exit requested"); - *control_flow = ControlFlow::Exit; - return - }, - WindowEvent::Resized(size) => { - state.camera.update_perspective_matrix((size.width, size.height)); - }, - _ => return - } - }, - Event::MainEventsCleared => (), - _ => return - } - - //Calculate delta time - let now = Instant::now(); - let dt = (now - last_render).as_secs_f32(); - last_render = now; - - //Update controls - state.controls.calculate(dt).apply_to_camera(&mut state.camera); - - //Load new chunks - - state.world.update_loaded_chunks( - Vec2::new(state.camera.position[0], state.camera.position[2]), - &options, - &display - ); - - //Start drawing - let mut target = display.draw(); - target.clear_color_and_depth((0.5, 0.5, 1., 1.), 1.); - - //Compute camera - if state.first_draw { - let target_dimensions = target.get_dimensions(); - state.camera.update_perspective_matrix(target_dimensions); - } - let perspective = state.camera.perspective_matrix; - let view = state.camera.view_matrix(); - - //Draw chunks - state.world.render(&mut target, &programs, &assets, perspective, view, &options); - - //Draw example triangle - // target.draw( - // &vertex_buffer, - // glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList), - // &programs.chunk, - // &uniform! { - // model: [ - // [1., 0., 0., 0.], - // [0., 1., 0., 0.], - // [0., 0., 1., 0.], - // [0., 0., 0., 1.0_f32] - // ], - // view: view, - // perspective: perspective, - // tex: Sampler(&assets.textures.block_atlas, sampler_nearest) - // }, - // &Default::default() - // ).unwrap(); - - //Finish drawing - target.finish().unwrap(); - - state.first_draw = false; - }); -} diff --git a/src/game/assets.rs b/src/game/assets.rs deleted file mode 100644 index 27687a9..0000000 --- a/src/game/assets.rs +++ /dev/null @@ -1,15 +0,0 @@ -pub mod textures; - -use textures::Textures; - -pub struct Assets { - pub textures: Textures -} -impl Assets { - /// Load all assets synchronously - pub fn load_all_sync(display: &glium::Display) -> Self { - Self { - textures: Textures::load_sync(display) - } - } -} diff --git a/src/game/assets/textures.rs b/src/game/assets/textures.rs deleted file mode 100644 index c7cf857..0000000 --- a/src/game/assets/textures.rs +++ /dev/null @@ -1,103 +0,0 @@ -use std::{fs, io, path::PathBuf, sync::atomic::AtomicU16}; -use rayon::prelude::*; -use glium::texture::{RawImage2d, SrgbTexture2d, SrgbTexture2dArray}; - -//This code is terrible and has a alot of duplication - -fn load_png(file_path: &str, display: &glium::Display) -> SrgbTexture2d { - log::info!("loading texture {}", file_path); - - //Load file - let data = fs::read(file_path) - .unwrap_or_else(|_| panic!("Failed to load texture: {}", file_path)); - - //decode image data - let image_data = image::load( - io::Cursor::new(&data), - image::ImageFormat::Png - ).unwrap().to_rgba8(); - - //Create raw glium image - let image_dimensions = image_data.dimensions(); - let raw_image = RawImage2d::from_raw_rgba_reversed( - &image_data.into_raw(), - image_dimensions - ); - - //Create texture - SrgbTexture2d::new(display, raw_image).unwrap() -} - -fn load_png_array(file_paths: &[PathBuf], display: &glium::Display) -> SrgbTexture2dArray { - let counter = AtomicU16::new(0); - let raw_images: Vec> = file_paths.par_iter().enumerate().map(|(_, file_path)| { - - let fname: &str = file_path.file_name().unwrap_or_default().to_str().unwrap(); - - //Load file - let data = fs::read(file_path).expect(&format!("Failed to load texture {}", fname)); - - //decode image data - let image_data = image::load( - io::Cursor::new(&data), - image::ImageFormat::Png - ).unwrap().to_rgba8(); - - //Create raw glium image - let image_dimensions = image_data.dimensions(); - let raw_image = RawImage2d::from_raw_rgba_reversed( - &image_data.into_raw(), - image_dimensions - ); - - let counter = counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst) + 1; - log::info!("loaded texture {}/{}: {}", counter, file_paths.len(), fname); - - raw_image - }).collect(); - SrgbTexture2dArray::new(display, raw_images).unwrap() -} - -pub struct Textures { - pub blocks: SrgbTexture2dArray -} -impl Textures { - /// Load textures synchronously, one by one and upload them to the GPU - pub fn load_sync(display: &glium::Display) -> Self { - Self { - blocks: load_png_array(&[ - "./assets/blocks/stone.png".into(), - "./assets/blocks/dirt.png".into(), - "./assets/blocks/grass_top.png".into(), - "./assets/blocks/grass_side.png".into(), - "./assets/blocks/sand.png".into(), - "./assets/blocks/bedrock.png".into(), - "./assets/blocks/wood.png".into(), - "./assets/blocks/wood_top.png".into(), - "./assets/blocks/leaf.png".into(), - "./assets/blocks/torch.png".into(), - "./assets/blocks/tall_grass.png".into(), - "./assets/blocks/snow.png".into(), - "./assets/blocks/grass_side_snow.png".into(), - ], display) - } - } -} - -#[derive(Clone, Copy, Debug)] -#[repr(u8)] -pub enum BlockTexture { - Stone = 0, - Dirt = 1, - GrassTop = 2, - GrassSide = 3, - Sand = 4, - Bedrock = 5, - Wood = 6, - WoodTop = 7, - Leaf = 8, - Torch = 9, - TallGrass = 10, - Snow = 11, - GrassSideSnow = 12, -} diff --git a/src/game/blocks.rs b/src/game/blocks.rs deleted file mode 100644 index 9db47b6..0000000 --- a/src/game/blocks.rs +++ /dev/null @@ -1,141 +0,0 @@ -use strum::{EnumIter, IntoEnumIterator}; -use crate::game::{ - items::Item, - assets::textures::BlockTexture, -}; - - -#[derive(Clone, Copy, Debug)] -pub enum CollisionType { - Solid, - Liquid, - Ladder, -} - -#[derive(Clone, Copy, Debug)] -pub enum RenderType { - OpaqueBlock, - TranslucentBlock, - TranslucentLiquid, - CrossShape -} - -#[derive(Clone, Copy, Debug)] -pub struct BlockTextures { - pub top: BlockTexture, - pub bottom: BlockTexture, - pub left: BlockTexture, - pub right: BlockTexture, - pub back: BlockTexture, - pub front: BlockTexture, -} -impl BlockTextures { - pub const fn all(tex: BlockTexture) -> Self { - Self { - top: tex, - bottom: tex, - left: tex, - right: tex, - back: tex, - front: tex, - } - } - pub const fn top_sides_bottom(top: BlockTexture, sides: BlockTexture, bottom: BlockTexture) -> Self { - Self { - top, - bottom, - left: sides, - right: sides, - back: sides, - front: sides, - } - } -} - -#[derive(Clone, Copy, Debug)] -pub struct BlockDescriptor { - pub name: &'static str, - pub id: &'static str, - pub collision: Option, - pub raycast_collision: bool, - pub render: Option<(RenderType, BlockTextures)>, - pub item: Option, -} -impl BlockDescriptor { - //Not using the Default trait because this function has to be const! - pub const fn default() -> Self { - Self { - name: "default", - id: "default", - collision: Some(CollisionType::Solid), - raycast_collision: true, - render: Some((RenderType::OpaqueBlock, BlockTextures::all(BlockTexture::Stone))), - item: None - } - } -} - -#[derive(Clone, Copy, Debug, EnumIter)] -pub enum Block { - Air, - Stone, - Dirt, - Grass, - Sand, -} -impl Block { - //TODO make this O(1) with compile-time computed maps - pub fn get_by_id(id: &str) -> Option { - for block in Self::iter() { - if block.descriptor().id == id { - return Some(block) - } - } - None - } - - pub const fn descriptor(self) -> BlockDescriptor { - match self { - Self::Air => BlockDescriptor { - name: "Air", - id: "air", - collision: None, - raycast_collision: false, - render: None, - item: None, - }, - Self::Stone => BlockDescriptor { - name: "Stone", - id: "stone", - collision: Some(CollisionType::Solid), - raycast_collision: true, - render: Some((RenderType::OpaqueBlock, BlockTextures::all(BlockTexture::Stone))), - item: Some(Item::StoneBlock) - }, - Self::Dirt => BlockDescriptor { - name: "Dirt", - id: "dirt", - collision: Some(CollisionType::Solid), - raycast_collision: true, - render: Some((RenderType::OpaqueBlock, BlockTextures::all(BlockTexture::Dirt))), - item: Some(Item::DirtBlock) - }, - Self::Grass => BlockDescriptor { - name: "Grass", - id: "grass", - collision: Some(CollisionType::Solid), - raycast_collision: true, - render: Some((RenderType::OpaqueBlock, BlockTextures::top_sides_bottom(BlockTexture::GrassTop, BlockTexture::GrassSide, BlockTexture::Dirt))), - item: Some(Item::DirtBlock) - }, - Self::Sand => BlockDescriptor { - name: "Sand", - id: "sand", - collision: Some(CollisionType::Solid), - raycast_collision: true, - render: Some((RenderType::OpaqueBlock, BlockTextures::all(BlockTexture::Sand))), //this is not a sand tex - item: Some(Item::StoneBlock) - } - } - } -} diff --git a/src/game/camera.rs b/src/game/camera.rs deleted file mode 100644 index 5dc2ce6..0000000 --- a/src/game/camera.rs +++ /dev/null @@ -1,157 +0,0 @@ -// Perspective/View matrix code from: -// https://glium.github.io/glium/book/tuto-10-perspective.html -// https://glium.github.io/glium/book/tuto-12-camera.html -// I don't understand anything but it works - -use std::f32::consts::PI; - -pub fn calculate_forward_direction(yaw: f32, pitch: f32) -> [f32; 3] { - [ - yaw.cos() * pitch.cos(), - pitch.sin(), - yaw.sin() * pitch.cos(), - ] -} - -fn normalize_plane(mut plane: [f32; 4]) -> [f32; 4] { - let mag = (plane[0] * plane[0] + plane[1] * plane[1] + plane[2] * plane[2]).sqrt(); - plane[0] = plane[0] / mag; - plane[1] = plane[1] / mag; - plane[2] = plane[2] / mag; - plane[3] = plane[3] / mag; - plane -} - -pub struct Camera { - pub yaw: f32, - pub pitch: f32, - pub position: [f32; 3], - pub direction: [f32; 3], - pub up: [f32; 3], - pub fov: f32, - pub znear: f32, - pub zfar: f32, - pub perspective_matrix: [[f32; 4]; 4], -} -impl Camera { - /// Update camera direction based on yaw/pitch - pub fn update_direction(&mut self) { - self.direction = calculate_forward_direction(self.yaw, self.pitch); - } - pub fn forward(&mut self, amount: f32) { - self.position[0] += self.direction[0] * amount; - self.position[1] += self.direction[1] * amount; - self.position[2] += self.direction[2] * amount; - } - - pub fn view_matrix(&self) -> [[f32; 4]; 4] { - let position = self.position; - let direction = self.direction; - let up = self.up; - - let f = { - let f = direction; - let len = f[0] * f[0] + f[1] * f[1] + f[2] * f[2]; - let len = len.sqrt(); - [f[0] / len, f[1] / len, f[2] / len] - }; - let s = [up[1] * f[2] - up[2] * f[1], - up[2] * f[0] - up[0] * f[2], - up[0] * f[1] - up[1] * f[0]]; - let s_norm = { - let len = s[0] * s[0] + s[1] * s[1] + s[2] * s[2]; - let len = len.sqrt(); - [s[0] / len, s[1] / len, s[2] / len] - }; - let u = [f[1] * s_norm[2] - f[2] * s_norm[1], - f[2] * s_norm[0] - f[0] * s_norm[2], - f[0] * s_norm[1] - f[1] * s_norm[0]]; - let p = [-position[0] * s_norm[0] - position[1] * s_norm[1] - position[2] * s_norm[2], - -position[0] * u[0] - position[1] * u[1] - position[2] * u[2], - -position[0] * f[0] - position[1] * f[1] - position[2] * f[2]]; - [ - [s_norm[0], u[0], f[0], 0.0], - [s_norm[1], u[1], f[1], 0.0], - [s_norm[2], u[2], f[2], 0.0], - [p[0], p[1], p[2], 1.0], - ] - } - - pub fn update_perspective_matrix(&mut self, target_dimensions: (u32, u32)) { - let znear = self.znear; - let zfar = self.zfar; - let fov = self.fov; - let (width, height) = target_dimensions; - let aspect_ratio = height as f32 / width as f32; - let f = 1.0 / (fov / 2.0).tan(); - self.perspective_matrix = [ - [f*aspect_ratio, 0.0, 0.0, 0.0], - [0.0, f, 0.0, 0.0], - [0.0, 0.0, (zfar+znear)/(zfar-znear), 1.0], - [0.0, 0.0, -(2.0*zfar*znear)/(zfar-znear), 0.0], - ]; - } - - // https://www.flipcode.com/archives/Frustum_Culling.shtml - // https://web.archive.org/web/20070226173353/https://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf - pub fn frustum_planes(&self, normalized: bool) -> [[f32; 4]; 6] { - let mut p_planes = [[0.0_f32; 4]; 6]; - let matrix = self.perspective_matrix; - - // Left clipping plane - p_planes[0][0] = matrix[3][0] + matrix[0][0]; - p_planes[0][1] = matrix[3][1] + matrix[0][1]; - p_planes[0][2] = matrix[3][2] + matrix[0][2]; - p_planes[0][3] = matrix[3][3] + matrix[0][3]; - // Right clipping plane - p_planes[1][0] = matrix[3][0] - matrix[0][0]; - p_planes[1][1] = matrix[3][1] - matrix[0][1]; - p_planes[1][2] = matrix[3][2] - matrix[0][2]; - p_planes[1][3] = matrix[3][3] - matrix[0][3]; - // Top clipping plane - p_planes[2][0] = matrix[3][0] - matrix[1][0]; - p_planes[2][1] = matrix[3][1] - matrix[1][1]; - p_planes[2][2] = matrix[3][2] - matrix[1][2]; - p_planes[2][3] = matrix[3][3] - matrix[1][3]; - // Bottom clipping plane - p_planes[3][0] = matrix[3][0] + matrix[1][0]; - p_planes[3][1] = matrix[3][1] + matrix[1][1]; - p_planes[3][2] = matrix[3][2] + matrix[1][2]; - p_planes[3][3] = matrix[3][3] + matrix[1][3]; - // Near clipping plane - p_planes[4][0] = matrix[3][0] + matrix[3][0]; - p_planes[4][1] = matrix[3][1] + matrix[3][1]; - p_planes[4][2] = matrix[3][2] + matrix[3][2]; - p_planes[4][3] = matrix[3][3] + matrix[3][3]; - // Far clipping plane - p_planes[5][0] = matrix[3][0] - matrix[3][0]; - p_planes[5][1] = matrix[3][1] - matrix[3][1]; - p_planes[5][2] = matrix[3][2] - matrix[3][2]; - p_planes[5][3] = matrix[3][3] - matrix[3][3]; - - //Normalize planes - if normalized { - for plane in &mut p_planes { - *plane = normalize_plane(*plane); - } - } - - p_planes - } - -} -impl Default for Camera { - fn default() -> Self { - Self { - position: [0., 0., 0.], - direction: [0., 0., 0.], - up: [0., 1., 0.], - fov: PI / 3., - zfar: 1024., - znear: 0.1, - yaw: 0., - pitch: 0., - perspective_matrix: [[0.; 4]; 4] - } - } -} diff --git a/src/game/controller.rs b/src/game/controller.rs deleted file mode 100644 index 58b5b29..0000000 --- a/src/game/controller.rs +++ /dev/null @@ -1,116 +0,0 @@ -use glium::glutin::event::{VirtualKeyCode, ElementState}; -use std::f32::consts::PI; -use crate::game::camera::Camera; - -#[derive(Default, Clone, Copy)] -pub struct InputAmounts { - move_x: (f32, f32), - move_y: (f32, f32), - move_z: (f32, f32), - look_h: f32, - look_v: f32, -} - -pub struct Actions { - pub movement: [f32; 3], - pub rotation: [f32; 2], -} -impl Actions { - pub fn apply_to_camera(&self, camera: &mut Camera) { - //Apply rotation - camera.yaw -= self.rotation[0]; - camera.pitch -= self.rotation[1]; - camera.pitch = camera.pitch.clamp(-PI/2. + f32::EPSILON, PI/2. - f32::EPSILON); - camera.update_direction(); - //Apply movement - let (yaw_sin, yaw_cos) = camera.yaw.sin_cos(); - //forward movement - camera.position[0] += yaw_cos * self.movement[2]; - camera.position[2] += yaw_sin * self.movement[2]; - //sideways movement - camera.position[0] -= -yaw_sin * self.movement[0]; - camera.position[2] -= yaw_cos * self.movement[0]; - //up/down movement - camera.position[1] += self.movement[1]; - } -} - -pub struct Controls { - inputs: InputAmounts, - pub speed: f32, - pub sensitivity: f32, -} -impl Controls { - //TODO locking controls - pub fn lock(&mut self) { - todo!() - } - pub fn unlock(&mut self) { - todo!() - } - pub fn process_mouse_input(&mut self, dx: f64, dy: f64) { - self.inputs.look_h += dx as f32; - self.inputs.look_v += dy as f32; - } - pub fn process_keyboard_input(&mut self, key: VirtualKeyCode, state: ElementState) { - let value = match state { - ElementState::Pressed => 1., - ElementState::Released => 0., - }; - match key { - VirtualKeyCode::W | VirtualKeyCode::Up => { - self.inputs.move_z.0 = value; - } - VirtualKeyCode::S | VirtualKeyCode::Down => { - self.inputs.move_z.1 = -value; - } - VirtualKeyCode::A | VirtualKeyCode::Left => { - self.inputs.move_x.0 = -value; - } - VirtualKeyCode::D | VirtualKeyCode::Right => { - self.inputs.move_x.1 = value; - } - VirtualKeyCode::Space => { - self.inputs.move_y.0 = value; - } - VirtualKeyCode::LShift => { - self.inputs.move_y.1 = -value; - } - _ => () - } - } - pub fn calculate(&mut self, dt: f32) -> Actions { - let movement = { - let move_x = self.inputs.move_x.0 + self.inputs.move_x.1; - let move_y = self.inputs.move_y.0 + self.inputs.move_y.1; - let move_z = self.inputs.move_z.0 + self.inputs.move_z.1; - let magnitude = (move_x.powi(2) + move_y.powi(2) + move_z.powi(2)).sqrt(); - if magnitude == 0. { - [0., 0., 0.] - } else { - [ - dt * self.speed * (move_x / magnitude), - dt * self.speed * (move_y / magnitude), - dt * self.speed * (move_z / magnitude) - ] - } - }; - let rotation = [ //Do mouse inputs need to be multiplied by dt? - self.inputs.look_h * self.sensitivity * 0.01, //* dt - self.inputs.look_v * self.sensitivity * 0.01 //* dt - ]; - //Only mouse related actions need to be reset - self.inputs.look_h = 0.; - self.inputs.look_v = 0.; - Actions { movement, rotation } - } -} -impl Default for Controls { - fn default() -> Self { - Self { - inputs: Default::default(), - speed: 40., - sensitivity: 1.24, - } - } -} diff --git a/src/game/display.rs b/src/game/display.rs deleted file mode 100644 index 97d7e02..0000000 --- a/src/game/display.rs +++ /dev/null @@ -1,16 +0,0 @@ -use glium::Display; -use glium::glutin::{ - ContextBuilder, - GlProfile, - window::WindowBuilder, - event_loop::EventLoop -}; - -pub fn init_display(event_loop: &EventLoop<()>) -> Display { - let wb = WindowBuilder::new() - .with_maximized(true); - let cb = ContextBuilder::new() - .with_depth_buffer(24) - .with_gl_profile(GlProfile::Core); - Display::new(wb, cb, event_loop).unwrap() -} diff --git a/src/game/items.rs b/src/game/items.rs deleted file mode 100644 index 0028d1c..0000000 --- a/src/game/items.rs +++ /dev/null @@ -1,9 +0,0 @@ -//TODO items - -#[derive(Clone, Copy, Debug)] -pub enum Item { - StoneBlock, - DirtBlock, - GrassBlock, - SandBlock, -} diff --git a/src/game/options.rs b/src/game/options.rs deleted file mode 100644 index 7a19998..0000000 --- a/src/game/options.rs +++ /dev/null @@ -1,13 +0,0 @@ -#[derive(Clone, Debug)] -pub struct GameOptions { - pub render_distance: u8, - pub debug_wireframe_mode: bool, -} -impl Default for GameOptions { - fn default() -> Self { - Self { - render_distance: if cfg!(debug_assertions) { 8 } else { 16 }, - debug_wireframe_mode: false, - } - } -} diff --git a/src/game/physics.rs b/src/game/physics.rs deleted file mode 100644 index a0e0d2c..0000000 --- a/src/game/physics.rs +++ /dev/null @@ -1,46 +0,0 @@ -use glam::{Vec3A, vec3a}; -use crate::game::World; - -const GRAVITY: Vec3A = vec3a(0., -1., 0.); - -pub struct BasicPhysicsActor { - pub height: f32, - pub gravity: Vec3A, - pub position: Vec3A, - pub velocity: Vec3A, -} -impl BasicPhysicsActor { - pub fn new(height: f32) -> Self { - Self { - height, - gravity: GRAVITY, - position: vec3a(0., 0., 0.), - velocity: vec3a(0., 0., 0.), - } - } - pub fn update(&mut self, world: &World, dt: f32) { - self.velocity += GRAVITY; - self.position += self.velocity; - loop { - let block_pos = self.position.floor().as_ivec3(); - let block_pos_f = block_pos.as_vec3a(); - if let Some(block) = world.try_get(block_pos) { - match block.descriptor().collision { - Some(super::blocks::CollisionType::Solid) => { - let position_delta = self.position - block_pos_f; - let distance_to_zero = position_delta.abs(); - let distance_to_one = (vec3a(1., 1., 1.) - position_delta).abs(); - - // let mut max_distance = 0; - // let mut max_distance_normal = 0; - // distance_to_one.x - //todo compute restitution here - } - _ => break - } - } else { - break - } - } - } -} diff --git a/src/game/player.rs b/src/game/player.rs deleted file mode 100644 index 8fde307..0000000 --- a/src/game/player.rs +++ /dev/null @@ -1,7 +0,0 @@ -use crate::game::camera::Camera; -use crate::game::physics::BasicPhysicsActor; - -pub struct MainPlayer { - pub camera: Camera, - pub actor: BasicPhysicsActor, -} diff --git a/src/game/shaders.rs b/src/game/shaders.rs deleted file mode 100644 index d949234..0000000 --- a/src/game/shaders.rs +++ /dev/null @@ -1,17 +0,0 @@ -use glium::{Display, Program}; - -pub mod chunk; -pub mod colored2d; - -pub struct Programs { - pub colored_2d: Program, - pub chunk: Program, -} -impl Programs { - pub fn compile_all(display: &Display) -> Self { - Self { - colored_2d: Program::from_source(display, colored2d::VERTEX_SHADER, colored2d::FRAGMENT_SHADER, None).unwrap(), - chunk: Program::from_source(display, chunk::VERTEX_SHADER, chunk::FRAGMENT_SHADER, None).unwrap(), - } - } -} diff --git a/src/game/shaders/chunk.rs b/src/game/shaders/chunk.rs deleted file mode 100644 index 03c47e6..0000000 --- a/src/game/shaders/chunk.rs +++ /dev/null @@ -1,34 +0,0 @@ -use glium::implement_vertex; - -#[derive(Clone, Copy)] -pub struct Vertex { - pub position: [f32; 3], - pub normal: [f32; 3], - pub uv: [f32; 2], - pub tex_index: u8, -} -implement_vertex!(Vertex, position, normal, uv, tex_index); - -pub const VERTEX_SHADER: &str = include_str!("./glsl/chunk.vert"); -pub const FRAGMENT_SHADER: &str = include_str!("./glsl/chunk.frag"); - -// pub const VERTEX_SHADER: &str = r#" -// #version 150 core - -// in vec3 position; -// in vec3 normal; -// in vec2 uv; -// out vec3 v_normal; -// out vec2 v_uv; -// uniform mat4 perspective; -// uniform mat4 view; -// uniform mat4 model; - -// void main() { -// mat4 modelview = view * model; -// //v_normal = transpose(inverse(mat3(modelview))) * normal; -// v_normal = normal; -// v_uv = uv; -// gl_Position = perspective * modelview * vec4(position, 1.0); -// } -// "#; diff --git a/src/game/shaders/colored2d.rs b/src/game/shaders/colored2d.rs deleted file mode 100644 index 336dab8..0000000 --- a/src/game/shaders/colored2d.rs +++ /dev/null @@ -1,10 +0,0 @@ -use glium::implement_vertex; - -#[derive(Clone, Copy)] -pub struct Vertex { - pub position: [f32; 2] -} -implement_vertex!(Vertex, position); - -pub const VERTEX_SHADER: &str = include_str!("./glsl/colored2d.vert"); -pub const FRAGMENT_SHADER: &str = include_str!("./glsl/colored2d.frag"); diff --git a/src/game/shaders/glsl/chunk.frag b/src/game/shaders/glsl/chunk.frag deleted file mode 100644 index e07b5e1..0000000 --- a/src/game/shaders/glsl/chunk.frag +++ /dev/null @@ -1,15 +0,0 @@ -#version 150 core - -in vec3 v_normal; -in vec2 v_uv; -flat in uint v_tex_index; -out vec4 color; -uniform sampler2DArray tex; - -void main() { - // base color from texture - color = texture(tex, vec3(v_uv, v_tex_index)); - //basic "lighting" - float light = abs(v_normal.x) + .8 * abs(v_normal.y) + .6 * abs(v_normal.z); - color *= vec4(vec3(light), 1.); -} diff --git a/src/game/shaders/glsl/chunk.vert b/src/game/shaders/glsl/chunk.vert deleted file mode 100644 index 91e2b39..0000000 --- a/src/game/shaders/glsl/chunk.vert +++ /dev/null @@ -1,19 +0,0 @@ -#version 150 core - -in vec3 position; -in vec3 normal; -in vec2 uv; -in uint tex_index; -out vec2 v_uv; -out vec3 v_normal; -flat out uint v_tex_index; -uniform vec2 position_offset; -uniform mat4 perspective; -uniform mat4 view; - -void main() { - v_normal = normal; - v_tex_index = tex_index; - v_uv = uv; - gl_Position = perspective * view * (vec4(position, 1.0) + vec4(position_offset.x, 0., position_offset.y, 0.)); -} diff --git a/src/game/shaders/glsl/colored2d.frag b/src/game/shaders/glsl/colored2d.frag deleted file mode 100644 index 9b2ac94..0000000 --- a/src/game/shaders/glsl/colored2d.frag +++ /dev/null @@ -1,8 +0,0 @@ -#version 150 core - -out vec4 color; -uniform vec4 u_color; - -void main() { - color = u_color; -} diff --git a/src/game/shaders/glsl/colored2d.vert b/src/game/shaders/glsl/colored2d.vert deleted file mode 100644 index af1807e..0000000 --- a/src/game/shaders/glsl/colored2d.vert +++ /dev/null @@ -1,7 +0,0 @@ -#version 150 core - -in vec2 position; - -void main() { - gl_Position = vec4(position, 0., 1.); -} diff --git a/src/game/world.rs b/src/game/world.rs deleted file mode 100644 index de8ff50..0000000 --- a/src/game/world.rs +++ /dev/null @@ -1,201 +0,0 @@ -use glam::{Vec2, IVec2, IVec3, Vec3Swizzles}; -use glium::{ - Display, Frame, Surface, - DrawParameters, Depth, - DepthTest, PolygonMode, - uniform, - uniforms::{ - Sampler, SamplerBehavior, - MinifySamplerFilter, MagnifySamplerFilter, - } -}; -use hashbrown::HashMap; -use crate::game::{ - options::GameOptions, - shaders::Programs, - assets::Assets, - blocks::Block, -}; - -mod chunk; -mod thread; - -use chunk::{Chunk, ChunkState, CHUNK_SIZE}; -use thread::WorldThreading; - -const POSITIVE_X_NEIGHBOR: usize = 0; -const NEGATIVE_X_NEIGHBOR: usize = 1; -const POSITIVE_Z_NEIGHBOR: usize = 2; -const NEGATIVE_Z_NEIGHBOR: usize = 3; - -const MAX_TASKS: usize = 6; - -pub struct World { - pub chunks: HashMap, - pub thread: WorldThreading, -} -impl World { - pub fn chunk_neighbors(&self, position: IVec2) -> [Option<&Chunk>; 4] { - [ - self.chunks.get(&(position + IVec2::new(1, 0))), - self.chunks.get(&(position - IVec2::new(1, 0))), - self.chunks.get(&(position + IVec2::new(0, 1))), - self.chunks.get(&(position - IVec2::new(0, 1))), - ] - } - - pub fn try_get(&self, position: IVec3) -> Option { - let chunk_coord = IVec2::new(position.x, position.z) / CHUNK_SIZE as i32; - let chunk = self.chunks.get(&chunk_coord)?; - let block_data = chunk.block_data.as_ref()?; - let block_position = position - (chunk_coord * CHUNK_SIZE as i32).extend(0).xzy(); - Some( - *block_data - .get(block_position.x as usize)? - .get(block_position.y as usize)? - .get(block_position.z as usize)? - ) - } - - pub fn new() -> Self { - Self { - chunks: HashMap::new(), - thread: WorldThreading::new(), - } - } - - pub fn render( - &self, - target: &mut Frame, - programs: &Programs, - assets: &Assets, - perspective: [[f32; 4]; 4], - view: [[f32; 4]; 4], - options: &GameOptions - ) { - let sampler = SamplerBehavior { - minify_filter: MinifySamplerFilter::Linear, - magnify_filter: MagnifySamplerFilter::Nearest, - max_anisotropy: 8, - ..Default::default() - }; - let draw_parameters = DrawParameters { - depth: Depth { - test: DepthTest::IfLess, - write: true, - ..Default::default() - }, - polygon_mode: if options.debug_wireframe_mode { - PolygonMode::Line - } else { - PolygonMode::Fill - }, - backface_culling: glium::draw_parameters::BackfaceCullingMode::CullCounterClockwise, - ..Default::default() - }; - for (&position, chunk) in &self.chunks { - if let Some(mesh) = &chunk.mesh { - target.draw( - &mesh.vertex_buffer, - &mesh.index_buffer, - &programs.chunk, - &uniform! { - position_offset: (position.as_vec2() * CHUNK_SIZE as f32).to_array(), - view: view, - perspective: perspective, - tex: Sampler(&assets.textures.blocks, sampler) - }, - &draw_parameters - ).unwrap(); - } - } - } - - pub fn update_loaded_chunks(&mut self, around_position: Vec2, options: &GameOptions, display: &Display) { - let render_dist = options.render_distance as i32 + 1; - let inside_chunk = (around_position / CHUNK_SIZE as f32).as_ivec2(); - - //Mark all chunks for unload - for (_, chunk) in &mut self.chunks { - chunk.desired = ChunkState::Unload; - } - - //Load new/update chunks in range - for x in -render_dist..=render_dist { - for z in -render_dist..=render_dist { - let offset = IVec2::new(x, z); - let position = inside_chunk + offset; - if !self.chunks.contains_key(&position) { - self.chunks.insert(position, Chunk::new(position)); - } - { - //we only need mutable reference here: - let chunk = self.chunks.get_mut(&position).unwrap(); - if x == -render_dist || z == -render_dist || x == render_dist || z == render_dist { - chunk.desired = ChunkState::Loaded; - } else { - chunk.desired = ChunkState::Rendered; - } - } - let chunk = self.chunks.get(&position).unwrap(); - if self.thread.task_amount() < MAX_TASKS { - if matches!(chunk.state, ChunkState::Nothing) && matches!(chunk.desired, ChunkState::Loaded | ChunkState::Rendered) { - self.thread.queue_load(position); - self.chunks.get_mut(&position).unwrap().state = ChunkState::Loading; - } else if matches!(chunk.state, ChunkState::Loaded) && matches!(chunk.desired, ChunkState::Rendered) { - let mut state_changed = false; - fn all_some<'a>(x: [Option<&'a Chunk>; 4]) -> Option<[&'a Chunk; 4]> { - Some([x[0]?, x[1]?, x[2]?, x[3]?]) - } - if let Some(neighbors) = all_some(self.chunk_neighbors(chunk.position)) { - if { - neighbors[0].block_data.is_some() && - neighbors[1].block_data.is_some() && - neighbors[2].block_data.is_some() && - neighbors[3].block_data.is_some() - } { - self.thread.queue_mesh( - position, - chunk.block_data.clone().unwrap(), - [ - neighbors[0].block_data.clone().unwrap(), - neighbors[1].block_data.clone().unwrap(), - neighbors[2].block_data.clone().unwrap(), - neighbors[3].block_data.clone().unwrap(), - ] - ); - state_changed = true; - } - } - if state_changed { - self.chunks.get_mut(&position).unwrap().state = ChunkState::Rendering; - } - } - } - } - } - //Unloads and state downgrades - self.chunks.retain(|_, chunk| { - match chunk.desired { - // Chunk unload - ChunkState::Unload => false, - // Any => Nothing downgrade - ChunkState::Nothing => { - chunk.block_data = None; - chunk.mesh = None; - chunk.state = ChunkState::Nothing; - true - }, - //Render => Loaded downgrade - ChunkState::Loaded if matches!(chunk.state, ChunkState::Rendering | ChunkState::Rendered) => { - chunk.mesh = None; - chunk.state = ChunkState::Loaded; - true - }, - _ => true - } - }); - //Apply changes from threads - self.thread.apply_tasks(&mut self.chunks, display); - } -} diff --git a/src/game/world/chunk.rs b/src/game/world/chunk.rs deleted file mode 100644 index 481b04b..0000000 --- a/src/game/world/chunk.rs +++ /dev/null @@ -1,45 +0,0 @@ -use glam::IVec2; -use glium::{VertexBuffer, IndexBuffer}; -use crate::game::{ - blocks::Block, - shaders::chunk::Vertex as ChunkVertex -}; - -pub const CHUNK_SIZE: usize = 32; -pub const CHUNK_HEIGHT: usize = 255; - -pub enum ChunkState { - Unload, - Nothing, - Loading, - Loaded, - Rendering, - Rendered, -} - -pub type ChunkData = Box<[[[Block; CHUNK_SIZE]; CHUNK_HEIGHT]; CHUNK_SIZE]>; - -pub struct ChunkMesh { - pub is_dirty: bool, - pub vertex_buffer: VertexBuffer, - pub index_buffer: IndexBuffer, -} - -pub struct Chunk { - pub position: IVec2, - pub block_data: Option, - pub mesh: Option, - pub state: ChunkState, - pub desired: ChunkState, -} -impl Chunk { - pub fn new(position: IVec2) -> Self { - Self { - position, - block_data: None, - mesh: None, - state: ChunkState::Nothing, - desired: ChunkState::Nothing, - } - } -} diff --git a/src/game/world/thread.rs b/src/game/world/thread.rs deleted file mode 100644 index b051112..0000000 --- a/src/game/world/thread.rs +++ /dev/null @@ -1,97 +0,0 @@ -use glam::IVec2; -use glium::{Display, VertexBuffer, IndexBuffer, index::PrimitiveType}; -use std::{mem, thread::{self, JoinHandle}}; -use hashbrown::HashMap; -use super::chunk::{Chunk, ChunkData, ChunkState}; -use crate::game::{shaders::chunk::Vertex as ChunkVertex, world::chunk::ChunkMesh}; - -mod world_gen; -mod mesh_gen; - -#[derive(Default)] -pub struct WorldThreading { - //drain_filter is not stable yet so - //Options are needed here to take ownership, - //None values should never appear here! - pub load_tasks: HashMap>>, - pub mesh_tasks: HashMap, Vec)>>>, -} -impl WorldThreading { - pub fn new() -> Self { - Self::default() - } - pub fn is_done(&self) -> bool { - self.load_tasks.is_empty() && - self.mesh_tasks.is_empty() - } - pub fn task_amount(&self) -> usize { - self.load_tasks.len() + self.mesh_tasks.len() - } - pub fn queue_load(&mut self, position: IVec2) { - let handle = thread::spawn(move || { - world_gen::generate_chunk(position, 0xdead_cafe) - }); - if self.load_tasks.insert(position, Some(handle)).is_some() { - log::warn!("load: discarded {}, reason: new task started", position); - } - } - pub fn queue_mesh(&mut self, position: IVec2, chunk: ChunkData, neighbor_data: [ChunkData; 4]) { - let handle = thread::spawn(move || { - mesh_gen::generate_mesh(position, chunk, neighbor_data) - }); - if self.mesh_tasks.insert(position, Some(handle)).is_some() { - log::warn!("mesh: discarded {}, reason: new task started", position); - } - } - pub fn apply_tasks(&mut self, chunks: &mut HashMap, display: &Display) { - //LOAD TASKS - self.load_tasks.retain(|position, handle| { - if !chunks.contains_key(position) { - log::warn!("load: discarded {}, reason: chunk no longer exists", position); - return false - } - if !matches!(chunks.get(position).unwrap().desired, ChunkState::Loaded | ChunkState::Rendered) { - log::warn!("load: discarded {}, reason: state undesired", position); - return false - } - if !handle.as_ref().expect("Something went terribly wrong").is_finished() { - //task not finished yet, keep it and wait - return true - } - log::info!("load: done {}", position); - let handle = mem::take(handle).unwrap(); - let data = handle.join().unwrap(); - let chunk = chunks.get_mut(position).unwrap(); - chunk.block_data = Some(data); - chunk.state = ChunkState::Loaded; - false - }); - //MESH TASKS - self.mesh_tasks.retain(|position, handle| { - if !chunks.contains_key(position) { - log::warn!("mesh: discarded {}, reason: chunk no longer exists", position); - return false - } - if !matches!(chunks.get(position).unwrap().desired, ChunkState::Rendered) { - log::warn!("mesh: discarded {}, reason: state undesired", position); - return false - } - if !handle.as_ref().expect("Something went terribly wrong").is_finished() { - //task not finished yet, keep it and wait - return true - } - log::info!("mesh: done {}", position); - let handle = mem::take(handle).unwrap(); - let (shape, index) = handle.join().unwrap(); - let chunk = chunks.get_mut(position).unwrap(); - chunk.mesh = Some(ChunkMesh { - is_dirty: false, - vertex_buffer: VertexBuffer::new(display, &shape).expect("Failed to build VertexBuffer"), - index_buffer: IndexBuffer::new(display, PrimitiveType::TrianglesList, &index).expect("Failed to build IndexBuffer") - }); - chunk.state = ChunkState::Rendered; - false - }); - - } -} diff --git a/src/game/world/thread/mesh_gen.rs b/src/game/world/thread/mesh_gen.rs deleted file mode 100644 index ad32b11..0000000 --- a/src/game/world/thread/mesh_gen.rs +++ /dev/null @@ -1,139 +0,0 @@ -use glam::{IVec2, IVec3, Vec2, Vec3A, vec3a, vec2, ivec3}; -use strum::{EnumIter, IntoEnumIterator}; -use crate::game::{ - world::{ - POSITIVE_X_NEIGHBOR, - NEGATIVE_X_NEIGHBOR, - POSITIVE_Z_NEIGHBOR, - NEGATIVE_Z_NEIGHBOR, - chunk::{ChunkData, CHUNK_SIZE, CHUNK_HEIGHT} - }, - shaders::chunk::Vertex, - blocks::Block -}; - -#[repr(usize)] -#[derive(Clone, Copy, Debug, EnumIter)] -pub enum CubeFace { - Top = 0, - Front = 1, - Left = 2, - Right = 3, - Back = 4, - Bottom = 5, -} -const CUBE_FACE_VERTICES: [[Vec3A; 4]; 6] = [ - [vec3a(0., 1., 0.), vec3a(0., 1., 1.), vec3a(1., 1., 0.), vec3a(1., 1., 1.)], - [vec3a(0., 0., 0.), vec3a(0., 1., 0.), vec3a(1., 0., 0.), vec3a(1., 1., 0.)], - [vec3a(0., 0., 1.), vec3a(0., 1., 1.), vec3a(0., 0., 0.), vec3a(0., 1., 0.)], - [vec3a(1., 0., 0.), vec3a(1., 1., 0.), vec3a(1., 0., 1.), vec3a(1., 1., 1.)], - [vec3a(1., 0., 1.), vec3a(1., 1., 1.), vec3a(0., 0., 1.), vec3a(0., 1., 1.)], - [vec3a(0., 0., 1.), vec3a(0., 0., 0.), vec3a(1., 0., 1.), vec3a(1., 0., 0.)], -]; -const CUBE_FACE_NORMALS: [[f32; 3]; 6] = [ - [0., 1., 0.], - [0., 0., -1.], - [-1., 0., 0.], - [1., 0., 0.], - [0., 0., 1.], - [0., -1., 0.] -]; -const CUBE_FACE_INDICES: [u32; 6] = [0, 1, 2, 2, 1, 3]; -const UV_COORDS: [[f32; 2]; 4] = [ - [0., 0.], - [0., 1.], - [1., 0.], - [1., 1.], -]; - - -#[derive(Default)] -struct MeshBuilder { - vertex_buffer: Vec, - index_buffer: Vec, - idx_counter: u32, -} -impl MeshBuilder { - pub fn new() -> Self { - Self::default() - } - - pub fn add_face(&mut self, face: CubeFace, coord: IVec3, texture: u8) { - let coord = coord.as_vec3a(); - let face_index = face as usize; - - //Push vertexes - let norm = CUBE_FACE_NORMALS[face_index]; - let vert = CUBE_FACE_VERTICES[face_index]; - self.vertex_buffer.reserve(4); - for i in 0..4 { - self.vertex_buffer.push(Vertex { - position: (coord + vert[i]).to_array(), - normal: norm, - uv: UV_COORDS[i], - tex_index: texture - }); - } - - //Push indices - self.index_buffer.extend_from_slice(&CUBE_FACE_INDICES.map(|x| x + self.idx_counter)); - self.idx_counter += 4; - } - - pub fn finish(self) -> (Vec, Vec) { - (self.vertex_buffer, self.index_buffer) - } -} - -pub fn generate_mesh(position: IVec2, chunk_data: ChunkData, neighbors: [ChunkData; 4]) -> (Vec, Vec) { - let get_block = |pos: IVec3| -> Block { - if pos.x < 0 { - neighbors[NEGATIVE_X_NEIGHBOR][(CHUNK_SIZE as i32 + pos.x) as usize][pos.y as usize][pos.z as usize] - } else if pos.x >= CHUNK_SIZE as i32 { - neighbors[POSITIVE_X_NEIGHBOR][pos.x as usize - CHUNK_SIZE as usize][pos.y as usize][pos.z as usize] - } else if pos.z < 0 { - neighbors[NEGATIVE_Z_NEIGHBOR][pos.x as usize][pos.y as usize][(CHUNK_SIZE as i32 + pos.z) as usize] - } else if pos.z >= CHUNK_SIZE as i32 { - neighbors[POSITIVE_Z_NEIGHBOR][pos.x as usize][pos.y as usize][pos.z as usize - CHUNK_SIZE as usize] - } else { - chunk_data[pos.x as usize][pos.y as usize][pos.z as usize] - } - }; - - let mut builer = MeshBuilder::new(); - - for x in 0..CHUNK_SIZE { - for y in 0..CHUNK_HEIGHT { - for z in 0..CHUNK_SIZE { - let coord = ivec3(x as i32, y as i32, z as i32); - let descriptor = get_block(coord).descriptor(); - if descriptor.render.is_none() { - continue - } - for face in CubeFace::iter() { - let facing = Vec3A::from_array(CUBE_FACE_NORMALS[face as usize]).as_ivec3(); - let facing_coord = coord + facing; - let show = { - (facing_coord.y < 0) || - (facing_coord.y >= CHUNK_HEIGHT as i32) || - get_block(facing_coord).descriptor().render.is_none() - }; - if show { - let texures = descriptor.render.unwrap().1; - let block_texture = match face { - CubeFace::Top => texures.top, - CubeFace::Front => texures.front, - CubeFace::Left => texures.left, - CubeFace::Right => texures.right, - CubeFace::Back => texures.back, - CubeFace::Bottom => texures.bottom, - }; - builer.add_face(face, coord, block_texture as u8); - } - } - } - } - } - - builer.finish() -} diff --git a/src/game/world/thread/world_gen.rs b/src/game/world/thread/world_gen.rs deleted file mode 100644 index 34b979b..0000000 --- a/src/game/world/thread/world_gen.rs +++ /dev/null @@ -1,58 +0,0 @@ -use glam::{Vec2, DVec2, IVec2}; -use noise::{NoiseFn, Perlin, Simplex, Fbm, Seedable}; -use crate::game::{ - world::chunk::{ChunkData, CHUNK_SIZE, CHUNK_HEIGHT}, - blocks::Block -}; - -const HEIGHTMAP_SCALE: f64 = 0.004; -const MOUNTAINESS_SCALE: f64 = 0.0001; -const MNT_RAMP_1: f64 = 0.5; -const MNT_RAMP_2: f64 = 0.6; -const MTN_VAL_SCALE: f64 = 1.233; -const TERRAIN_HEIGHT_MIN: f64 = 60.; -const TERRAIN_HEIGHT_MAX: f64 = 80.; - -pub fn generate_chunk(position: IVec2, seed: u32) -> ChunkData { - let world_xz = position.as_vec2() * CHUNK_SIZE as f32; - let mut chunk = Box::new([[[Block::Air; CHUNK_SIZE]; CHUNK_HEIGHT]; CHUNK_SIZE]); - - //generate noises - let mut terrain_base_fbm: Fbm = Fbm::new(seed); - terrain_base_fbm.octaves = 6; - - let mut mountainess_base_fbm: Fbm = Fbm::new(seed); - mountainess_base_fbm.octaves = 4; - - //put everything together - for x in 0..CHUNK_SIZE { - for z in 0..CHUNK_SIZE { - let point = world_xz.as_dvec2() + DVec2::from_array([x as f64, z as f64]); - - let heightmap = (terrain_base_fbm.get((point * HEIGHTMAP_SCALE).to_array()) + 1.) / 2.; - let mountainess = MTN_VAL_SCALE * ((mountainess_base_fbm.get((point * MOUNTAINESS_SCALE).to_array()) + 1.) / 2.); - - //generate basic terrain - let terain_height = - ( - TERRAIN_HEIGHT_MIN + - (heightmap * TERRAIN_HEIGHT_MAX * (0.1 + 1.5 * if mountainess < MNT_RAMP_1 { - 0. - } else { - if mountainess > MNT_RAMP_2 { - 1. - } else { - (mountainess - MNT_RAMP_1) / (MNT_RAMP_2 - MNT_RAMP_1) * 1. - } - })) - ).floor() as usize; - for y in 0..terain_height { - chunk[x][y][z] = Block::Dirt; - } - chunk[x][terain_height][z] = Block::Grass; - } - } - - //return generated world - chunk -} diff --git a/src/logging.rs b/src/logging.rs deleted file mode 100644 index 013b4e9..0000000 --- a/src/logging.rs +++ /dev/null @@ -1,45 +0,0 @@ -//! Custom env_logger options and styling - -use env_logger::{fmt::Color, Builder, Env}; -use log::Level; -use std::io::Write; - -pub fn init() { - let mut env = Env::default(); - if cfg!(debug_assertions) { - env = env.filter_or("RUST_LOG", "trace"); - } - Builder::from_env(env) - .format(|buf, record| { - let mut level_style = buf.style(); - level_style.set_color(match record.level() { - Level::Error => Color::Red, - Level::Warn => Color::Yellow, - _ => Color::Blue - }).set_bold(true); - - let mut location_style = buf.style(); - location_style.set_bold(true); - location_style.set_dimmed(true); - - let mut location_line_style = buf.style(); - location_line_style.set_dimmed(true); - - writeln!( - buf, - "{} {:<50}\t{}{}{}", - level_style.value(match record.level() { - Level::Error => "[e]", - Level::Warn => "[w]", - Level::Info => "[i]", - Level::Debug => "[d]", - Level::Trace => "[t]", - }), - format!("{}", record.args()), - location_style.value(record.target()), - location_line_style.value(" :"), - location_line_style.value(record.line().unwrap_or(0)) - ) - }) - .init(); -} diff --git a/src/main.rs b/src/main.rs index 08de79c..58dfaaa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,3 @@ -mod game; -mod logging; - fn main() { - logging::init(); - game::run(); + }