1use super::create::create_mesh;
7use super::types::{MeshData, MeshDef};
8use crate::math_functions::{add, cos, sin, Vec3, PI, TWO_PI};
9
10pub fn create_grid_mesh(
12 x_count: i32,
13 z_count: i32,
14 cell_width: f32,
15 material_count: i32,
16 identify_edges: bool,
17) -> Option<MeshData> {
18 debug_assert!((0..=u8::MAX as i32).contains(&material_count));
19
20 let vertex_count = (x_count + 1) * (z_count + 1);
21 let mut vertices = vec![Vec3::default(); vertex_count as usize];
22 let mut index = 0usize;
23
24 let x_width = cell_width * (x_count as f32);
25 let z_width = cell_width * (z_count as f32);
26
27 let mut x = -0.5 * x_width;
28 for _ix in 0..=x_count {
29 let mut z = -0.5 * z_width;
30 for _iz in 0..=z_count {
31 vertices[index] = Vec3 { x, y: 0.0, z };
32 z += cell_width;
33 index += 1;
34 }
35 x += cell_width;
36 }
37 debug_assert!(index == vertex_count as usize);
38
39 let triangle_count = 2 * x_count * z_count;
40 let mut indices = vec![0i32; (3 * triangle_count) as usize];
41 let mut material_indices = vec![0u8; triangle_count as usize];
42
43 let mut material_index = 0i32;
44 index = 0;
45 for ix in 0..x_count {
46 for iz in 0..z_count {
47 let index1 = iz + (z_count + 1) * ix;
48 let index2 = index1 + 1;
49 let index3 = index2 + (z_count + 1);
50 let index4 = index3 - 1;
51
52 debug_assert!(index1 < vertex_count);
53 debug_assert!(index2 < vertex_count);
54 debug_assert!(index3 < vertex_count);
55 debug_assert!(index4 < vertex_count);
56
57 indices[index] = index1;
58 indices[index + 1] = index2;
59 indices[index + 2] = index3;
60 indices[index + 3] = index3;
61 indices[index + 4] = index4;
62 indices[index + 5] = index1;
63
64 if material_count > 0 {
65 material_indices[(2 * material_index) as usize] =
66 (material_index % material_count) as u8;
67 material_indices[(2 * material_index + 1) as usize] =
68 (material_index % material_count) as u8;
69 }
70
71 material_index += 1;
72 index += 6;
73 }
74 }
75 debug_assert!(index == (3 * triangle_count) as usize);
76
77 let def = MeshDef {
78 vertices,
79 indices,
80 material_indices: if material_count > 0 {
81 material_indices
82 } else {
83 Vec::new()
84 },
85 use_median_split: true,
86 identify_edges,
87 ..Default::default()
88 };
89
90 create_mesh(&def, None)
91}
92
93pub fn create_wave_mesh(
97 x_count: i32,
98 z_count: i32,
99 cell_width: f32,
100 amplitude: f32,
101 row_frequency: f32,
102 column_frequency: f32,
103) -> Option<MeshData> {
104 let vertex_count = (x_count + 1) * (z_count + 1);
105 let mut vertices = vec![Vec3::default(); vertex_count as usize];
106 let mut index = 0usize;
107
108 let x_width = cell_width * (x_count as f32);
109 let z_width = cell_width * (z_count as f32);
110
111 let omega_z = 2.0 * PI * row_frequency * cell_width;
112 let omega_x = 2.0 * PI * column_frequency * cell_width;
113
114 let mut x = -0.5 * x_width;
115 for ix in 0..=x_count {
116 let row_height = (omega_x * (ix as f32)).sin();
117 let mut z = -0.5 * z_width;
118 for iz in 0..=z_count {
119 let column_height = (omega_z * (iz as f32)).sin();
120 let y = amplitude * row_height * column_height;
121 vertices[index] = Vec3 { x, y, z };
122 z += cell_width;
123 index += 1;
124 }
125 x += cell_width;
126 }
127 debug_assert!(index == vertex_count as usize);
128
129 let triangle_count = 2 * x_count * z_count;
130 let mut indices = vec![0i32; (3 * triangle_count) as usize];
131 index = 0;
132 for ix in 0..x_count {
133 for iz in 0..z_count {
134 let index1 = iz + (z_count + 1) * ix;
135 let index2 = index1 + 1;
136 let index3 = index2 + (z_count + 1);
137 let index4 = index3 - 1;
138
139 indices[index] = index1;
140 indices[index + 1] = index2;
141 indices[index + 2] = index3;
142 indices[index + 3] = index3;
143 indices[index + 4] = index4;
144 indices[index + 5] = index1;
145 index += 6;
146 }
147 }
148 debug_assert!(index == (3 * triangle_count) as usize);
149
150 let def = MeshDef {
151 vertices,
152 indices,
153 use_median_split: true,
154 identify_edges: true,
155 ..Default::default()
156 };
157
158 create_mesh(&def, None)
159}
160
161pub fn create_torus_mesh(
163 radial_resolution: i32,
164 tubular_resolution: i32,
165 radius: f32,
166 thickness: f32,
167) -> Option<MeshData> {
168 let mut vertices = Vec::new();
169
170 for radial_index in 0..radial_resolution {
171 for tubular_index in 0..tubular_resolution {
172 let u = (tubular_index as f32) / (tubular_resolution as f32) * TWO_PI;
173 let v = (radial_index as f32) / (radial_resolution as f32) * TWO_PI;
174
175 let x = (radius + thickness * cos(v)) * cos(u);
176 let y = (radius + thickness * cos(v)) * sin(u);
177 let z = thickness * sin(v);
178
179 vertices.push(Vec3 { x, y, z });
180 }
181 }
182
183 let mut indices = Vec::new();
184 for radial_index1 in 0..radial_resolution {
185 let radial_index2 = (radial_index1 + 1) % radial_resolution;
186 for tubular_index1 in 0..tubular_resolution {
187 let tubular_index2 = (tubular_index1 + 1) % tubular_resolution;
188 let index1 = radial_index1 * tubular_resolution + tubular_index1;
189 let index2 = radial_index1 * tubular_resolution + tubular_index2;
190 let index3 = radial_index2 * tubular_resolution + tubular_index2;
191 let index4 = radial_index2 * tubular_resolution + tubular_index1;
192
193 indices.push(index1);
194 indices.push(index2);
195 indices.push(index3);
196 indices.push(index3);
197 indices.push(index4);
198 indices.push(index1);
199 }
200 }
201
202 let def = MeshDef {
203 vertices,
204 indices,
205 use_median_split: false,
206 identify_edges: true,
207 ..Default::default()
208 };
209
210 create_mesh(&def, None)
211}
212
213pub fn create_box_mesh(center: Vec3, extent: Vec3, identify_edges: bool) -> Option<MeshData> {
215 let x = extent.x;
216 let y = extent.y;
217 let z = extent.z;
218 let mut vertices = [
219 Vec3 { x, y, z },
220 Vec3 { x: -x, y, z },
221 Vec3 { x: -x, y: -y, z },
222 Vec3 { x, y: -y, z },
223 Vec3 { x, y, z: -z },
224 Vec3 { x: -x, y, z: -z },
225 Vec3 {
226 x: -x,
227 y: -y,
228 z: -z,
229 },
230 Vec3 { x, y: -y, z: -z },
231 ];
232
233 for v in &mut vertices {
234 *v = add(*v, center);
235 }
236
237 let indices = [
238 0, 1, 3, 1, 2, 3, 0, 4, 1, 1, 4, 5, 0, 3, 7, 4, 0, 7, 4, 7, 5, 6, 5, 7, 1, 5, 2, 6, 2, 5, 3, 2, 7, 6, 7, 2, ];
245
246 let def = MeshDef {
247 vertices: vertices.to_vec(),
248 indices: indices.to_vec(),
249 use_median_split: false,
250 identify_edges,
251 ..Default::default()
252 };
253
254 create_mesh(&def, None)
255}
256
257pub fn create_hollow_box_mesh(center: Vec3, extent: Vec3) -> Option<MeshData> {
259 let x = extent.x;
260 let y = extent.y;
261 let z = extent.z;
262 let mut vertices = [
263 Vec3 { x, y, z },
264 Vec3 { x: -x, y, z },
265 Vec3 { x: -x, y: -y, z },
266 Vec3 { x, y: -y, z },
267 Vec3 { x, y, z: -z },
268 Vec3 { x: -x, y, z: -z },
269 Vec3 {
270 x: -x,
271 y: -y,
272 z: -z,
273 },
274 Vec3 { x, y: -y, z: -z },
275 ];
276
277 for v in &mut vertices {
278 *v = add(*v, center);
279 }
280
281 let indices = [
282 3, 1, 0, 3, 2, 1, 1, 4, 0, 5, 4, 1, 7, 3, 0, 7, 0, 4, 5, 7, 4, 7, 5, 6, 2, 5, 1, 5, 2, 6, 7, 2, 3, 2, 7, 6, ];
289
290 let def = MeshDef {
291 vertices: vertices.to_vec(),
292 indices: indices.to_vec(),
293 use_median_split: false,
294 identify_edges: true,
295 ..Default::default()
296 };
297
298 create_mesh(&def, None)
299}
300
301pub fn create_platform_mesh(
303 center: Vec3,
304 height: f32,
305 top_width: f32,
306 bottom_width: f32,
307) -> Option<MeshData> {
308 let hb = 0.5 * bottom_width;
309 let ht = 0.5 * top_width;
310 let hy = 0.5 * height;
311 let mut vertices = [
312 Vec3 {
313 x: ht,
314 y: hy,
315 z: ht,
316 },
317 Vec3 {
318 x: -ht,
319 y: hy,
320 z: ht,
321 },
322 Vec3 {
323 x: -hb,
324 y: -hy,
325 z: hb,
326 },
327 Vec3 {
328 x: hb,
329 y: -hy,
330 z: hb,
331 },
332 Vec3 {
333 x: ht,
334 y: hy,
335 z: -ht,
336 },
337 Vec3 {
338 x: -ht,
339 y: hy,
340 z: -ht,
341 },
342 Vec3 {
343 x: -hb,
344 y: -hy,
345 z: -hb,
346 },
347 Vec3 {
348 x: hb,
349 y: -hy,
350 z: -hb,
351 },
352 ];
353
354 for v in &mut vertices {
355 *v = add(*v, center);
356 }
357
358 let indices = [
359 0, 1, 3, 1, 2, 3, 0, 4, 1, 1, 4, 5, 0, 3, 7, 4, 0, 7, 4, 7, 5, 6, 5, 7, 1, 5, 2, 6, 2, 5, 3, 2, 7, 6, 7, 2, ];
366
367 let def = MeshDef {
368 vertices: vertices.to_vec(),
369 indices: indices.to_vec(),
370 use_median_split: true,
371 identify_edges: true,
372 ..Default::default()
373 };
374
375 create_mesh(&def, None)
376}