summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-01-05 23:24:57 +0100
committermetamuffin <metamuffin@disroot.org>2025-01-05 23:24:57 +0100
commit1c0c8f788c8125c90a097e5241b5e8fe2518d1d2 (patch)
treeb5542fe00a472b5d5a8bcdd17fb3a34b75ad1dd0
parente15b39b2a9cf028b12cbe98f56674e58c5a6bd4c (diff)
downloadweareserver-1c0c8f788c8125c90a097e5241b5e8fe2518d1d2.tar
weareserver-1c0c8f788c8125c90a097e5241b5e8fe2518d1d2.tar.bz2
weareserver-1c0c8f788c8125c90a097e5241b5e8fe2518d1d2.tar.zst
a
-rw-r--r--a.md16
-rw-r--r--client/src/download.rs9
-rw-r--r--client/src/network.rs3
-rw-r--r--client/src/part.rs11
-rw-r--r--client/src/renderer.rs22
-rw-r--r--client/src/shader.wgsl4
-rw-r--r--client/src/window.rs11
-rw-r--r--server/src/main.rs8
-rw-r--r--shared/src/packets.rs38
-rw-r--r--shared/src/resources.rs6
-rw-r--r--shared/src/tree.rs14
11 files changed, 105 insertions, 37 deletions
diff --git a/a.md b/a.md
index 642c44f..48136ce 100644
--- a/a.md
+++ b/a.md
@@ -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 {