lambda/render/
mesh.rs

1//! Mesh Implementation
2
3use lambda_platform::obj::load_textured_obj_from_file;
4
5use super::{
6  vertex::{
7    Vertex,
8    VertexAttribute,
9    VertexElement,
10  },
11  ColorFormat,
12};
13
14// ---------------------------------- Mesh ------------------------------------
15
16/// Collection of vertices and indices that define a 3D object.
17#[derive(Debug)]
18pub struct Mesh {
19  vertices: Vec<Vertex>,
20  attributes: Vec<VertexAttribute>,
21}
22
23impl Mesh {
24  /// Gets the vertices of the mesh.
25  pub fn vertices(&self) -> &[Vertex] {
26    &self.vertices
27  }
28
29  /// Gets the attributes of the mesh.
30  pub fn attributes(&self) -> &[VertexAttribute] {
31    &self.attributes
32  }
33}
34
35// ------------------------------ MeshBuilder ---------------------------------
36
37/// Construction for a mesh.
38#[derive(Clone, Debug)]
39pub struct MeshBuilder {
40  capacity: usize,
41  vertices: Vec<Vertex>,
42  attributes: Vec<VertexAttribute>,
43}
44
45impl MeshBuilder {
46  /// Creates a new mesh builder.
47  pub fn new() -> Self {
48    return Self {
49      capacity: 0,
50      vertices: Vec::new(),
51      attributes: Vec::new(),
52    };
53  }
54
55  /// Allocates memory for the given number of vertices and fills
56  /// the mesh with empty vertices.
57  pub fn with_capacity(&mut self, size: usize) -> &mut Self {
58    self.capacity = size;
59    self.vertices.resize(
60      size,
61      Vertex {
62        position: [0.0, 0.0, 0.0],
63        normal: [0.0, 0.0, 0.0],
64        color: [0.0, 0.0, 0.0],
65      },
66    );
67    return self;
68  }
69
70  /// Adds a vertex to the mesh.
71  pub fn with_vertex(&mut self, vertex: Vertex) -> &mut Self {
72    self.vertices.push(vertex);
73    return self;
74  }
75
76  /// Specify the attributes of the mesh. This is used to map the vertex data to
77  /// the input of the vertex shader.
78  pub fn with_attributes(
79    &mut self,
80    attributes: Vec<VertexAttribute>,
81  ) -> &mut Self {
82    self.attributes = attributes;
83    return self;
84  }
85
86  /// Builds a mesh from the vertices and indices that have been added to the
87  /// builder and allocates the memory for the mesh on the GPU.
88  pub fn build(&self) -> Mesh {
89    return Mesh {
90      vertices: self.vertices.clone(),
91      attributes: self.attributes.clone(),
92    };
93  }
94
95  /// Builds a mesh from the vertices of an OBJ file. The mesh will have the same
96  /// attributes as the OBJ file and can be allocated on to the GPU with
97  /// `BufferBuilder::build_from_mesh`.
98  pub fn build_from_obj(&self, file_path: &str) -> Mesh {
99    let obj = load_textured_obj_from_file(file_path);
100
101    let vertices = obj
102      .vertices
103      .iter()
104      .map(|v| {
105        return Vertex {
106          position: v.position,
107          normal: v.normal,
108          color: [1.0, 1.0, 1.0],
109        };
110      })
111      .collect::<Vec<Vertex>>();
112
113    // Returns a mesh with the given vertices with attributes for position,
114    // normal, and color.
115    return Mesh {
116      vertices,
117      attributes: vec![
118        VertexAttribute {
119          location: 0,
120          offset: 0,
121          element: VertexElement {
122            format: ColorFormat::Rgb32Sfloat,
123            offset: 0,
124          },
125        },
126        VertexAttribute {
127          location: 1,
128          offset: 0,
129          element: VertexElement {
130            format: ColorFormat::Rgb32Sfloat,
131            offset: 12,
132          },
133        },
134        VertexAttribute {
135          location: 2,
136          offset: 0,
137          element: VertexElement {
138            format: ColorFormat::Rgb32Sfloat,
139            offset: 24,
140          },
141        },
142      ],
143    };
144  }
145}
146
147#[cfg(test)]
148mod tests {
149  #[test]
150  fn mesh_building() {
151    let mut mesh = super::MeshBuilder::new();
152
153    assert_eq!(mesh.vertices.len(), 0);
154  }
155}