1#[derive(Debug, Clone, Copy, PartialEq)]
5pub struct Vertex {
6 pub position: [f32; 3],
8 pub normal: [f32; 3],
10 pub uv: [f32; 2],
12 pub color: [f32; 4],
14}
15
16impl Vertex {
17 pub fn new(position: [f32; 3], normal: [f32; 3], uv: [f32; 2]) -> Self {
18 Self {
19 position,
20 normal,
21 uv,
22 color: [1.0, 1.0, 1.0, 1.0], }
24 }
25
26 pub fn with_color(mut self, color: [f32; 4]) -> Self {
27 self.color = color;
28 self
29 }
30}
31
32impl Default for Vertex {
33 fn default() -> Self {
34 Self {
35 position: [0.0, 0.0, 0.0],
36 normal: [0.0, 1.0, 0.0],
37 uv: [0.0, 0.0],
38 color: [1.0, 1.0, 1.0, 1.0],
39 }
40 }
41}
42
43#[derive(Debug, Clone, Default)]
45pub struct Mesh {
46 pub vertices: Vec<Vertex>,
48 pub indices: Vec<u32>,
50}
51
52impl Mesh {
53 pub fn new() -> Self {
54 Self::default()
55 }
56
57 pub fn add_vertex(&mut self, vertex: Vertex) -> u32 {
59 let index = self.vertices.len() as u32;
60 self.vertices.push(vertex);
61 index
62 }
63
64 pub fn add_triangle(&mut self, i0: u32, i1: u32, i2: u32) {
66 self.indices.push(i0);
67 self.indices.push(i1);
68 self.indices.push(i2);
69 }
70
71 pub fn add_quad(&mut self, i0: u32, i1: u32, i2: u32, i3: u32) {
74 self.add_triangle(i0, i2, i1);
77 self.add_triangle(i0, i3, i2);
79 }
80
81 pub fn add_quad_ao(&mut self, i0: u32, i1: u32, i2: u32, i3: u32, ao: [u8; 4]) {
84 if ao[0] as u16 + ao[2] as u16 > ao[1] as u16 + ao[3] as u16 {
87 self.add_triangle(i1, i0, i3);
90 self.add_triangle(i1, i3, i2);
91 } else {
92 self.add_triangle(i0, i2, i1);
94 self.add_triangle(i0, i3, i2);
95 }
96 }
97
98 pub fn triangle_count(&self) -> usize {
100 self.indices.len() / 3
101 }
102
103 pub fn vertex_count(&self) -> usize {
105 self.vertices.len()
106 }
107
108 pub fn is_empty(&self) -> bool {
110 self.vertices.is_empty()
111 }
112
113 pub fn merge(&mut self, other: &Mesh) {
115 let offset = self.vertices.len() as u32;
116
117 self.vertices.extend_from_slice(&other.vertices);
118
119 for index in &other.indices {
120 self.indices.push(index + offset);
121 }
122 }
123
124 pub fn translate(&mut self, offset: [f32; 3]) {
126 for vertex in &mut self.vertices {
127 vertex.position[0] += offset[0];
128 vertex.position[1] += offset[1];
129 vertex.position[2] += offset[2];
130 }
131 }
132
133 pub fn positions_flat(&self) -> Vec<f32> {
135 self.vertices
136 .iter()
137 .flat_map(|v| v.position)
138 .collect()
139 }
140
141 pub fn normals_flat(&self) -> Vec<f32> {
143 self.vertices
144 .iter()
145 .flat_map(|v| v.normal)
146 .collect()
147 }
148
149 pub fn uvs_flat(&self) -> Vec<f32> {
151 self.vertices
152 .iter()
153 .flat_map(|v| v.uv)
154 .collect()
155 }
156
157 pub fn colors_flat(&self) -> Vec<f32> {
159 self.vertices
160 .iter()
161 .flat_map(|v| v.color)
162 .collect()
163 }
164}
165
166#[cfg(test)]
167mod tests {
168 use super::*;
169
170 #[test]
171 fn test_mesh_creation() {
172 let mut mesh = Mesh::new();
173 assert!(mesh.is_empty());
174
175 let v0 = mesh.add_vertex(Vertex::new([0.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0]));
176 let v1 = mesh.add_vertex(Vertex::new([1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 0.0]));
177 let v2 = mesh.add_vertex(Vertex::new([1.0, 0.0, 1.0], [0.0, 1.0, 0.0], [1.0, 1.0]));
178
179 mesh.add_triangle(v0, v1, v2);
180
181 assert_eq!(mesh.vertex_count(), 3);
182 assert_eq!(mesh.triangle_count(), 1);
183 }
184
185 #[test]
186 fn test_mesh_quad() {
187 let mut mesh = Mesh::new();
188
189 let v0 = mesh.add_vertex(Vertex::new([0.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0]));
190 let v1 = mesh.add_vertex(Vertex::new([1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 0.0]));
191 let v2 = mesh.add_vertex(Vertex::new([1.0, 0.0, 1.0], [0.0, 1.0, 0.0], [1.0, 1.0]));
192 let v3 = mesh.add_vertex(Vertex::new([0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [0.0, 1.0]));
193
194 mesh.add_quad(v0, v1, v2, v3);
195
196 assert_eq!(mesh.vertex_count(), 4);
197 assert_eq!(mesh.triangle_count(), 2);
198 assert_eq!(mesh.indices, vec![0, 2, 1, 0, 3, 2]);
200 }
201
202 #[test]
203 fn test_mesh_merge() {
204 let mut mesh1 = Mesh::new();
205 let v0 = mesh1.add_vertex(Vertex::new([0.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0]));
206 let v1 = mesh1.add_vertex(Vertex::new([1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 0.0]));
207 let v2 = mesh1.add_vertex(Vertex::new([0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [0.0, 1.0]));
208 mesh1.add_triangle(v0, v1, v2);
209
210 let mut mesh2 = Mesh::new();
211 let v0 = mesh2.add_vertex(Vertex::new([2.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0]));
212 let v1 = mesh2.add_vertex(Vertex::new([3.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 0.0]));
213 let v2 = mesh2.add_vertex(Vertex::new([2.0, 0.0, 1.0], [0.0, 1.0, 0.0], [0.0, 1.0]));
214 mesh2.add_triangle(v0, v1, v2);
215
216 mesh1.merge(&mesh2);
217
218 assert_eq!(mesh1.vertex_count(), 6);
219 assert_eq!(mesh1.triangle_count(), 2);
220 assert_eq!(mesh1.indices, vec![0, 1, 2, 3, 4, 5]);
222 }
223}