mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-11-28 01:38:41 -06:00
player position sync, refactor some stuff
This commit is contained in:
parent
73940d61ff
commit
75c6d127b7
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -954,6 +954,7 @@ dependencies = [
|
||||||
"rayon",
|
"rayon",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"shipyard",
|
"shipyard",
|
||||||
|
"static_assertions",
|
||||||
"strum",
|
"strum",
|
||||||
"uflow",
|
"uflow",
|
||||||
"winapi",
|
"winapi",
|
||||||
|
|
|
@ -12,6 +12,9 @@ opt-level = 1
|
||||||
[profile.dev.package."*"]
|
[profile.dev.package."*"]
|
||||||
opt-level = 1
|
opt-level = 1
|
||||||
|
|
||||||
|
[profile.dev.package.uflow]
|
||||||
|
opt-level = 3
|
||||||
|
|
||||||
[profile.dev.package.glium]
|
[profile.dev.package.glium]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ publish = false
|
||||||
kubi-shared = { path = "../kubi-shared" }
|
kubi-shared = { path = "../kubi-shared" }
|
||||||
kubi-logging = { path = "../kubi-logging" }
|
kubi-logging = { path = "../kubi-logging" }
|
||||||
log = "*"
|
log = "*"
|
||||||
shipyard = { git = "https://github.com/leudz/shipyard", rev = "a4f4d27edcf", features = ["thread_local"] }
|
shipyard = { git = "https://github.com/leudz/shipyard", rev = "a4f4d27edcf", default-features = false, features = ["std", "proc", "thread_local"] }
|
||||||
serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] }
|
serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] }
|
||||||
toml = "0.7"
|
toml = "0.7"
|
||||||
glam = { version = "0.23", features = ["debug-glam-assert", "fast-math"] }
|
glam = { version = "0.23", features = ["debug-glam-assert", "fast-math"] }
|
||||||
|
@ -23,6 +23,7 @@ postcard = { version = "1.0", features = ["alloc"] }
|
||||||
lz4_flex = { version = "0.10", default-features = false, features = ["std", "checked-decode"] }
|
lz4_flex = { version = "0.10", default-features = false, features = ["std", "checked-decode"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = ["parallel"]
|
||||||
|
parallel = ["shipyard/parallel"]
|
||||||
safe_lz4 = ["lz4_flex/safe-encode", "lz4_flex/safe-decode"]
|
safe_lz4 = ["lz4_flex/safe-encode", "lz4_flex/safe-decode"]
|
||||||
nightly = ["hashbrown/nightly", "rand/nightly", "rand/simd_support", "glam/core-simd", "kubi-shared/nightly"]
|
nightly = ["hashbrown/nightly", "rand/nightly", "rand/simd_support", "glam/core-simd", "kubi-shared/nightly"]
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
use glam::Mat4;
|
use glam::Mat4;
|
||||||
use shipyard::{Component, EntityId, Unique, AllStoragesView, UniqueView, NonSendSync, View, ViewMut, Get};
|
use shipyard::{Component, EntityId, Unique, AllStoragesView, UniqueView, NonSendSync, View, ViewMut, Get, IntoIter};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
use uflow::SendMode;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use kubi_shared::{
|
use kubi_shared::{
|
||||||
networking::{
|
networking::{
|
||||||
client::{ClientIdMap, Client},
|
client::{ClientIdMap, Client},
|
||||||
messages::{ClientToServerMessage, C_POSITION_CHANGED}
|
messages::{ClientToServerMessage, ServerToClientMessage, C_POSITION_CHANGED},
|
||||||
|
channels::CHANNEL_MOVE
|
||||||
},
|
},
|
||||||
transform::Transform
|
transform::Transform
|
||||||
};
|
};
|
||||||
|
@ -35,7 +37,8 @@ pub fn sync_client_positions(
|
||||||
events: UniqueView<ServerEvents>,
|
events: UniqueView<ServerEvents>,
|
||||||
addr_map: UniqueView<ClientAddressMap>,
|
addr_map: UniqueView<ClientAddressMap>,
|
||||||
clients: View<Client>,
|
clients: View<Client>,
|
||||||
mut transforms: ViewMut<Transform>
|
mut transforms: ViewMut<Transform>,
|
||||||
|
addrs: View<ClientAddress>,
|
||||||
) {
|
) {
|
||||||
for event in &events.0 {
|
for event in &events.0 {
|
||||||
let Some(message) = check_message_auth::<C_POSITION_CHANGED>(&server, event, &clients, &addr_map) else {
|
let Some(message) = check_message_auth::<C_POSITION_CHANGED>(&server, event, &clients, &addr_map) else {
|
||||||
|
@ -44,9 +47,34 @@ pub fn sync_client_positions(
|
||||||
let ClientToServerMessage::PositionChanged { position, velocity: _, direction } = message.message else {
|
let ClientToServerMessage::PositionChanged { position, velocity: _, direction } = message.message else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
//Apply position to client
|
|
||||||
|
//log movement (annoying duh)
|
||||||
|
log::debug!("dbg: player moved id: {} coords: {} quat: {}", message.client_id, position, direction);
|
||||||
|
|
||||||
|
//Apply position to server-side client
|
||||||
let mut trans = (&mut transforms).get(message.entity_id).unwrap();
|
let mut trans = (&mut transforms).get(message.entity_id).unwrap();
|
||||||
trans.0 = Mat4::from_rotation_translation(direction, position);
|
trans.0 = Mat4::from_rotation_translation(direction, position);
|
||||||
|
|
||||||
|
//Transmit the change to other players
|
||||||
|
for (other_client, other_client_address) in (&clients, &addrs).iter() {
|
||||||
|
if other_client.0 == message.client_id {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
let Some(client) = server.0.client(&other_client_address.0) else {
|
||||||
|
log::error!("Client with address not found");
|
||||||
|
continue
|
||||||
|
};
|
||||||
|
client.borrow_mut().send(
|
||||||
|
postcard::to_allocvec(
|
||||||
|
&ServerToClientMessage::PlayerPositionChanged {
|
||||||
|
client_id: message.client_id,
|
||||||
|
position,
|
||||||
|
direction
|
||||||
|
}
|
||||||
|
).unwrap().into_boxed_slice(),
|
||||||
|
CHANNEL_MOVE,
|
||||||
|
SendMode::Reliable
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ mod auth;
|
||||||
|
|
||||||
use config::read_config;
|
use config::read_config;
|
||||||
use server::{bind_server, update_server, log_server_errors};
|
use server::{bind_server, update_server, log_server_errors};
|
||||||
use client::init_client_maps;
|
use client::{init_client_maps, sync_client_positions};
|
||||||
use auth::authenticate_players;
|
use auth::authenticate_players;
|
||||||
use world::{update_world, init_world};
|
use world::{update_world, init_world};
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ fn update() -> Workload {
|
||||||
log_server_errors,
|
log_server_errors,
|
||||||
authenticate_players,
|
authenticate_players,
|
||||||
update_world,
|
update_world,
|
||||||
|
sync_client_positions,
|
||||||
).into_workload()
|
).into_workload()
|
||||||
).into_sequential_workload()
|
).into_sequential_workload()
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ pub fn bind_server(
|
||||||
endpoint_config: EndpointConfig {
|
endpoint_config: EndpointConfig {
|
||||||
active_timeout_ms: config.server.timeout_ms,
|
active_timeout_ms: config.server.timeout_ms,
|
||||||
keepalive: true,
|
keepalive: true,
|
||||||
keepalive_interval_ms: 1000,
|
keepalive_interval_ms: 300,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
|
@ -23,6 +23,7 @@ uflow = "0.7"
|
||||||
postcard = { version = "1.0", features = ["alloc"] }
|
postcard = { version = "1.0", features = ["alloc"] }
|
||||||
serde_json = { version = "1.0", optional = true }
|
serde_json = { version = "1.0", optional = true }
|
||||||
lz4_flex = { version = "0.10", default-features = false, features = ["std", "checked-decode"] }
|
lz4_flex = { version = "0.10", default-features = false, features = ["std", "checked-decode"] }
|
||||||
|
static_assertions = "1.1"
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
winapi = { version = "0.3" }
|
winapi = { version = "0.3" }
|
||||||
|
@ -32,4 +33,4 @@ default = []
|
||||||
generate_visualizer_data = ["serde_json", "shipyard/serde1"]
|
generate_visualizer_data = ["serde_json", "shipyard/serde1"]
|
||||||
safe_lz4 = ["lz4_flex/safe-encode", "lz4_flex/safe-decode"]
|
safe_lz4 = ["lz4_flex/safe-encode", "lz4_flex/safe-decode"]
|
||||||
parallel = ["shipyard/parallel"]
|
parallel = ["shipyard/parallel"]
|
||||||
nightly = ["hashbrown/nightly", "glam/core-simd", "kubi-shared/nightly"]
|
nightly = ["hashbrown/nightly", "glam/core-simd", "static_assertions/nightly", "kubi-shared/nightly"]
|
||||||
|
|
|
@ -6,5 +6,7 @@ out vec4 out_color;
|
||||||
uniform vec4 color;
|
uniform vec4 color;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
// discard fully transparent pixels
|
||||||
|
if (color.w <= 0.) discard;
|
||||||
out_color = color;
|
out_color = color;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
#version 300 es
|
|
||||||
|
|
||||||
precision highp float;
|
|
||||||
|
|
||||||
out vec4 color;
|
|
||||||
uniform vec4 u_color;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
color = u_color;
|
|
||||||
// color -= vec4(0, 0, 0, 0.1 * sin(gl_FragCoord.x) * cos(gl_FragCoord.y));
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
#version 300 es
|
|
||||||
|
|
||||||
precision highp float;
|
|
||||||
|
|
||||||
in vec3 position;
|
|
||||||
uniform ivec3 u_position;
|
|
||||||
uniform mat4 perspective;
|
|
||||||
uniform mat4 view;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = perspective * view * vec4(position + vec3(u_position), 1.);
|
|
||||||
}
|
|
|
@ -19,20 +19,8 @@ uniform sampler2DArray tex;
|
||||||
void main() {
|
void main() {
|
||||||
// base color from texture
|
// base color from texture
|
||||||
color = texture(tex, vec3(v_uv, v_tex_index));
|
color = texture(tex, vec3(v_uv, v_tex_index));
|
||||||
// HACKY texture "antialiasing"
|
|
||||||
// color += (
|
|
||||||
// alpha_drop(color, texture(tex, vec3(v_uv + vec2(.000, .001), v_tex_index))) +
|
|
||||||
// alpha_drop(color, texture(tex, vec3(v_uv + vec2(.001, .000), v_tex_index))) +
|
|
||||||
// alpha_drop(color, texture(tex, vec3(v_uv + vec2(.001, .001), v_tex_index))) +
|
|
||||||
// alpha_drop(color, texture(tex, vec3(v_uv - vec2(.000, .001), v_tex_index))) +
|
|
||||||
// alpha_drop(color, texture(tex, vec3(v_uv - vec2(.001, .000), v_tex_index))) +
|
|
||||||
// alpha_drop(color, texture(tex, vec3(v_uv - vec2(.001, .001), v_tex_index)))
|
|
||||||
// ) / 6.;
|
|
||||||
// color /= 2.;
|
|
||||||
// discard fully transparent pixels
|
// discard fully transparent pixels
|
||||||
if (color.w <= 0.0) {
|
if (color.w <= 0.0) discard;
|
||||||
discard;
|
|
||||||
}
|
|
||||||
//basic "lighting"
|
//basic "lighting"
|
||||||
float light = abs(v_normal.x) + .8 * abs(v_normal.y) + .6 * abs(v_normal.z);
|
float light = abs(v_normal.x) + .8 * abs(v_normal.y) + .6 * abs(v_normal.z);
|
||||||
color *= vec4(vec3(light), 1.);
|
color *= vec4(vec3(light), 1.);
|
||||||
|
|
|
@ -63,7 +63,7 @@ fn block_placement_system(
|
||||||
(ray.block_position, Block::Air)
|
(ray.block_position, Block::Air)
|
||||||
};
|
};
|
||||||
//queue place
|
//queue place
|
||||||
block_event_queue.push(QueuedBlock {
|
block_event_queue.0.push(QueuedBlock {
|
||||||
position: place_position,
|
position: place_position,
|
||||||
block_type: place_block,
|
block_type: place_block,
|
||||||
soft: place_block != Block::Air,
|
soft: place_block != Block::Air,
|
||||||
|
|
|
@ -69,9 +69,9 @@ use rendering::{
|
||||||
init_window_size,
|
init_window_size,
|
||||||
update_window_size,
|
update_window_size,
|
||||||
primitives::init_primitives,
|
primitives::init_primitives,
|
||||||
|
world::{draw_world, draw_current_chunk_border},
|
||||||
selection_box::render_selection_box,
|
selection_box::render_selection_box,
|
||||||
world::draw_world,
|
entities::render_entities,
|
||||||
world::draw_current_chunk_border,
|
|
||||||
};
|
};
|
||||||
use block_placement::update_block_placement;
|
use block_placement::update_block_placement;
|
||||||
use delta_time::{DeltaTime, init_delta_time};
|
use delta_time::{DeltaTime, init_delta_time};
|
||||||
|
@ -107,6 +107,7 @@ fn startup() -> Workload {
|
||||||
init_delta_time,
|
init_delta_time,
|
||||||
).into_sequential_workload()
|
).into_sequential_workload()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update() -> Workload {
|
fn update() -> Workload {
|
||||||
(
|
(
|
||||||
update_window_size,
|
update_window_size,
|
||||||
|
@ -143,6 +144,7 @@ fn update() -> Workload {
|
||||||
disconnect_on_exit.run_if(is_multiplayer),
|
disconnect_on_exit.run_if(is_multiplayer),
|
||||||
).into_sequential_workload()
|
).into_sequential_workload()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render() -> Workload {
|
fn render() -> Workload {
|
||||||
(
|
(
|
||||||
clear_background,
|
clear_background,
|
||||||
|
@ -150,10 +152,12 @@ fn render() -> Workload {
|
||||||
draw_world,
|
draw_world,
|
||||||
draw_current_chunk_border,
|
draw_current_chunk_border,
|
||||||
render_selection_box,
|
render_selection_box,
|
||||||
|
render_entities,
|
||||||
).into_sequential_workload().run_if(is_ingame),
|
).into_sequential_workload().run_if(is_ingame),
|
||||||
render_gui,
|
render_gui,
|
||||||
).into_sequential_workload()
|
).into_sequential_workload()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_frame_end() -> Workload {
|
fn after_frame_end() -> Workload {
|
||||||
(
|
(
|
||||||
clear_events,
|
clear_events,
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
use shipyard::{Unique, AllStoragesView, UniqueView, UniqueViewMut, Workload, IntoWorkload, EntitiesViewMut, Component, ViewMut, SystemModificator, View, IntoIter, WorkloadModificator};
|
use shipyard::{Unique, AllStoragesView, UniqueView, UniqueViewMut, Workload, IntoWorkload, EntitiesViewMut, Component, ViewMut, SystemModificator, View, IntoIter, WorkloadModificator};
|
||||||
use glium::glutin::event_loop::ControlFlow;
|
use glium::glutin::event_loop::ControlFlow;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use uflow::{client::{Client, Config as ClientConfig, Event as ClientEvent}, EndpointConfig};
|
use uflow::{
|
||||||
|
client::{Client, Config as ClientConfig, Event as ClientEvent},
|
||||||
|
EndpointConfig
|
||||||
|
};
|
||||||
use kubi_shared::networking::{
|
use kubi_shared::networking::{
|
||||||
messages::ServerToClientMessage,
|
messages::ServerToClientMessage,
|
||||||
state::ClientJoinState,
|
state::ClientJoinState,
|
||||||
|
@ -71,7 +74,7 @@ fn connect_client(
|
||||||
endpoint_config: EndpointConfig {
|
endpoint_config: EndpointConfig {
|
||||||
active_timeout_ms: 10000,
|
active_timeout_ms: 10000,
|
||||||
keepalive: true,
|
keepalive: true,
|
||||||
keepalive_interval_ms: 1000,
|
keepalive_interval_ms: 300,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
}).expect("Client connection failed");
|
}).expect("Client connection failed");
|
||||||
|
@ -128,8 +131,8 @@ pub fn update_networking() -> Workload {
|
||||||
).into_sequential_workload().run_if(is_join_state::<{ClientJoinState::Connected as u8}>),
|
).into_sequential_workload().run_if(is_join_state::<{ClientJoinState::Connected as u8}>),
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
receive_player_connect_events
|
receive_player_connect_events,
|
||||||
),
|
).into_workload(),
|
||||||
(
|
(
|
||||||
recv_block_place_events,
|
recv_block_place_events,
|
||||||
receive_player_movement_events,
|
receive_player_movement_events,
|
||||||
|
|
|
@ -4,7 +4,7 @@ use uflow::{SendMode, client::Event as ClientEvent};
|
||||||
use kubi_shared::{
|
use kubi_shared::{
|
||||||
transform::Transform,
|
transform::Transform,
|
||||||
networking::{
|
networking::{
|
||||||
messages::{ClientToServerMessage, ServerToClientMessage, S_PLAYER_POSITION_CHANGED},
|
messages::{ClientToServerMessage, ServerToClientMessage, S_PLAYER_POSITION_CHANGED, S_PLAYER_CONNECTED},
|
||||||
channels::CHANNEL_MOVE,
|
channels::CHANNEL_MOVE,
|
||||||
client::ClientIdMap,
|
client::ClientIdMap,
|
||||||
},
|
},
|
||||||
|
@ -83,7 +83,7 @@ pub fn receive_player_connect_events(
|
||||||
let ClientEvent::Receive(data) = &event.0 else {
|
let ClientEvent::Receive(data) = &event.0 else {
|
||||||
return None
|
return None
|
||||||
};
|
};
|
||||||
if !event.is_message_of_type::<S_PLAYER_POSITION_CHANGED>() {
|
if !event.is_message_of_type::<S_PLAYER_CONNECTED>() {
|
||||||
return None
|
return None
|
||||||
};
|
};
|
||||||
let Ok(parsed_message) = postcard::from_bytes(data) else {
|
let Ok(parsed_message) = postcard::from_bytes(data) else {
|
||||||
|
|
|
@ -86,6 +86,6 @@ pub fn recv_block_place_events(
|
||||||
let ServerToClientMessage::QueueBlock { item } = parsed_message else {
|
let ServerToClientMessage::QueueBlock { item } = parsed_message else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
queue.push(item);
|
queue.0.push(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,18 +37,19 @@ impl AssetPaths for BlockTexture {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Unique)]
|
#[derive(Unique)]
|
||||||
|
#[repr(transparent)]
|
||||||
pub struct BlockTexturesPrefab(pub SrgbTexture2dArray);
|
pub struct BlockTexturesPrefab(pub SrgbTexture2dArray);
|
||||||
|
|
||||||
#[derive(Unique)]
|
#[derive(Unique)]
|
||||||
|
#[repr(transparent)]
|
||||||
pub struct ChunkShaderPrefab(pub Program);
|
pub struct ChunkShaderPrefab(pub Program);
|
||||||
|
|
||||||
#[derive(Unique)]
|
#[derive(Unique)]
|
||||||
pub struct SelBoxShaderPrefab(pub Program);
|
#[repr(transparent)]
|
||||||
|
|
||||||
#[derive(Unique)]
|
|
||||||
pub struct ColoredShaderPrefab(pub Program);
|
pub struct ColoredShaderPrefab(pub Program);
|
||||||
|
|
||||||
#[derive(Unique)]
|
#[derive(Unique)]
|
||||||
|
#[repr(transparent)]
|
||||||
pub struct ProgressbarShaderPrefab(pub Program);
|
pub struct ProgressbarShaderPrefab(pub Program);
|
||||||
|
|
||||||
pub fn load_prefabs(
|
pub fn load_prefabs(
|
||||||
|
@ -73,14 +74,6 @@ pub fn load_prefabs(
|
||||||
&renderer.display
|
&renderer.display
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
storages.add_unique_non_send_sync(SelBoxShaderPrefab(
|
|
||||||
include_shader_prefab!(
|
|
||||||
"selection_box",
|
|
||||||
"../shaders/selection_box.vert",
|
|
||||||
"../shaders/selection_box.frag",
|
|
||||||
&renderer.display
|
|
||||||
)
|
|
||||||
));
|
|
||||||
storages.add_unique_non_send_sync(ColoredShaderPrefab(
|
storages.add_unique_non_send_sync(ColoredShaderPrefab(
|
||||||
include_shader_prefab!(
|
include_shader_prefab!(
|
||||||
"colored",
|
"colored",
|
||||||
|
|
|
@ -14,14 +14,18 @@ use crate::{events::WindowResizedEvent, settings::{GameSettings, FullscreenMode}
|
||||||
pub mod primitives;
|
pub mod primitives;
|
||||||
pub mod world;
|
pub mod world;
|
||||||
pub mod selection_box;
|
pub mod selection_box;
|
||||||
|
pub mod entities;
|
||||||
|
|
||||||
#[derive(Unique)]
|
#[derive(Unique)]
|
||||||
|
#[repr(transparent)]
|
||||||
pub struct RenderTarget(pub glium::Frame);
|
pub struct RenderTarget(pub glium::Frame);
|
||||||
|
|
||||||
#[derive(Unique)]
|
#[derive(Unique)]
|
||||||
|
#[repr(transparent)]
|
||||||
pub struct BackgroundColor(pub Vec3);
|
pub struct BackgroundColor(pub Vec3);
|
||||||
|
|
||||||
#[derive(Unique, Clone, Copy)]
|
#[derive(Unique, Clone, Copy)]
|
||||||
|
#[repr(transparent)]
|
||||||
pub struct WindowSize(pub UVec2);
|
pub struct WindowSize(pub UVec2);
|
||||||
|
|
||||||
#[derive(Unique)]
|
#[derive(Unique)]
|
||||||
|
@ -32,7 +36,6 @@ impl Renderer {
|
||||||
pub fn init(event_loop: &EventLoop<()>, settings: &GameSettings) -> Self {
|
pub fn init(event_loop: &EventLoop<()>, settings: &GameSettings) -> Self {
|
||||||
log::info!("initializing display");
|
log::info!("initializing display");
|
||||||
|
|
||||||
|
|
||||||
let wb = WindowBuilder::new()
|
let wb = WindowBuilder::new()
|
||||||
.with_title("kubi")
|
.with_title("kubi")
|
||||||
.with_maximized(true)
|
.with_maximized(true)
|
||||||
|
|
59
kubi/src/rendering/entities.rs
Normal file
59
kubi/src/rendering/entities.rs
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
use shipyard::{NonSendSync, UniqueViewMut, UniqueView, View, IntoIter, IntoWithId};
|
||||||
|
use glium::{DepthTest, Depth, PolygonMode, BackfaceCullingMode, DrawParameters, Surface, uniform};
|
||||||
|
use kubi_shared::{entity::Entity, transform::Transform};
|
||||||
|
use crate::{
|
||||||
|
prefabs::ColoredShaderPrefab,
|
||||||
|
camera::Camera,
|
||||||
|
settings::GameSettings,
|
||||||
|
player::MainPlayer
|
||||||
|
};
|
||||||
|
use super::{
|
||||||
|
RenderTarget,
|
||||||
|
primitives::cube::CubePrimitive
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: entity models
|
||||||
|
pub fn render_entities(
|
||||||
|
mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
|
||||||
|
buffers: NonSendSync<UniqueView<CubePrimitive>>,
|
||||||
|
program: NonSendSync<UniqueView<ColoredShaderPrefab>>,
|
||||||
|
camera: View<Camera>,
|
||||||
|
settings: UniqueView<GameSettings>,
|
||||||
|
entities: View<Entity>,
|
||||||
|
transform: View<Transform>,
|
||||||
|
) {
|
||||||
|
let (camera_id, camera) = camera.iter().with_id().next().expect("No cameras in the scene");
|
||||||
|
|
||||||
|
let draw_parameters = DrawParameters {
|
||||||
|
depth: Depth {
|
||||||
|
test: DepthTest::IfLess,
|
||||||
|
write: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
multisampling: settings.msaa.is_some(),
|
||||||
|
polygon_mode: PolygonMode::Fill,
|
||||||
|
backface_culling: BackfaceCullingMode::CullClockwise,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let view = camera.view_matrix.to_cols_array_2d();
|
||||||
|
let perspective = camera.perspective_matrix.to_cols_array_2d();
|
||||||
|
|
||||||
|
for (entity_id, (_, trans)) in (&entities, &transform).iter().with_id() {
|
||||||
|
//skip rendering camera holder (as the entity would block the view)
|
||||||
|
if entity_id == camera_id { continue }
|
||||||
|
|
||||||
|
//render entity
|
||||||
|
target.0.draw(
|
||||||
|
&buffers.0,
|
||||||
|
&buffers.1,
|
||||||
|
&program.0,
|
||||||
|
&uniform! {
|
||||||
|
color: [1.0, 1.0, 1.0, 1.0_f32],
|
||||||
|
model: trans.0.to_cols_array_2d(),
|
||||||
|
view: view,
|
||||||
|
perspective: perspective,
|
||||||
|
},
|
||||||
|
&draw_parameters
|
||||||
|
).unwrap();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
use glam::{Mat4, Vec3, Quat};
|
||||||
use shipyard::{View, IntoIter, NonSendSync, UniqueViewMut, UniqueView};
|
use shipyard::{View, IntoIter, NonSendSync, UniqueViewMut, UniqueView};
|
||||||
use glium::{
|
use glium::{
|
||||||
Surface,
|
Surface,
|
||||||
|
@ -8,18 +9,21 @@ use glium::{
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
world::raycast::LookingAtBlock,
|
world::raycast::LookingAtBlock,
|
||||||
camera::Camera, prefabs::SelBoxShaderPrefab
|
camera::Camera,
|
||||||
|
prefabs::ColoredShaderPrefab
|
||||||
};
|
};
|
||||||
use super::{
|
use super::{
|
||||||
RenderTarget,
|
RenderTarget,
|
||||||
primitives::cube::CubePrimitive,
|
primitives::cube::CubePrimitive,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const SMOL: f32 = 0.0001;
|
||||||
|
|
||||||
pub fn render_selection_box(
|
pub fn render_selection_box(
|
||||||
lookat: View<LookingAtBlock>,
|
lookat: View<LookingAtBlock>,
|
||||||
camera: View<Camera>,
|
camera: View<Camera>,
|
||||||
mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
|
mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
|
||||||
program: NonSendSync<UniqueView<SelBoxShaderPrefab>>,
|
program: NonSendSync<UniqueView<ColoredShaderPrefab>>,
|
||||||
buffers: NonSendSync<UniqueView<CubePrimitive>>,
|
buffers: NonSendSync<UniqueView<CubePrimitive>>,
|
||||||
) {
|
) {
|
||||||
let camera = camera.iter().next().unwrap();
|
let camera = camera.iter().next().unwrap();
|
||||||
|
@ -32,8 +36,12 @@ pub fn render_selection_box(
|
||||||
&buffers.1,
|
&buffers.1,
|
||||||
&program.0,
|
&program.0,
|
||||||
&uniform! {
|
&uniform! {
|
||||||
u_color: [0., 0., 0., 0.5_f32],
|
color: [0., 0., 0., 0.5_f32],
|
||||||
u_position: lookat.block_position.to_array(),
|
model: Mat4::from_scale_rotation_translation(
|
||||||
|
Vec3::splat(1. + SMOL * 2.),
|
||||||
|
Quat::default(),
|
||||||
|
lookat.block_position.as_vec3() - Vec3::splat(SMOL)
|
||||||
|
).to_cols_array_2d(),
|
||||||
perspective: camera.perspective_matrix.to_cols_array_2d(),
|
perspective: camera.perspective_matrix.to_cols_array_2d(),
|
||||||
view: camera.view_matrix.to_cols_array_2d(),
|
view: camera.view_matrix.to_cols_array_2d(),
|
||||||
},
|
},
|
||||||
|
@ -41,7 +49,8 @@ pub fn render_selection_box(
|
||||||
backface_culling: BackfaceCullingMode::CullClockwise,
|
backface_culling: BackfaceCullingMode::CullClockwise,
|
||||||
blend: Blend::alpha_blending(),
|
blend: Blend::alpha_blending(),
|
||||||
depth: Depth {
|
depth: Depth {
|
||||||
test: DepthTest::IfLessOrEqual, //this may be unreliable!
|
//this may be unreliable... unless scale is applied! hacky...
|
||||||
|
test: DepthTest::IfLessOrEqual,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
|
@ -191,7 +191,7 @@ fn process_completed_tasks(
|
||||||
let mut ops: usize = 0;
|
let mut ops: usize = 0;
|
||||||
while let Some(res) = task_manager.receive() {
|
while let Some(res) = task_manager.receive() {
|
||||||
match res {
|
match res {
|
||||||
ChunkTaskResponse::LoadedChunk { position, chunk_data, queued } => {
|
ChunkTaskResponse::LoadedChunk { position, chunk_data, mut queued } => {
|
||||||
//check if chunk exists
|
//check if chunk exists
|
||||||
let Some(chunk) = world.chunks.get_mut(&position) else {
|
let Some(chunk) = world.chunks.get_mut(&position) else {
|
||||||
log::warn!("blocks data discarded: chunk doesn't exist");
|
log::warn!("blocks data discarded: chunk doesn't exist");
|
||||||
|
@ -213,10 +213,8 @@ fn process_completed_tasks(
|
||||||
chunk.current_state = CurrentChunkState::Loaded;
|
chunk.current_state = CurrentChunkState::Loaded;
|
||||||
|
|
||||||
//push queued blocks
|
//push queued blocks
|
||||||
//TODO use extend
|
queue.0.append(&mut queued);
|
||||||
for item in queued {
|
drop(queued); //`queued` is empty after `append`
|
||||||
queue.push(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
//increase ops counter
|
//increase ops counter
|
||||||
ops += 1;
|
ops += 1;
|
||||||
|
|
|
@ -4,16 +4,12 @@ use shipyard::{UniqueViewMut, Unique};
|
||||||
use super::ChunkStorage;
|
use super::ChunkStorage;
|
||||||
|
|
||||||
#[derive(Unique, Default, Clone)]
|
#[derive(Unique, Default, Clone)]
|
||||||
pub struct BlockUpdateQueue {
|
#[repr(transparent)]
|
||||||
queue: Vec<QueuedBlock>
|
pub struct BlockUpdateQueue(pub Vec<QueuedBlock>);
|
||||||
}
|
|
||||||
impl BlockUpdateQueue {
|
impl BlockUpdateQueue {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
pub fn push(&mut self, event: QueuedBlock) {
|
|
||||||
self.queue.push(event)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_queued_blocks(
|
pub fn apply_queued_blocks(
|
||||||
|
@ -21,7 +17,7 @@ pub fn apply_queued_blocks(
|
||||||
mut world: UniqueViewMut<ChunkStorage>
|
mut world: UniqueViewMut<ChunkStorage>
|
||||||
) {
|
) {
|
||||||
//maybe i need to check for desired/current state here before marking as dirty?
|
//maybe i need to check for desired/current state here before marking as dirty?
|
||||||
queue.queue.retain(|&event| {
|
queue.0.retain(|&event| {
|
||||||
if let Some(block) = world.get_block_mut(event.position) {
|
if let Some(block) = world.get_block_mut(event.position) {
|
||||||
if event.soft && *block != Block::Air {
|
if event.soft && *block != Block::Air {
|
||||||
return false
|
return false
|
||||||
|
|
Loading…
Reference in a new issue