summaryrefslogtreecommitdiff
path: root/client/src/scene_prepare.rs
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/scene_prepare.rs')
-rw-r--r--client/src/scene_prepare.rs111
1 files changed, 80 insertions, 31 deletions
diff --git a/client/src/scene_prepare.rs b/client/src/scene_prepare.rs
index 8d50fc3..47f168d 100644
--- a/client/src/scene_prepare.rs
+++ b/client/src/scene_prepare.rs
@@ -1,5 +1,6 @@
use crate::download::Downloader;
use anyhow::{Context, Result};
+use log::{debug, info};
use std::{
collections::{HashMap, HashSet},
sync::Arc,
@@ -8,8 +9,12 @@ use weareshared::{
Affine3A,
packets::{ReadWrite, Resource},
resources::{Attribute, Part, Prefab},
+ store::sha256,
+};
+use wgpu::{
+ Buffer, BufferUsages, Device,
+ util::{BufferInitDescriptor, DeviceExt},
};
-use wgpu::Buffer;
pub struct ScenePreparer {
index_buffers: HashMap<Resource, (Arc<Buffer>, u32)>,
@@ -20,6 +25,8 @@ pub struct ScenePreparer {
parts_needed: HashSet<Resource>,
pub prefabs: HashMap<Resource, RPrefab>,
pub prefabs_needed: HashSet<Resource>,
+
+ device: Arc<Device>,
}
pub struct RPrefab(pub Vec<(Affine3A, Arc<RPart>)>);
@@ -32,7 +39,7 @@ pub struct RPart {
}
impl ScenePreparer {
- pub fn new() -> Self {
+ pub fn new(device: Arc<Device>) -> Self {
Self {
index_buffers: HashMap::new(),
vertex_buffers: HashMap::new(),
@@ -42,6 +49,7 @@ impl ScenePreparer {
prefabs: HashMap::new(),
prefabs_needed: HashSet::new(),
index_buffers_needed: HashSet::new(),
+ device,
}
}
pub fn update(&mut self, dls: &mut Downloader) -> Result<()> {
@@ -59,12 +67,45 @@ impl ScenePreparer {
}
if rprefab.0.len() == prefab.0.len() {
self.prefabs.insert(*pres, rprefab);
+ debug!("prefab created ({pres})");
done.push(*pres);
}
}
}
for pres in &self.index_buffers_needed {
- if let Some(buf) = dls.try_get(*pres)? {}
+ if let Some(buf) = dls.try_get(*pres)? {
+ let buffer = self.device.create_buffer_init(&BufferInitDescriptor {
+ contents: &buf,
+ label: None,
+ usage: BufferUsages::INDEX | BufferUsages::COPY_DST,
+ });
+ self.index_buffers
+ .insert(*pres, (Arc::new(buffer), buf.len() as u32 / 2));
+ debug!("index buffer created (len={}) {pres}", buf.len() / 6);
+ done.push(*pres);
+ }
+ }
+ for pres in &self.vertex_buffers_needed {
+ if let Some(buf) = dls.try_get(*pres)? {
+ let buf = buf
+ .into_iter()
+ .array_chunks::<4>()
+ .map(f32::from_be_bytes)
+ .map(f32::to_le_bytes)
+ .flatten()
+ .collect::<Vec<_>>();
+ let buffer = self.device.create_buffer_init(&BufferInitDescriptor {
+ contents: &buf,
+ label: None,
+ usage: BufferUsages::VERTEX | BufferUsages::COPY_DST,
+ });
+ self.vertex_buffers.insert(*pres, Arc::new(buffer));
+ debug!(
+ "vertex attribute buffer created (len={}) {pres}",
+ buf.len() / 4
+ );
+ done.push(*pres);
+ }
}
for pres in &self.parts_needed {
if let Some(buf) = dls.try_get(*pres)? {
@@ -80,64 +121,72 @@ impl ScenePreparer {
self.index_buffers_needed.insert(indexres);
continue;
};
- let mut positions = Vec::new();
+ let mut position = Vec::new();
for vr in positionres {
match vr {
Attribute::Constant(_) => todo!(),
Attribute::Vertex(resource) => {
- let Some(vertex) = self.vertex_buffers.get(&resource).cloned()
- else {
- self.vertex_buffers_needed.insert(indexres);
- continue;
+ if let Some(vertex) = self.vertex_buffers.get(&resource).cloned() {
+ position.push(vertex);
+ } else {
+ self.vertex_buffers_needed.insert(resource);
};
- positions.push(vertex);
}
Attribute::Texture(_resource) => todo!(),
}
}
- let mut normals = Vec::new();
+ let mut normal = Vec::new();
for vr in normalres {
match vr {
Attribute::Constant(_) => todo!(),
Attribute::Vertex(resource) => {
- let Some(vertex) = self.vertex_buffers.get(&resource).cloned()
- else {
- self.vertex_buffers_needed.insert(indexres);
- continue;
+ if let Some(vertex) = self.vertex_buffers.get(&resource).cloned() {
+ normal.push(vertex);
+ } else {
+ self.vertex_buffers_needed.insert(resource);
};
- normals.push(vertex);
}
Attribute::Texture(_resource) => todo!(),
}
}
- let mut texcoords = Vec::new();
+ let mut texcoord = Vec::new();
for vr in texcoordres {
match vr {
Attribute::Constant(_) => todo!(),
Attribute::Vertex(resource) => {
- let Some(vertex) = self.vertex_buffers.get(&resource).cloned()
- else {
- self.vertex_buffers_needed.insert(indexres);
- continue;
+ if let Some(vertex) = self.vertex_buffers.get(&resource).cloned() {
+ texcoord.push(vertex);
+ } else {
+ self.vertex_buffers_needed.insert(resource);
};
- texcoords.push(vertex);
}
Attribute::Texture(_resource) => todo!(),
}
}
- self.parts.insert(
- *pres,
- Arc::new(RPart {
- index_count,
- index,
- texcoord: texcoords.try_into().unwrap(),
- normal: normals.try_into().unwrap(),
- position: positions.try_into().unwrap(),
- }),
- );
+ if texcoord.len() == 2 && normal.len() == 3 && position.len() == 3 {
+ debug!("part created ({pres})");
+ self.parts.insert(
+ *pres,
+ Arc::new(RPart {
+ index_count,
+ index,
+ texcoord: texcoord.try_into().unwrap(),
+ normal: normal.try_into().unwrap(),
+ position: position.try_into().unwrap(),
+ }),
+ );
+ done.push(*pres);
+ }
}
}
}
+
+ for d in done {
+ self.parts_needed.remove(&d);
+ self.prefabs_needed.remove(&d);
+ self.index_buffers_needed.remove(&d);
+ self.vertex_buffers_needed.remove(&d);
+ }
Ok(())
}
}