Skip to main content

mirage_engine/mesh/
part.rs

1use core::fmt::Debug;
2use core::hash::Hash;
3
4/// A name for one repaintable part of a mesh.
5///
6/// Required if you want to repaint one part of a mesh and leave the rest:
7/// derive it on an enum whose variants are the loaded mesh's material
8/// names, and name that enum where the mesh implements
9/// [`Mesh`](crate::mesh::Mesh).
10pub trait Part: Hash + Eq + Clone + Debug {
11    /// The part the material `name` resolves to, or `None` to leave that
12    /// material as authored, which no draw repaints on its own.
13    fn from_name(name: &str) -> Option<Self>;
14
15    /// Every part, in the order [`index`](Part::index) counts them.
16    ///
17    /// Each of them must resolve exactly one material of every loaded mesh
18    /// built over this vocabulary; otherwise startup fails.
19    fn all() -> Vec<Self>;
20
21    /// This part's position in [`all`](Part::all).
22    fn index(&self) -> u32;
23}
24
25/// The vocabulary of a mesh with no parts a draw repaints one at a time.
26///
27/// A mesh that states no part vocabulary reads as this one, so a game
28/// never writes it. It has no value, so no draw of such a mesh can call
29/// [`material_of`](crate::mesh::Instance::material_of);
30/// [`material`](crate::mesh::Instance::material) repaints every slot of
31/// any mesh.
32#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
33pub enum NoParts {}
34
35impl Part for NoParts {
36    /// No material name resolves to a part.
37    fn from_name(_name: &str) -> Option<Self> {
38        None
39    }
40
41    fn all() -> Vec<Self> {
42        Vec::new()
43    }
44
45    fn index(&self) -> u32 {
46        match *self {}
47    }
48}