diff --git a/src/camera.rs b/src/camera.rs index e69de29..3efa0f6 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -0,0 +1,47 @@ +use glam::{Mat4, Vec3, Vec3A}; +use shipyard::{Component, ViewMut, View, IntoIter, Workload, IntoWorkload}; +use crate::transform::Transform; + +#[derive(Component)] +pub struct Camera { + pub view_matrix: Mat4, + pub perspective_matrix: Mat4, + pub up: Vec3, + pub fov: f32, + pub z_near: f32, + pub z_far: f32, +} + +pub fn compute_cameras() -> Workload { + ( + update_perspective_matrix, + update_view_matrix, + ).into_workload() +} + +fn update_view_matrix( + mut vm_camera: ViewMut, + v_transform: View +) { + for (camera, transform) in (&mut vm_camera, v_transform.inserted_or_modified()).iter() { + let (_, rotation, translation) = transform.0.to_scale_rotation_translation(); + let dir = rotation * Vec3::Z; //this may be incorrect! + camera.view_matrix = Mat4::look_to_rh(translation, dir, camera.up); + } +} + +fn update_perspective_matrix( + mut vm_camera: ViewMut, + v_transform: View +) { + //todo compute this on win resize! + const ASPECT_RATIO: f32 = 9. / 16.; + for (camera, transform) in (&mut vm_camera, &v_transform).iter() { + camera.perspective_matrix = Mat4::perspective_rh_gl( + camera.fov, + ASPECT_RATIO, + camera.z_near, + camera.z_far, + ) + } +} diff --git a/src/main.rs b/src/main.rs index daf797d..97232f8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,17 +15,20 @@ use std::time::{Instant, Duration}; mod logging; pub(crate) mod rendering; -pub(crate) mod player; pub(crate) mod world; +pub(crate) mod player; pub(crate) mod prefabs; pub(crate) mod transform; pub(crate) mod settings; +pub(crate) mod state; +pub(crate) mod camera; use rendering::{Renderer, RenderTarget, BackgroundColor, clear_background}; +use world::{ChunkStorage, ChunkMeshStorage, loading::update_loaded_world_around_player}; use player::spawn_player; -use world::{ChunkStorage, ChunkMeshStorage, loading::load_world_around_player}; use prefabs::load_prefabs; use settings::GameSettings; +use camera::compute_cameras; #[derive(Unique)] pub(crate) struct DeltaTime(Duration); @@ -37,13 +40,14 @@ fn startup() -> Workload { } fn update() -> Workload { ( - load_world_around_player + update_loaded_world_around_player, + compute_cameras, ).into_workload() } fn render() -> Workload { ( clear_background, - ).into_workload() + ).into_sequential_workload() } fn main() { @@ -57,8 +61,8 @@ fn main() { //Add systems and uniques, Init and load things world.add_unique_non_send_sync(Renderer::init(&event_loop)); - world.add_unique(ChunkStorage::new()); world.add_unique_non_send_sync(ChunkMeshStorage::new()); + world.add_unique(ChunkStorage::new()); world.add_unique(BackgroundColor(vec3(0.5, 0.5, 1.))); world.add_unique(DeltaTime(Duration::default())); world.add_unique(GameSettings::default()); diff --git a/src/state.rs b/src/state.rs new file mode 100644 index 0000000..6e1f9a7 --- /dev/null +++ b/src/state.rs @@ -0,0 +1,6 @@ +pub enum GameState { + MainMenu, + Connecting, + LoadingWorld, + InGame +} diff --git a/src/world/loading.rs b/src/world/loading.rs index 27c20cd..dab53df 100644 --- a/src/world/loading.rs +++ b/src/world/loading.rs @@ -3,7 +3,7 @@ use shipyard::{View, UniqueView, UniqueViewMut, IntoIter, Workload, IntoWorkload use crate::{player::LocalPlayer, transform::Transform, settings::GameSettings}; use super::{ChunkStorage, chunk::{Chunk, ChunkState, CHUNK_SIZE}, ChunkMeshStorage}; -pub fn load_world_around_player() -> Workload { +pub fn update_loaded_world_around_player() -> Workload { ( update_chunks_if_player_moved, unload_marked_chunks @@ -16,7 +16,8 @@ pub fn update_chunks_if_player_moved( v_transform: View, mut vm_world: UniqueViewMut, ) { - //Check if the player actually moved + //Check if the player actually moved + //TODO fix this also triggers on rotation, only activate when the player crosses the chnk border let Some((_, transform)) = (&v_local_player, v_transform.inserted_or_modified()).iter().next() else { return }; @@ -81,3 +82,9 @@ fn unload_marked_chunks( } }) } + +fn process_tasks( + +) { + +}