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}