use crate::download::Downloader; use anyhow::Result; use std::{ collections::{HashMap, HashSet}, sync::Arc, }; use weareshared::{ Affine3A, packets::{ReadWrite, Resource}, resources::{Attribute, Part, Prefab}, }; use wgpu::Buffer; pub struct ScenePreparer { index_buffers: HashMap>, index_buffers_needed: HashSet, vertex_buffers: HashMap>, vertex_buffers_needed: HashSet, parts: HashMap>, parts_needed: HashSet, prefabs: HashMap, prefabs_needed: HashSet, } pub struct RPrefab(pub Vec<(Affine3A, Arc)>); pub struct RPart { pub index_count: u32, pub index: Arc, pub positions: Arc, pub normals: Arc, } impl ScenePreparer { pub fn new() -> Self { Self { index_buffers: HashMap::new(), vertex_buffers: HashMap::new(), vertex_buffers_needed: HashSet::new(), parts: HashMap::new(), parts_needed: HashSet::new(), prefabs: HashMap::new(), prefabs_needed: HashSet::new(), index_buffers_needed: HashSet::new(), } } pub fn update(&mut self, dls: &mut Downloader) -> Result<()> { let mut done = Vec::new(); for pres in &self.prefabs_needed { if let Some(buf) = dls.try_get(*pres)? { let prefab = Prefab::read(&mut buf.as_slice())?; let mut rprefab = RPrefab(Vec::new()); for (aff, partres) in &prefab.0 { if let Some(part) = self.parts.get(partres) { rprefab.0.push((*aff, part.clone())); } else { self.parts_needed.insert(*partres); } } if rprefab.0.len() == prefab.0.len() { self.prefabs.insert(*pres, rprefab); done.push(*pres); } } } for pres in &self.parts_needed { if let Some(buf) = dls.try_get(*pres)? { let part = Part::read(&mut buf.as_slice())?; if let Some(indexres) = part.index { if let Some(vertexres) = part.va_position { let Some(index) = self.index_buffers.get(&indexres) else { self.index_buffers_needed.insert(indexres); continue; }; for vr in vertexres { match vr { Attribute::Constant(_) => todo!(), Attribute::Vertex(resource) => { let Some(vertex) = self.index_buffers.get(&resource) else { self.index_buffers_needed.insert(indexres); continue; }; } Attribute::Texture(resource) => todo!(), } } } } } } Ok(()) } }