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
use crate::graph::SceneDescriptor;
use crate::{Materials, Mesh3D, SceneError};
use rfw_backend::MeshId3D;
use rfw_utils::collections::TrackedStorage;
use std::path::PathBuf;

pub mod gltf;
pub mod obj;

#[derive(Debug, Clone)]
pub enum LoadResult {
    /// Reference to single mesh
    Object(MeshId3D),
    /// Indices of root nodes of scene
    Scene(SceneDescriptor),
}

#[derive(Debug, Clone)]
pub enum Error {
    ResultIsScene,
    ResultIsMesh,
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "Error({})",
            match self {
                Error::ResultIsScene => "Result is a scene, not a mesh",
                Error::ResultIsMesh => "Result is a mesh, not a scene",
            }
        )
    }
}

impl std::error::Error for Error {}

impl LoadResult {
    pub fn object(self) -> Result<MeshId3D, Error> {
        match self {
            LoadResult::Object(obj) => Ok(obj),
            LoadResult::Scene(_) => Err(Error::ResultIsScene),
        }
    }

    pub fn scene(self) -> Result<SceneDescriptor, Error> {
        match self {
            LoadResult::Scene(scene) => Ok(scene),
            LoadResult::Object(_) => Err(Error::ResultIsMesh),
        }
    }
}

pub trait ObjectLoader: std::fmt::Display + std::fmt::Debug + Send + Sync {
    fn load(
        &self,
        path: PathBuf,
        mat_manager: &mut Materials,
        mesh_storage: &mut TrackedStorage<Mesh3D>,
    ) -> Result<LoadResult, SceneError>;

    fn load_from_str(
        &self,
        string: &str,
        mat_manager: &mut Materials,
        mesh_storage: &mut TrackedStorage<Mesh3D>
    )  -> Result<LoadResult, SceneError>;
}