summaryrefslogtreecommitdiff
path: root/client/src/scene_prepare.rs
blob: 5376145bda6523ff07a22499d9d692b4c72781d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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<Resource, Arc<Buffer>>,
    index_buffers_needed: HashSet<Resource>,
    vertex_buffers: HashMap<Resource, Arc<Buffer>>,
    vertex_buffers_needed: HashSet<Resource>,
    parts: HashMap<Resource, Arc<RPart>>,
    parts_needed: HashSet<Resource>,
    prefabs: HashMap<Resource, RPrefab>,
    prefabs_needed: HashSet<Resource>,
}

pub struct RPrefab(pub Vec<(Affine3A, Arc<RPart>)>);
pub struct RPart {
    pub index_count: u32,
    pub index: Arc<Buffer>,
    pub positions: Arc<Buffer>,
    pub normals: Arc<Buffer>,
}

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(())
    }
}