diff options
author | metamuffin <metamuffin@disroot.org> | 2025-01-05 23:24:57 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-01-05 23:24:57 +0100 |
commit | 1c0c8f788c8125c90a097e5241b5e8fe2518d1d2 (patch) | |
tree | b5542fe00a472b5d5a8bcdd17fb3a34b75ad1dd0 | |
parent | e15b39b2a9cf028b12cbe98f56674e58c5a6bd4c (diff) | |
download | weareserver-1c0c8f788c8125c90a097e5241b5e8fe2518d1d2.tar weareserver-1c0c8f788c8125c90a097e5241b5e8fe2518d1d2.tar.bz2 weareserver-1c0c8f788c8125c90a097e5241b5e8fe2518d1d2.tar.zst |
a
-rw-r--r-- | a.md | 16 | ||||
-rw-r--r-- | client/src/download.rs | 9 | ||||
-rw-r--r-- | client/src/network.rs | 3 | ||||
-rw-r--r-- | client/src/part.rs | 11 | ||||
-rw-r--r-- | client/src/renderer.rs | 22 | ||||
-rw-r--r-- | client/src/shader.wgsl | 4 | ||||
-rw-r--r-- | client/src/window.rs | 11 | ||||
-rw-r--r-- | server/src/main.rs | 8 | ||||
-rw-r--r-- | shared/src/packets.rs | 38 | ||||
-rw-r--r-- | shared/src/resources.rs | 6 | ||||
-rw-r--r-- | shared/src/tree.rs | 14 |
11 files changed, 105 insertions, 37 deletions
@@ -5,14 +5,14 @@ Vec is stored as `len:u8 *(data:T)` ```rs type Obj = [u8; 16] type Res = [u8; 32] -01 request_resource(name: Res) -02 respond_resource(data: Vec<u8>) -03 add(id: Obj, prefab: Res) -04 remove(id: Obj) -05 position(id: Obj, pos: Vec3, rot: Vec3) -06 pose(id: Obj, params: Vec<f32>) -07 parent(parent: Obj, child: Obj) -08 sound(id: Obj, data: Vec<u8>) +len 01 request_resource(name: Res) +len 02 respond_resource(data: Vec<u8>) +len 03 add(id: Obj, prefab: Res) +len 04 remove(id: Obj) +len 05 position(id: Obj, pos: Vec3, rot: Vec3) +len 06 pose(id: Obj, params: Vec<f32>) +len 07 parent(parent: Obj, child: Obj) +len 08 sound(id: Obj, data: Vec<u8>) ``` ## Resource formats diff --git a/client/src/download.rs b/client/src/download.rs index 256c25c..dfd7ff0 100644 --- a/client/src/download.rs +++ b/client/src/download.rs @@ -1,12 +1,12 @@ +use crate::network::Network; use anyhow::Result; +use log::debug; use std::collections::HashSet; use weareshared::{ packets::{Packet, Resource}, store::{ResourceStore, sha256}, }; -use crate::network::Network; - pub struct Downloader { have: HashSet<Resource>, need: HashSet<Resource>, @@ -38,7 +38,9 @@ impl Downloader { self.store.set(&d)?; self.need.remove(&key); self.pending.remove(&key); - self.have.insert(key); + if self.have.insert(key) { + debug!("have {key}"); + } } _ => (), } @@ -51,6 +53,7 @@ impl Downloader { .packet_send .send(Packet::RequestResource(*n)) .unwrap(); + debug!("need {n}"); new_pending.push(*n); } self.pending.extend(new_pending); diff --git a/client/src/network.rs b/client/src/network.rs index 0fd5f08..e542c7e 100644 --- a/client/src/network.rs +++ b/client/src/network.rs @@ -1,5 +1,5 @@ use std::{ - io::{BufReader, BufWriter}, + io::{BufReader, BufWriter, Write}, net::TcpStream, sync::mpsc::{Receiver, Sender, channel}, thread::spawn, @@ -50,6 +50,7 @@ fn handle_conn_write(sock: TcpStream, rx: Receiver<Packet>) -> Result<()> { for packet in rx { debug!("-> {packet:?}"); packet.serialize(&mut sock)?; + sock.flush()?; } Ok(()) } diff --git a/client/src/part.rs b/client/src/part.rs index 0ad714a..7d02f0c 100644 --- a/client/src/part.rs +++ b/client/src/part.rs @@ -12,13 +12,18 @@ use wgpu::{ util::{BufferInitDescriptor, DeviceExt}, }; -pub struct RenderPart { +pub struct PartRenderer { vertex: Buffer, index: Buffer, pipeline: RenderPipeline, bind_group: BindGroup, n_vertex: u32, } + +pub struct PrefabData { + +} + pub struct PartData { target: Part, vertex: Vec<Option<VertexAttributes>>, @@ -48,7 +53,7 @@ impl PartData { } } -impl RenderPart { +impl PartRenderer { pub fn new(device: Device, data: PartData, format: TextureFormat) -> Self { let mut vertex = Vec::new(); let mut index = Vec::new(); @@ -140,7 +145,7 @@ impl RenderPart { n_vertex, } } - pub fn draw(&self, commands: &mut CommandEncoder, target: TextureView) { + pub fn draw(&self, commands: &mut CommandEncoder, target: &TextureView) { let mut rpass = commands.begin_render_pass(&RenderPassDescriptor { label: None, color_attachments: &[Some(RenderPassColorAttachment { diff --git a/client/src/renderer.rs b/client/src/renderer.rs index cc44446..35bc0ef 100644 --- a/client/src/renderer.rs +++ b/client/src/renderer.rs @@ -1,6 +1,9 @@ +use crate::part::{PartData, PartRenderer}; use anyhow::{Result, anyhow}; use log::info; use pollster::FutureExt; +use std::collections::HashMap; +use weareshared::{packets::Resource, tree::SceneTree}; use wgpu::{ Backends, BindGroup, BindGroupDescriptor, BindGroupLayoutDescriptor, BlendState, Color, ColorTargetState, ColorWrites, CommandEncoderDescriptor, Device, DeviceDescriptor, Features, @@ -20,6 +23,9 @@ pub struct Renderer<'a> { queue: Queue, device: Device, surface_configuration: SurfaceConfiguration, + + prefabs_loading: HashMap<Resource, Vec<PartData>>, + prefabs: HashMap<Resource, Vec<PartRenderer>>, } impl<'a> Renderer<'a> { pub fn new(window: &'a Window) -> Result<Self> { @@ -111,6 +117,8 @@ impl<'a> Renderer<'a> { device, queue, surface_configuration, + prefabs: HashMap::new(), + prefabs_loading: HashMap::new(), }) } @@ -121,7 +129,7 @@ impl<'a> Renderer<'a> { .configure(&self.device, &self.surface_configuration); } - pub fn draw(&mut self) -> Result<()> { + pub fn draw(&mut self, scene: &SceneTree) -> Result<()> { let target = self.surface.get_current_texture()?; let target_view = target .texture @@ -150,9 +158,19 @@ impl<'a> Renderer<'a> { rpass.draw(0..3, 0..1); } + for data in scene.objects.values() { + if let Some(ob) = self.prefabs.get(&data.res) { + for p in ob { + p.draw(&mut commands, &target_view); + } + } else { + let loading = self.prefabs_loading.entry(data.res).or_default(); + + } + } + let i = self.queue.submit(Some(commands.finish())); self.device.poll(MaintainBase::WaitForSubmissionIndex(i)); - target.present(); Ok(()) diff --git a/client/src/shader.wgsl b/client/src/shader.wgsl index 859ffa4..41c21d9 100644 --- a/client/src/shader.wgsl +++ b/client/src/shader.wgsl @@ -1,6 +1,6 @@ @vertex fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4<f32> { - let x = f32(i32(in_vertex_index) - 1); + let x = f32(i32(in_vertex_index) % 2); let y = f32(i32(in_vertex_index & 1u) * 2 - 1); return vec4<f32>(x, y, 0.0, 1.0); } @@ -8,4 +8,4 @@ fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) ve @fragment fn fs_main() -> @location(0) vec4<f32> { return vec4<f32>(1.0, 0.0, 0.0, 1.0); -}
\ No newline at end of file +} diff --git a/client/src/window.rs b/client/src/window.rs index 5f2e7f8..2219bbc 100644 --- a/client/src/window.rs +++ b/client/src/window.rs @@ -43,7 +43,7 @@ impl ApplicationHandler for WindowState { WindowEvent::Resized(size) => { sta.renderer.resize(size.width, size.height); } - WindowEvent::RedrawRequested => sta.renderer.draw().unwrap(), + WindowEvent::RedrawRequested => sta.renderer.draw(&sta.tree).unwrap(), WindowEvent::CloseRequested => { event_loop.exit(); } @@ -59,3 +59,12 @@ impl ApplicationHandler for WindowState { } } } + +impl Drop for WindowState { + fn drop(&mut self) { + if let Some((win, sta)) = self.window.take() { + drop(sta); + drop(win) + } + } +} diff --git a/server/src/main.rs b/server/src/main.rs index d9d65cc..cc55488 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -3,7 +3,7 @@ use clap::Parser; use log::{debug, info}; use std::{ collections::HashMap, - io::{BufReader, BufWriter}, + io::{BufReader, BufWriter, Write}, net::{IpAddr, TcpListener, TcpStream}, sync::{ Arc, Mutex, @@ -38,10 +38,13 @@ fn main() -> Result<()> { let (sock, addr) = listener.accept()?; info!("{addr} connected"); let (tx, rx) = channel(); - state.lock().unwrap().tx.insert(conn, tx); let state2 = state.clone(); let sock2 = sock.try_clone().unwrap(); spawn(move || { + for p in state2.lock().unwrap().tree.prime_client() { + tx.send(p).unwrap(); + } + state2.lock().unwrap().tx.insert(conn, tx); let _ = handle_conn_read(conn, sock, state2.clone()); info!("{addr} disconnected"); state2.lock().unwrap().tx.remove(&conn); @@ -66,6 +69,7 @@ fn handle_conn_write(conn: usize, sock: TcpStream, rx: Receiver<Packet>) -> Resu for packet in rx { debug!("{conn} -> {packet:?}"); packet.serialize(&mut sock)?; + sock.flush()?; } Ok(()) } diff --git a/shared/src/packets.rs b/shared/src/packets.rs index c273028..325cf14 100644 --- a/shared/src/packets.rs +++ b/shared/src/packets.rs @@ -1,6 +1,9 @@ use anyhow::{Result, bail}; use glam::Vec3; -use std::io::{Read, Write}; +use std::{ + fmt::Display, + io::{Read, Write}, +}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Resource(pub [u8; 32]); @@ -27,6 +30,13 @@ impl Object { impl Packet { pub fn serialize(&self, w: &mut impl Write) -> Result<()> { + let mut buf = Vec::new(); + self.serialize_inner(&mut buf)?; + w.write_all(&(buf.len() as u16).to_be_bytes())?; + w.write_all(&buf)?; + Ok(()) + } + pub fn serialize_inner(&self, w: &mut impl Write) -> Result<()> { match self { Packet::RequestResource(resource) => { w.write_all(&[0x01])?; @@ -75,9 +85,9 @@ impl Packet { Ok(()) } pub fn deserialize(r: &mut impl Read) -> Result<Self> { - let mut tag = [0u8; 1]; - r.read_exact(&mut tag)?; - Ok(match tag[0] { + let mut size_tag = [0u8; 3]; + r.read_exact(&mut size_tag)?; + Ok(match size_tag[2] { 0x01 => Packet::RequestResource(read_res(r)?), 0x02 => Packet::RespondResource(read_data(r)?), 0x03 => Packet::Add(Object(read_u128(r)?), read_res(r)?), @@ -90,7 +100,12 @@ impl Packet { 0x06 => Packet::Pose(Object(read_u128(r)?), read_params(r)?), 0x07 => Packet::Parent(Object(read_u128(r)?), Object(read_u128(r)?)), 0x08 => Packet::Sound(Object(read_u128(r)?), read_data(r)?), - _ => bail!("unknown packet tag"), + _ => { + for _ in 0..u16::from_be_bytes([size_tag[0], size_tag[1]]) { + r.read_exact(&mut [0])?; + } + bail!("unknown packet tag"); + } }) } } @@ -128,3 +143,16 @@ fn read_params(r: &mut impl Read) -> Result<Vec<f32>> { } Ok(v) } + +impl Display for Resource { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Res{{{:08x}{:08x}{:08x}{:08x}}}", + u64::from_be_bytes(self.0[0..8].try_into().unwrap()), + u64::from_be_bytes(self.0[8..16].try_into().unwrap()), + u64::from_be_bytes(self.0[16..24].try_into().unwrap()), + u64::from_be_bytes(self.0[24..32].try_into().unwrap()), + ) + } +} diff --git a/shared/src/resources.rs b/shared/src/resources.rs index 651eb4b..a677755 100644 --- a/shared/src/resources.rs +++ b/shared/src/resources.rs @@ -15,7 +15,7 @@ pub struct Part { pub fragment_shader_data: Option<Resource>, pub vertex_shader: Option<Resource>, pub vertex_shader_data: Option<Resource>, - pub texture: Option<Resource>, + pub texture: Vec<Resource>, } #[derive(Debug, Default, Clone)] @@ -91,7 +91,7 @@ impl Part { if let Some(x) = &self.vertex_shader_data { write_kv(w, b"vertex_shader_data", &x.0); } - if let Some(x) = &self.texture { + for x in &self.vertex { write_kv(w, b"texture", &x.0); } Ok(()) @@ -108,7 +108,7 @@ impl Part { b"fragment_shader_data" => s.fragment_shader_data = Some(slice_to_res(&v)?), b"vertex_shader" => s.vertex_shader = Some(slice_to_res(&v)?), b"vertex_shader_data" => s.vertex_shader_data = Some(slice_to_res(&v)?), - b"texture" => s.texture = Some(slice_to_res(&v)?), + b"texture" => s.texture.push(slice_to_res(&v)?), _ => warn!("unknown part key"), } } diff --git a/shared/src/tree.rs b/shared/src/tree.rs index fce6f8a..4cb7abc 100644 --- a/shared/src/tree.rs +++ b/shared/src/tree.rs @@ -3,14 +3,14 @@ use glam::Vec3; use std::collections::HashMap; pub struct SceneTree { - objects: HashMap<Object, ObjectData>, + pub objects: HashMap<Object, ObjectData>, } -struct ObjectData { - pos: Vec3, - rot: Vec3, - parent: Object, - pose: Vec<f32>, - res: Resource, +pub struct ObjectData { + pub pos: Vec3, + pub rot: Vec3, + pub parent: Object, + pub pose: Vec<f32>, + pub res: Resource, } impl Default for SceneTree { fn default() -> Self { |