This commit is contained in:
griffi-gh 2024-04-25 13:39:23 +02:00
parent ee6a5dd2f9
commit 09af18dda0
4 changed files with 149 additions and 49 deletions

View file

@ -1,48 +1,49 @@
use glam::{Vec3, Mat4};
use shipyard::{ViewMut, View, IntoIter, Workload, IntoWorkload, track, UniqueView, SystemModificator};
use crate::{transform::Transform, rendering::WindowSize, events::WindowResizedEvent};
use super::Camera;
//maybe parallelize these two?
fn update_view_matrix(
mut vm_camera: ViewMut<Camera>,
v_transform: View<Transform, track::All>
) {
for (mut camera, transform) in (&mut vm_camera, v_transform.inserted_or_modified()).iter() {
let (_, rotation, translation) = transform.0.to_scale_rotation_translation();
let direction = (rotation.normalize() * Vec3::NEG_Z).normalize();
camera.view_matrix = Mat4::look_to_rh(translation, direction, camera.up);
}
}
fn update_perspective_matrix(
mut vm_camera: ViewMut<Camera>,
size: UniqueView<WindowSize>,
) {
for mut camera in (&mut vm_camera).iter() {
camera.perspective_matrix = Mat4::perspective_rh_gl(
camera.fov,
size.0.x as f32 / size.0.y as f32,
camera.z_near,
camera.z_far,
)
}
}
fn need_perspective_calc(
v_camera: View<Camera>,
resize_event: View<WindowResizedEvent>,
) -> bool {
(resize_event.len() > 0) ||
(v_camera.iter().any(|camera| {
camera.perspective_matrix == Mat4::default()
}))
}
pub fn update_matrices() -> Workload {
(
update_view_matrix,
update_perspective_matrix.run_if(need_perspective_calc),
).into_sequential_workload()
}
use glam::{Vec3, Mat4};
use shipyard::{ViewMut, View, IntoIter, Workload, IntoWorkload, track, UniqueView, SystemModificator};
use crate::{transform::Transform, rendering::WindowSize, events::WindowResizedEvent};
use super::Camera;
//maybe parallelize these two?
fn update_view_matrix(
mut vm_camera: ViewMut<Camera>,
v_transform: View<Transform, track::All>
) {
for (mut camera, transform) in (&mut vm_camera, v_transform.inserted_or_modified()).iter() {
let (_, rotation, translation) = transform.0.to_scale_rotation_translation();
let direction = (rotation.normalize() * Vec3::NEG_Z).normalize();
camera.view_matrix = Mat4::look_to_rh(translation, direction, camera.up);
}
}
fn update_perspective_matrix(
mut vm_camera: ViewMut<Camera>,
size: UniqueView<WindowSize>,
) {
for mut camera in (&mut vm_camera).iter() {
camera.perspective_matrix = Mat4::perspective_rh_gl(
camera.fov,
size.0.x as f32 / size.0.y as f32,
camera.z_near,
camera.z_far,
)
}
}
fn need_perspective_calc(
v_camera: View<Camera>,
resize_event: View<WindowResizedEvent>,
) -> bool {
(resize_event.len() > 0) ||
(v_camera.iter().any(|camera| {
camera.perspective_matrix == Mat4::default()
}))
}
pub fn update_matrices() -> Workload {
(
update_view_matrix,
//update_perspective_matrix,
update_perspective_matrix.run_if(need_perspective_calc),
).into_sequential_workload()
}

54
kubi/src/chat.rs Normal file
View file

@ -0,0 +1,54 @@
use shipyard::{AllStoragesView, Unique, UniqueViewMut};
pub enum ChatMessage {
PlayerMessage {
username: String,
message: String,
},
PlayerJoin {
username: String,
},
PlayerLeave {
username: String,
},
System(String),
}
#[derive(Unique, Default)]
pub struct ChatManager {
pub messages: Vec<ChatMessage>,
}
impl ChatManager {
pub fn add_message(&mut self, message: ChatMessage) {
self.messages.push(message);
}
pub fn add_chat_message(&mut self, username: String, message: String,) {
self.messages.push(ChatMessage::PlayerMessage { username, message });
}
pub fn add_player_join(&mut self, username: String) {
self.messages.push(ChatMessage::PlayerJoin { username });
}
pub fn add_player_leave(&mut self, username: String) {
self.messages.push(ChatMessage::PlayerLeave { username });
}
pub fn add_system_message(&mut self, message: String) {
self.messages.push(ChatMessage::System(message));
}
pub fn get_messages(&self) -> &[ChatMessage] {
&self.messages[..]
}
}
pub fn init_chat_manager(
storages: AllStoragesView,
) {
let mut chat_manager = ChatManager::default();
chat_manager.add_system_message("Welcome to Kubi!".to_string());
storages.add_unique(chat_manager);
}

View file

@ -18,8 +18,9 @@ pub(crate) use kubi_shared::transform;
mod ui {
pub(crate) mod loading_screen;
pub(crate) mod connecting_screen;
pub(crate) mod chat_ui;
}
pub(crate) use ui::{loading_screen, connecting_screen};
pub(crate) use ui::{loading_screen, connecting_screen, chat_ui};
pub(crate) mod rendering;
pub(crate) mod world;
@ -42,6 +43,7 @@ pub(crate) mod color;
pub(crate) mod fixed_timestamp;
pub(crate) mod filesystem;
pub(crate) mod client_physics;
pub(crate) mod chat;
use world::{
init_game_world,
@ -87,6 +89,8 @@ use connecting_screen::update_connecting_screen;
use fixed_timestamp::init_fixed_timestamp_storage;
use filesystem::AssetManager;
use client_physics::{init_client_physics, update_client_physics_late};
use chat_ui::render_chat;
use chat::init_chat_manager;
/// stuff required to init the renderer and other basic systems
fn pre_startup() -> Workload {
@ -111,6 +115,7 @@ fn startup() -> Workload {
insert_control_flow_unique,
init_delta_time,
init_client_physics,
init_chat_manager,
).into_sequential_workload()
}
@ -144,6 +149,7 @@ fn update() -> Workload {
update_raycasts,
update_block_placement,
apply_queued_blocks,
render_chat,
).into_sequential_workload().run_if(is_ingame),
update_networking_late.run_if(is_multiplayer),
compute_cameras,

39
kubi/src/ui/chat_ui.rs Normal file
View file

@ -0,0 +1,39 @@
use hui::{element::{container::Container, text::Text, UiElementExt}, layout::Alignment, size};
use shipyard::{NonSendSync, UniqueView, UniqueViewMut};
use crate::{chat::{ChatManager, ChatMessage}, hui_integration::UiState, rendering::WindowSize};
pub fn render_chat(
mut hui: NonSendSync<UniqueViewMut<UiState>>,
size: UniqueView<WindowSize>,
chat: UniqueView<ChatManager>,
) {
let messages = chat.get_messages();
if messages.is_empty() { return }
Container::default()
.with_size(size!(100%, 100%))
.with_align((Alignment::Begin, Alignment::End))
.with_children(|ui| {
for message in messages.iter().rev().take(10).rev() {
let text = match message {
ChatMessage::PlayerMessage { username, message } => {
format!("{}: {}", username, message)
}
ChatMessage::PlayerJoin { username } => {
format!("{} joined the game", username)
}
ChatMessage::PlayerLeave { username } => {
format!("{} left the game", username)
}
ChatMessage::System(message) => message.clone(),
};
Container::default()
.with_background((0., 0., 0., 0.5))
.with_children(|ui| {
Text::new(text)
.add_child(ui)
})
.add_child(ui);
}
})
.add_root(&mut hui.hui, size.0.as_vec2());
}