gemini_engine/mesh3d/components.rs
1use crate::core::ColChar;
2
3/// An alias to [`DVec3`](glam::DVec3), a three-dimensional vector of `f64` values
4pub type Vec3D = glam::DVec3;
5/// An alias to [`DMat4`](glam::DMat4), a 4x4 matrix of `f64` values
6pub type Transform3D = glam::DMat4;
7
8/// A `Face` contains indices to a mesh's collection of vertices and a `ColChar` to fill the face. Indices should be arranged in a clockwise order, as if they appear counter-clockwise when rendering they will not be rendered at all (this is how gemini-engine handles backface culling and maximises performance)
9#[derive(Debug, Clone)]
10pub struct Face {
11 /// The vertex indices of the face
12 pub v_indices: Vec<usize>,
13 /// The desired appearance of the face when rendered
14 pub fill_char: ColChar,
15}
16
17impl Face {
18 /// Create a new face with the given indices and [`ColChar`]
19 #[must_use]
20 pub const fn new(v_indices: Vec<usize>, fill_char: ColChar) -> Self {
21 Self {
22 v_indices,
23 fill_char,
24 }
25 }
26
27 /// Return a vector with the elements found at the vertex indices of the given slice
28 ///
29 /// # Errors
30 /// Will return an error if the passed slice is not long enough to be indexed by the face
31 pub fn index_into<T: Copy>(&self, vertices: &[T]) -> Result<Vec<T>, String> {
32 let mut indexed_vertices = Vec::new();
33 for v_index in &self.v_indices {
34 if let Some(vertex) = vertices.get(*v_index) {
35 indexed_vertices.push(*vertex);
36 } else {
37 return Err(format!(
38 "Mesh face vertex index ({}) is out of bounds ({})",
39 v_index,
40 vertices.len(),
41 ));
42 }
43 }
44 Ok(indexed_vertices)
45 }
46}