Skip to main content

gizmo_engine/
asset_server.rs

1use crate::core::asset::Handle;
2use crate::renderer::async_assets::AsyncAssetLoader;
3use crate::renderer::components::{Material, Mesh};
4use wgpu::util::DeviceExt;
5
6pub struct AssetServer {
7    pub loader: AsyncAssetLoader,
8    mesh_paths: std::collections::HashMap<String, Handle<Mesh>>,
9    _material_paths: std::collections::HashMap<String, Handle<Material>>,
10    pub completed_gltfs: Vec<crate::renderer::async_assets::GltfImportCompletion>,
11    pub completed_gltf_errors: Vec<crate::renderer::async_assets::GltfImportError>,
12}
13
14impl Default for AssetServer {
15    fn default() -> Self {
16        Self::new()
17    }
18}
19
20impl AssetServer {
21    pub fn new() -> Self {
22        Self {
23            loader: AsyncAssetLoader::new(),
24            mesh_paths: std::collections::HashMap::new(),
25            _material_paths: std::collections::HashMap::new(),
26            completed_gltfs: Vec::new(),
27            completed_gltf_errors: Vec::new(),
28        }
29    }
30
31    pub fn load_mesh(&mut self, path: &str) -> Handle<Mesh> {
32        if let Some(handle) = self.mesh_paths.get(path) {
33            return handle.clone();
34        }
35        let handle = Handle::new(); // Generates a new HandleId
36        self.loader.request_obj_load(path.to_string(), handle.id.0);
37        self.mesh_paths.insert(path.to_string(), handle.clone());
38        handle
39    }
40}
41
42pub fn asset_server_update_system(
43    mut server: crate::core::system::ResMut<AssetServer>,
44    renderer: crate::core::system::ResMut<crate::renderer::Renderer>,
45    mut meshes: crate::core::system::ResMut<crate::core::asset::Assets<Mesh>>,
46) {
47    let completed = server.loader.drain_completed();
48
49    server.completed_gltfs.extend(completed.gltfs);
50    server.completed_gltf_errors.extend(completed.gltf_errors);
51
52    if completed.objs.is_empty() && completed.textures.is_empty() {
53        return;
54    }
55
56    for obj in completed.objs {
57        let mesh_source = format!("obj:{}", obj.path);
58        // Create wgpu buffer
59        let vbuf = renderer
60            .device
61            .create_buffer_init(&wgpu::util::BufferInitDescriptor {
62                label: Some(&format!("Obj VBuf: {}", obj.path)),
63                contents: bytemuck::cast_slice(&obj.vertices),
64                usage: wgpu::BufferUsages::VERTEX,
65            });
66        let mesh = Mesh::new(
67            &renderer.device,
68            std::sync::Arc::new(vbuf),
69            &obj.vertices,
70            gizmo_math::Vec3::ZERO,
71            mesh_source,
72        );
73        for handle_id in obj.handle_ids {
74            let handle = crate::core::asset::Handle::weak(crate::core::asset::HandleId(handle_id));
75            meshes.insert(&handle, mesh.clone());
76        }
77    }
78}
79
80pub struct AssetServerPlugin;
81
82impl<State: 'static> crate::app::Plugin<State> for AssetServerPlugin {
83    fn build(&self, app: &mut crate::app::App<State>) {
84        app.world.insert_resource(AssetServer::new());
85        app.schedule.add_di_system(asset_server_update_system);
86    }
87}