1pub mod gltfLoader;
4use std::sync::Arc;
5use vulkano::buffer::{Buffer, BufferCreateInfo, BufferUsage, Subbuffer};
6use vulkano::memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator};
7use vulkano::pipeline::graphics::vertex_input::Vertex;
8pub trait VertexType: Vertex + bytemuck::Pod + bytemuck::Zeroable + Send + Sync {}
10
11#[repr(C)]
13#[derive(Copy, Clone, Debug, Vertex, bytemuck::Pod, bytemuck::Zeroable)]
14pub struct VertexPosColor {
15 #[format(R32G32B32_SFLOAT)]
16 pub position: [f32; 3], #[format(R32G32B32_SFLOAT)]
18 pub color: [f32; 3], #[format(R32G32B32_SFLOAT)]
20 pub barycentric: [f32; 3],
21}
22
23impl VertexType for VertexPosColor {}
24
25#[repr(C)]
27#[derive(Copy, Clone, Debug, Vertex, bytemuck::Pod, bytemuck::Zeroable)]
28pub struct VertexPosColorUv {
29 #[format(R32G32B32_SFLOAT)]
30 pub position: [f32; 3], #[format(R32G32B32_SFLOAT)]
32 pub normal: [f32; 3], #[format(R32G32_SFLOAT)]
34 pub uv: [f32; 2], }
36
37impl VertexType for VertexPosColorUv {}
38
39#[repr(C)]
41#[derive(Copy, Clone, Debug, Vertex, bytemuck::Pod, bytemuck::Zeroable)]
42pub struct VertexPosColorNormal {
43 #[format(R32G32B32_SFLOAT)]
44 pub position: [f32; 3], #[format(R32G32B32_SFLOAT)]
46 pub color: [f32; 3], #[format(R32G32B32_SFLOAT)]
48 pub normal: [f32; 3], #[format(R32G32B32_SFLOAT)]
50 pub barycentric: [f32; 3], }
52
53impl VertexType for VertexPosColorNormal {}
54
55#[derive(Clone)]
57pub struct Mesh {
58 pub vertices: Subbuffer<[VertexPosColorUv]>, pub indices: Option<Subbuffer<[u32]>>, pub vertex_count: u32, pub index_count: u32, pub base_color_texture: Option<usize>,
63}
64
65impl Mesh {
66 pub fn new(
68 memory_allocator: &Arc<StandardMemoryAllocator>,
69 vertices: &[VertexPosColorUv],
70 indices: Option<&[u32]>,
71 ) -> Self {
72 let vertex_buffer = Buffer::from_iter(
74 &memory_allocator.clone(),
75 BufferCreateInfo {
76 usage: BufferUsage::VERTEX_BUFFER,
77 ..Default::default()
78 },
79 AllocationCreateInfo {
80 usage: MemoryUsage::Upload,
81 ..Default::default()
82 },
83 vertices.iter().copied(),
84 )
85 .unwrap();
86
87 let vertex_count = vertices.len() as u32;
88
89 let (index_buffer, index_count) = if let Some(indices) = indices {
91 let buffer = Buffer::from_iter(
92 &memory_allocator.clone(),
93 BufferCreateInfo {
94 usage: BufferUsage::INDEX_BUFFER,
95 ..Default::default()
96 },
97 AllocationCreateInfo {
98 usage: MemoryUsage::Upload,
99 ..Default::default()
100 },
101 indices.iter().copied(),
102 )
103 .unwrap();
104 (Some(buffer), indices.len() as u32)
105 } else {
106 (None, 0)
107 };
108
109 Self {
110 vertices: vertex_buffer,
111 indices: index_buffer,
112 vertex_count,
113 index_count,
114 base_color_texture: None,
115 }
116 }
117
118 pub fn new_indexed(
120 memory_allocator: &Arc<StandardMemoryAllocator>,
121 vertices: &[VertexPosColorUv],
122 indices: &[u32],
123 ) -> Self {
124 Self::new(memory_allocator, vertices, Some(indices))
125 }
126}
127
128pub mod shapes {
132 use super::*;
133 use std::f32::consts::PI;
134
135 fn normalize(v: [f32; 3]) -> [f32; 3] {
137 let len = (v[0] * v[0] + v[1] * v[1] + v[2] * v[2]).sqrt();
138 if len > 0.0 {
139 [v[0] / len, v[1] / len, v[2] / len]
140 } else {
141 v
142 }
143 }
144
145 fn calculate_normal(p1: [f32; 3], p2: [f32; 3], p3: [f32; 3]) -> [f32; 3] {
146 let u = [p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]];
147 let v = [p3[0] - p1[0], p3[1] - p1[1], p3[2] - p1[2]];
148
149 let normal = [
151 u[1] * v[2] - u[2] * v[1],
152 u[2] * v[0] - u[0] * v[2],
153 u[0] * v[1] - u[1] * v[0],
154 ];
155
156 normalize(normal)
157 }
158
159 fn add_triangle(
161 vertices: &mut Vec<VertexPosColorUv>,
162 p1: [f32; 3],
163 p2: [f32; 3],
164 p3: [f32; 3],
165 ) {
166 let normal = calculate_normal(p1, p2, p3);
168
169 vertices.push(VertexPosColorUv {
170 position: p1,
171 normal,
172 uv: [1.0, 1.0],
173 });
174 vertices.push(VertexPosColorUv {
175 position: p2,
176 normal,
177 uv: [1.0, 1.0],
178 });
179 vertices.push(VertexPosColorUv {
180 position: p3,
181 normal,
182 uv: [1.0, 1.0],
183 });
184 }
185
186 fn add_wrong_triangle(
188 vertices: &mut Vec<VertexPosColorUv>,
189 p1: [f32; 3],
190 p2: [f32; 3],
191 p3: [f32; 3],
192 ) {
193 let mut normal = calculate_normal(p1, p2, p3);
195 normal[0] *= -1.0;
196 normal[1] *= -1.0;
197 normal[2] *= -1.0;
198 vertices.push(VertexPosColorUv {
199 position: p1,
200 normal,
201 uv: [1.0, 1.0],
202 });
203 vertices.push(VertexPosColorUv {
204 position: p2,
205 normal,
206 uv: [1.0, 1.0],
207 });
208 vertices.push(VertexPosColorUv {
209 position: p3,
210 normal,
211 uv: [1.0, 1.0],
212 });
213 }
214
215 fn add_quad(
218 vertices: &mut Vec<VertexPosColorUv>,
219 p1: [f32; 3],
220 p2: [f32; 3],
221 p3: [f32; 3],
222 p4: [f32; 3],
223 ) {
224 let normal1 = calculate_normal(p1, p2, p3);
226 let normal2 = calculate_normal(p3, p4, p1);
228
229 vertices.push(VertexPosColorUv {
231 position: p1,
232 normal: normal1,
233 uv: [1.0, 1.0],
234 });
235 vertices.push(VertexPosColorUv {
236 position: p2,
237 normal: normal1,
238 uv: [1.0, 1.0],
239 });
240 vertices.push(VertexPosColorUv {
241 position: p3,
242 normal: normal1,
243 uv: [1.0, 1.0],
244 });
245
246 vertices.push(VertexPosColorUv {
248 position: p3,
249 normal: normal2,
250 uv: [1.0, 1.0],
251 });
252 vertices.push(VertexPosColorUv {
253 position: p4,
254 normal: normal2,
255 uv: [1.0, 1.0],
256 });
257 vertices.push(VertexPosColorUv {
258 position: p1,
259 normal: normal2,
260 uv: [1.0, 1.0],
261 });
262 }
263
264 pub fn create_triangle(memory_allocator: &Arc<StandardMemoryAllocator>) -> Mesh {
265 let mut vertices: Vec<VertexPosColorUv> = Vec::new();
266
267 let v = [[-0.5, -0.5, 0.0], [0.5, -0.5, 0.0], [0.0, 0.5, 0.0]];
268
269 add_triangle(&mut vertices, v[0], v[1], v[2]);
271
272 Mesh::new(memory_allocator, &vertices, None)
273 }
274
275 pub fn create_cube(
277 memory_allocator: &Arc<StandardMemoryAllocator>,
278 ) -> Mesh {
279 let mut vertices: Vec<VertexPosColorUv> = Vec::new();
280
281 let v = [
282 [-0.5, -0.5, 0.5],
283 [0.5, -0.5, 0.5],
284 [0.5, 0.5, 0.5],
285 [-0.5, 0.5, 0.5],
286 [-0.5, -0.5, -0.5],
287 [0.5, -0.5, -0.5],
288 [0.5, 0.5, -0.5],
289 [-0.5, 0.5, -0.5],
290 ];
291
292 add_triangle(&mut vertices, v[0], v[1], v[2]);
294 add_triangle(&mut vertices, v[2], v[3], v[0]);
295
296 add_triangle(&mut vertices, v[1], v[5], v[6]);
298 add_triangle(&mut vertices, v[6], v[2], v[1]);
299
300 add_triangle(&mut vertices, v[5], v[4], v[7]);
302 add_triangle(&mut vertices, v[7], v[6], v[5]);
303
304 add_triangle(&mut vertices, v[4], v[0], v[3]);
306 add_triangle(&mut vertices, v[3], v[7], v[4]);
307
308 add_triangle(&mut vertices, v[3], v[2], v[6]);
310 add_triangle(&mut vertices, v[6], v[7], v[3]);
311
312 add_triangle(&mut vertices, v[4], v[5], v[1]);
314 add_triangle(&mut vertices, v[1], v[0], v[4]);
315
316 Mesh::new(memory_allocator, &vertices, None)
317 }
318
319 pub fn create_wrong_cube(memory_allocator: &Arc<StandardMemoryAllocator>) -> Mesh {
321 let mut vertices: Vec<VertexPosColorUv> = Vec::new();
322
323 let v = [
324 [-0.5, -0.5, 0.5],
325 [0.5, -0.5, 0.5],
326 [0.5, 0.5, 0.5],
327 [-0.5, 0.5, 0.5],
328 [-0.5, -0.5, -0.5],
329 [0.5, -0.5, -0.5],
330 [0.5, 0.5, -0.5],
331 [-0.5, 0.5, -0.5],
332 ];
333
334 add_wrong_triangle(&mut vertices, v[0], v[1], v[2]);
336 add_wrong_triangle(&mut vertices, v[2], v[3], v[0]);
337
338 add_wrong_triangle(&mut vertices, v[1], v[5], v[6]);
340 add_wrong_triangle(&mut vertices, v[6], v[2], v[1]);
341
342 add_wrong_triangle(&mut vertices, v[5], v[4], v[7]);
344 add_wrong_triangle(&mut vertices, v[7], v[6], v[5]);
345
346 add_wrong_triangle(&mut vertices, v[4], v[0], v[3]);
348 add_wrong_triangle(&mut vertices, v[3], v[7], v[4]);
349
350 add_wrong_triangle(&mut vertices, v[3], v[2], v[6]);
352 add_wrong_triangle(&mut vertices, v[6], v[7], v[3]);
353
354 add_wrong_triangle(&mut vertices, v[4], v[5], v[1]);
356 add_wrong_triangle(&mut vertices, v[1], v[0], v[4]);
357
358 Mesh::new(memory_allocator, &vertices, None)
359 }
360
361 pub fn create_sphere(
364 memory_allocator: &Arc<StandardMemoryAllocator>,
365
366 sectors: u32,
367 stacks: u32,
368 ) -> Mesh {
369 let mut vertices = Vec::new();
370 let mut indices = Vec::new();
371 let radius = 0.5;
372
373 for i in 0..=stacks {
374 let stack_angle = PI / 2.0 - (i as f32) * PI / stacks as f32;
375 let xy = radius * stack_angle.cos();
376 let z = radius * stack_angle.sin();
377
378 for j in 0..=sectors {
379 let sector_angle = (j as f32) * 2.0 * PI / sectors as f32;
380 let x = xy * sector_angle.cos();
381 let y = xy * sector_angle.sin();
382
383 let normal = normalize([x, y, z]);
385
386 vertices.push(VertexPosColorUv {
387 position: [x, y, z],
388
389 normal,
390 uv: [1.0, 1.0],
391 });
392 }
393 }
394
395 for i in 0..stacks {
396 for j in 0..sectors {
397 let p1 = i * (sectors + 1) + j;
398 let p2 = p1 + (sectors + 1);
399 let p3 = p1 + 1;
400 let p4 = p2 + 1;
401
402 indices.push(p1);
403 indices.push(p2);
404 indices.push(p3);
405
406 indices.push(p2);
407 indices.push(p4);
408 indices.push(p3);
409 }
410 }
411
412 let mut triangle_vertices = Vec::new();
414 for i in (0..indices.len()).step_by(3) {
415 let v1 = vertices[indices[i] as usize];
416 let v2 = vertices[indices[i + 1] as usize];
417 let v3 = vertices[indices[i + 2] as usize];
418 triangle_vertices.push(v1);
419 triangle_vertices.push(v2);
420 triangle_vertices.push(v3);
421 }
422
423 Mesh::new(memory_allocator, &triangle_vertices, None)
424 }
425
426 pub fn create_sphere_subdivided(
428 memory_allocator: &Arc<StandardMemoryAllocator>,
429
430 subdivisions: u32,
431 ) -> Mesh {
432 let t = (1.0 + (5.0_f32).sqrt()) / 2.0;
433
434 let initial_vertices = [
435 [-1.0, t, 0.0],
436 [1.0, t, 0.0],
437 [-1.0, -t, 0.0],
438 [1.0, -t, 0.0],
439 [0.0, -1.0, t],
440 [0.0, 1.0, t],
441 [0.0, -1.0, -t],
442 [0.0, 1.0, -t],
443 [t, 0.0, -1.0],
444 [t, 0.0, 1.0],
445 [-t, 0.0, -1.0],
446 [-t, 0.0, 1.0],
447 ];
448
449 let initial_indices = [
450 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7,
451 6, 7, 1, 8, 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, 4, 9, 5, 2, 4, 11, 6, 2, 10,
452 8, 6, 7, 9, 8, 1,
453 ];
454
455 let mut normalized_vertices: Vec<[f32; 3]> =
457 initial_vertices.iter().map(|v| normalize(*v)).collect();
458
459 let mut indices = initial_indices.to_vec();
461
462 for _ in 0..subdivisions {
463 let mut new_indices = Vec::new();
464 let mut mid_point_cache = std::collections::HashMap::new();
465
466 for i in (0..indices.len()).step_by(3) {
467 let v1 = normalized_vertices[indices[i] as usize];
468 let v2 = normalized_vertices[indices[i + 1] as usize];
469 let v3 = normalized_vertices[indices[i + 2] as usize];
470
471 let a = *mid_point_cache
473 .entry((indices[i], indices[i + 1]))
474 .or_insert_with(|| {
475 normalized_vertices.push(normalize([
476 (v1[0] + v2[0]) * 0.5,
477 (v1[1] + v2[1]) * 0.5,
478 (v1[2] + v2[2]) * 0.5,
479 ]));
480 (normalized_vertices.len() - 1) as u32
481 });
482
483 let b = *mid_point_cache
484 .entry((indices[i + 1], indices[i + 2]))
485 .or_insert_with(|| {
486 normalized_vertices.push(normalize([
487 (v2[0] + v3[0]) * 0.5,
488 (v2[1] + v3[1]) * 0.5,
489 (v2[2] + v3[2]) * 0.5,
490 ]));
491 (normalized_vertices.len() - 1) as u32
492 });
493
494 let c = *mid_point_cache
495 .entry((indices[i + 2], indices[i]))
496 .or_insert_with(|| {
497 normalized_vertices.push(normalize([
498 (v3[0] + v1[0]) * 0.5,
499 (v3[1] + v1[1]) * 0.5,
500 (v3[2] + v1[2]) * 0.5,
501 ]));
502 (normalized_vertices.len() - 1) as u32
503 });
504
505 new_indices.extend_from_slice(&[indices[i], a, c]);
507 new_indices.extend_from_slice(&[indices[i + 1], b, a]);
508 new_indices.extend_from_slice(&[indices[i + 2], c, b]);
509 new_indices.extend_from_slice(&[a, b, c]);
510 }
511 indices = new_indices;
512 }
513
514 let mut final_vertices = Vec::new();
516 for i in (0..indices.len()).step_by(3) {
517 let v1_pos = normalized_vertices[indices[i] as usize];
518 let v2_pos = normalized_vertices[indices[i + 1] as usize];
519 let v3_pos = normalized_vertices[indices[i + 2] as usize];
520
521 let v1_normal = v1_pos;
523 let v2_normal = v2_pos;
524 let v3_normal = v3_pos;
525
526 final_vertices.push(VertexPosColorUv {
527 position: v1_pos,
528 normal: v1_normal,
529 uv: [1.0, 1.0],
530 });
531 final_vertices.push(VertexPosColorUv {
532 position: v2_pos,
533 normal: v2_normal,
534 uv: [1.0, 1.0],
535 });
536 final_vertices.push(VertexPosColorUv {
537 position: v3_pos,
538 normal: v3_normal,
539 uv: [1.0, 1.0],
540 });
541 }
542
543 Mesh::new(memory_allocator, &final_vertices, None)
544 }
545
546 pub fn create_tetrahedron(memory_allocator: &Arc<StandardMemoryAllocator>) -> Mesh {
548 let mut vertices = Vec::new();
549 let a = 0.5;
550
551 let v = [[a, a, a], [a, -a, -a], [-a, a, -a], [-a, -a, a]];
553
554 add_triangle(&mut vertices, v[0], v[1], v[2]);
556 add_triangle(&mut vertices, v[0], v[2], v[3]);
557 add_triangle(&mut vertices, v[0], v[3], v[1]);
558 add_triangle(&mut vertices, v[1], v[3], v[2]);
559
560 Mesh::new(memory_allocator, &vertices, None)
561 }
562
563 pub fn create_octahedron(memory_allocator: &Arc<StandardMemoryAllocator>) -> Mesh {
565 let mut vertices = Vec::new();
566 let a = 0.5;
567
568 let v = [
570 [a, 0.0, 0.0],
571 [-a, 0.0, 0.0],
572 [0.0, a, 0.0],
573 [0.0, -a, 0.0],
574 [0.0, 0.0, a],
575 [0.0, 0.0, -a],
576 ];
577
578 add_triangle(&mut vertices, v[4], v[0], v[2]);
580 add_triangle(&mut vertices, v[4], v[2], v[1]);
581 add_triangle(&mut vertices, v[4], v[1], v[3]);
582 add_triangle(&mut vertices, v[4], v[3], v[0]);
583
584 add_triangle(&mut vertices, v[5], v[2], v[0]);
586 add_triangle(&mut vertices, v[5], v[1], v[2]);
587 add_triangle(&mut vertices, v[5], v[3], v[1]);
588 add_triangle(&mut vertices, v[5], v[0], v[3]);
589
590 Mesh::new(memory_allocator, &vertices, None)
591 }
592
593 pub fn create_dodecahedron(memory_allocator: &Arc<StandardMemoryAllocator>) -> Mesh {
595 let mut vertices = Vec::new();
596 let phi = (1.0 + (5.0_f32).sqrt()) / 2.0; let a = 0.3;
598 let b = a / phi;
599 let c = a * phi;
600
601 let v = [
603 [a, a, a],
604 [a, a, -a],
605 [a, -a, a],
606 [a, -a, -a],
607 [-a, a, a],
608 [-a, a, -a],
609 [-a, -a, a],
610 [-a, -a, -a],
611 [0.0, b, -c],
612 [0.0, -b, -c],
613 [0.0, b, c],
614 [0.0, -b, c],
615 [b, c, 0.0],
616 [b, -c, 0.0],
617 [-b, c, 0.0],
618 [-b, -c, 0.0],
619 [c, 0.0, b],
620 [c, 0.0, -b],
621 [-c, 0.0, b],
622 [-c, 0.0, -b],
623 ];
624
625 let faces = [
627 [0, 10, 11, 2, 16],
628 [0, 16, 17, 1, 8],
629 [0, 8, 4, 14, 10],
630 [1, 17, 3, 9, 5],
631 [1, 5, 13, 12, 8],
632 [2, 11, 6, 18, 15],
633 [2, 15, 13, 3, 16],
634 [3, 13, 5, 9, 17],
635 [4, 8, 12, 14, 18],
636 [4, 18, 6, 11, 10],
637 [5, 9, 7, 19, 13],
638 [6, 15, 19, 7, 18],
639 ];
640
641 for face in faces.iter() {
642 for i in 1..(face.len() - 1) {
644 add_triangle(&mut vertices, v[face[0]], v[face[i]], v[face[i + 1]]);
645 }
646 }
647
648 Mesh::new(memory_allocator, &vertices, None)
649 }
650
651 pub fn create_icosahedron(memory_allocator: &Arc<StandardMemoryAllocator>) -> Mesh {
653 let mut vertices = Vec::new();
654 let phi = (1.0 + (5.0_f32).sqrt()) / 2.0;
655 let a = 0.5;
656
657 let v_raw = [
659 [-a, phi, 0.0],
660 [a, phi, 0.0],
661 [-a, -phi, 0.0],
662 [a, -phi, 0.0],
663 [0.0, -a, phi],
664 [0.0, a, phi],
665 [0.0, -a, -phi],
666 [0.0, a, -phi],
667 [phi, 0.0, -a],
668 [phi, 0.0, a],
669 [-phi, 0.0, -a],
670 [-phi, 0.0, a],
671 ];
672
673 let v: Vec<[f32; 3]> = v_raw.iter().map(|&p| normalize(p)).collect();
675
676 let faces = [
678 [0, 11, 5],
679 [0, 5, 1],
680 [0, 1, 7],
681 [0, 7, 10],
682 [0, 10, 11],
683 [1, 5, 9],
684 [5, 11, 4],
685 [11, 10, 2],
686 [10, 7, 6],
687 [7, 1, 8],
688 [3, 9, 4],
689 [3, 4, 2],
690 [3, 2, 6],
691 [3, 6, 8],
692 [3, 8, 9],
693 [4, 9, 5],
694 [2, 4, 11],
695 [6, 2, 10],
696 [8, 6, 7],
697 [9, 8, 1],
698 ];
699
700 for face in faces.iter() {
701 add_triangle(&mut vertices, v[face[0]], v[face[1]], v[face[2]]);
702 }
703
704 Mesh::new(memory_allocator, &vertices, None)
705 }
706
707 pub fn create_torus(
709 memory_allocator: &Arc<StandardMemoryAllocator>,
710
711 major_radius: f32,
712 minor_radius: f32,
713 major_segments: u32,
714 minor_segments: u32,
715 ) -> Mesh {
716 let mut vertices = Vec::new();
717
718 for i in 0..major_segments {
719 let major_angle = (i as f32) * 2.0 * PI / major_segments as f32;
720 let next_major_angle = ((i + 1) as f32) * 2.0 * PI / major_segments as f32;
721
722 let cos_major = major_angle.cos();
723 let sin_major = major_angle.sin();
724 let cos_next_major = next_major_angle.cos();
725 let sin_next_major = next_major_angle.sin();
726
727 for j in 0..minor_segments {
728 let minor_angle = (j as f32) * 2.0 * PI / minor_segments as f32;
729 let next_minor_angle = ((j + 1) as f32) * 2.0 * PI / minor_segments as f32;
730
731 let cos_minor = minor_angle.cos();
732 let sin_minor = minor_angle.sin();
733 let cos_next_minor = next_minor_angle.cos();
734 let sin_next_minor = next_minor_angle.sin();
735
736 let p1 = [
738 (major_radius + minor_radius * cos_minor) * cos_major,
739 (major_radius + minor_radius * cos_minor) * sin_major,
740 minor_radius * sin_minor,
741 ];
742
743 let p2 = [
744 (major_radius + minor_radius * cos_next_minor) * cos_major,
745 (major_radius + minor_radius * cos_next_minor) * sin_major,
746 minor_radius * sin_next_minor,
747 ];
748
749 let p3 = [
750 (major_radius + minor_radius * cos_next_minor) * cos_next_major,
751 (major_radius + minor_radius * cos_next_minor) * sin_next_major,
752 minor_radius * sin_next_minor,
753 ];
754
755 let p4 = [
756 (major_radius + minor_radius * cos_minor) * cos_next_major,
757 (major_radius + minor_radius * cos_minor) * sin_next_major,
758 minor_radius * sin_minor,
759 ];
760
761 add_triangle(&mut vertices, p1, p2, p3);
763 add_triangle(&mut vertices, p3, p4, p1); }
765 }
766
767 Mesh::new(memory_allocator, &vertices, None)
768 }
769
770 pub fn create_cylinder(
772 memory_allocator: &Arc<StandardMemoryAllocator>,
773
774 radius: f32,
775 height: f32,
776 sectors: u32,
777 ) -> Mesh {
778 let mut vertices = Vec::new();
779 let half_height = height / 2.0;
780
781 let mut circle_points = Vec::new();
783 for i in 0..sectors {
784 let angle = (i as f32) * 2.0 * PI / sectors as f32;
785 circle_points.push([radius * angle.cos(), radius * angle.sin()]);
786 }
787
788 for i in 0..sectors {
790 let current_idx = i as usize;
791 let next_idx = ((i + 1) % sectors) as usize;
792
793 let p1 = [
794 circle_points[current_idx][0],
795 circle_points[current_idx][1],
796 -half_height,
797 ];
798 let p2 = [
799 circle_points[next_idx][0],
800 circle_points[next_idx][1],
801 -half_height,
802 ];
803 let p3 = [
804 circle_points[next_idx][0],
805 circle_points[next_idx][1],
806 half_height,
807 ];
808 let p4 = [
809 circle_points[current_idx][0],
810 circle_points[current_idx][1],
811 half_height,
812 ];
813
814 let normal = normalize([
816 circle_points[current_idx][0],
817 circle_points[current_idx][1],
818 0.0,
819 ]);
820
821 vertices.push(VertexPosColorUv {
823 position: p1,
824 normal,
825 uv: [1.0, 1.0],
826 });
827 vertices.push(VertexPosColorUv {
828 position: p2,
829 normal,
830 uv: [1.0, 1.0],
831 });
832 vertices.push(VertexPosColorUv {
833 position: p3,
834 normal,
835 uv: [1.0, 1.0],
836 });
837
838 vertices.push(VertexPosColorUv {
839 position: p3,
840 normal,
841 uv: [1.0, 1.0],
842 });
843 vertices.push(VertexPosColorUv {
844 position: p4,
845 normal,
846 uv: [1.0, 1.0],
847 });
848 vertices.push(VertexPosColorUv {
849 position: p1,
850 normal,
851 uv: [1.0, 1.0],
852 });
853 }
854
855 let top_normal = [0.0, 0.0, 1.0];
857 for i in 0..sectors {
858 let current_idx = i as usize;
859 let next_i = ((i + 1) % sectors) as usize;
860 let p1 = [0.0, 0.0, half_height];
861 let p2 = [
862 circle_points[current_idx][0],
863 circle_points[current_idx][1],
864 half_height,
865 ];
866 let p3 = [
867 circle_points[next_i][0],
868 circle_points[next_i][1],
869 half_height,
870 ];
871
872 vertices.push(VertexPosColorUv {
873 position: p1,
874 normal: top_normal,
875 uv: [1.0, 1.0],
876 });
877 vertices.push(VertexPosColorUv {
878 position: p2,
879 normal: top_normal,
880 uv: [1.0, 1.0],
881 });
882 vertices.push(VertexPosColorUv {
883 position: p3,
884 normal: top_normal,
885 uv: [1.0, 1.0],
886 });
887 }
888
889 let bottom_normal = [0.0, 0.0, -1.0];
891 for i in 0..sectors {
892 let current_idx = i as usize;
893 let next_i = ((i + 1) % sectors) as usize;
894
895 let p1 = [0.0, 0.0, -half_height];
896 let p2 = [
897 circle_points[current_idx][0],
898 circle_points[current_idx][1],
899 -half_height,
900 ];
901 let p3 = [
902 circle_points[next_i][0],
903 circle_points[next_i][1],
904 -half_height,
905 ];
906
907 vertices.push(VertexPosColorUv {
908 position: p1,
909 normal: bottom_normal,
910 uv: [1.0, 1.0],
911 });
912 vertices.push(VertexPosColorUv {
913 position: p2,
914 normal: bottom_normal,
915 uv: [1.0, 1.0],
916 });
917 vertices.push(VertexPosColorUv {
918 position: p3,
919 normal: bottom_normal,
920 uv: [1.0, 1.0],
921 });
922 }
923
924 Mesh::new(memory_allocator, &vertices, None)
925 }
926
927 pub fn create_cone(
929 memory_allocator: &Arc<StandardMemoryAllocator>,
930
931 radius: f32,
932 height: f32,
933 sectors: u32,
934 ) -> Mesh {
935 let mut vertices = Vec::new();
936 let half_height = height / 2.0;
937
938 let mut circle_points = Vec::new();
940 for i in 0..sectors {
941 let angle = (i as f32) * 2.0 * PI / sectors as f32;
942 circle_points.push([radius * angle.cos(), radius * angle.sin()]);
943 }
944
945 let tip = [0.0, 0.0, half_height];
947
948 for i in 0..sectors {
950 let current_idx = i as usize;
951 let next_i = ((i + 1) % sectors) as usize;
952 let p1 = tip;
953 let p2 = [
954 circle_points[current_idx][0],
955 circle_points[current_idx][1],
956 -half_height,
957 ];
958 let p3 = [
959 circle_points[next_i][0],
960 circle_points[next_i][1],
961 -half_height,
962 ];
963
964 let side_normal = calculate_normal(p1, p2, p3);
966
967 vertices.push(VertexPosColorUv {
968 position: p1,
969 normal: side_normal,
970 uv: [1.0, 1.0],
971 });
972 vertices.push(VertexPosColorUv {
973 position: p2,
974 normal: side_normal,
975 uv: [1.0, 1.0],
976 });
977 vertices.push(VertexPosColorUv {
978 position: p3,
979 normal: side_normal,
980 uv: [1.0, 1.0],
981 });
982 }
983
984 let bottom_normal = [0.0, 0.0, -1.0];
986 for i in 0..sectors {
987 let current_idx = i as usize;
988 let next_i = ((i + 1) % sectors) as usize;
989 let p1 = [0.0, 0.0, -half_height];
990 let p2 = [
991 circle_points[current_idx][0],
992 circle_points[current_idx][1],
993 -half_height,
994 ];
995 let p3 = [
996 circle_points[next_i][0],
997 circle_points[next_i][1],
998 -half_height,
999 ];
1000
1001 vertices.push(VertexPosColorUv {
1002 position: p1,
1003 normal: bottom_normal,
1004 uv: [1.0, 1.0],
1005 });
1006 vertices.push(VertexPosColorUv {
1007 position: p2,
1008 normal: bottom_normal,
1009 uv: [1.0, 1.0],
1010 });
1011 vertices.push(VertexPosColorUv {
1012 position: p3,
1013 normal: bottom_normal,
1014 uv: [1.0, 1.0],
1015 });
1016 }
1017
1018 Mesh::new(memory_allocator, &vertices, None)
1019 }
1020
1021 pub fn create_plane(
1023 memory_allocator: &Arc<StandardMemoryAllocator>,
1024
1025 width: f32,
1026 height: f32,
1027 ) -> Mesh {
1028 let w = width / 2.0;
1029 let h = height / 2.0;
1030
1031 let v0 = [-w, -h, 0.0];
1032 let v1 = [w, -h, 0.0];
1033 let v2 = [w, h, 0.0];
1034 let v3 = [-w, h, 0.0];
1035
1036 let normal = [0.0, 0.0, 1.0];
1038
1039 let vertices = vec![
1040 VertexPosColorUv {
1041 position: v0,
1042 normal,
1043 uv: [1.0, 1.0],
1044 },
1045 VertexPosColorUv {
1046 position: v1,
1047 normal,
1048 uv: [1.0, 1.0],
1049 },
1050 VertexPosColorUv {
1051 position: v2,
1052 normal,
1053 uv: [1.0, 1.0],
1054 },
1055 VertexPosColorUv {
1056 position: v2,
1057 normal,
1058 uv: [1.0, 1.0],
1059 },
1060 VertexPosColorUv {
1061 position: v3,
1062 normal,
1063 uv: [1.0, 1.0],
1064 },
1065 VertexPosColorUv {
1066 position: v0,
1067 normal,
1068 uv: [1.0, 1.0],
1069 },
1070 ];
1071
1072 Mesh::new(memory_allocator, &vertices, None)
1073 }
1074
1075 pub fn create_grid(
1077 memory_allocator: &Arc<StandardMemoryAllocator>,
1078
1079 size: f32,
1080 divisions: u32,
1081 ) -> Mesh {
1082 let mut vertices = Vec::new();
1083 let step = size / divisions as f32;
1084 let half = size / 2.0;
1085
1086 let normal = [0.0, 0.0, 0.0];
1088
1089 for i in 0..=divisions {
1091 let x = -half + i as f32 * step;
1092 vertices.push(VertexPosColorUv {
1093 position: [x, -half, 0.0],
1094 normal,
1095 uv: [1.0, 1.0],
1096 });
1097 vertices.push(VertexPosColorUv {
1098 position: [x, half, 0.0],
1099 normal,
1100 uv: [1.0, 1.0],
1101 });
1102 }
1103
1104 for i in 0..=divisions {
1106 let y = -half + i as f32 * step;
1107 vertices.push(VertexPosColorUv {
1108 position: [-half, y, 0.0],
1109 normal,
1110 uv: [1.0, 1.0],
1111 });
1112 vertices.push(VertexPosColorUv {
1113 position: [half, y, 0.0],
1114 normal,
1115 uv: [1.0, 1.0],
1116 });
1117 }
1118
1119 Mesh::new(memory_allocator, &vertices, None)
1120 }
1121
1122 pub fn create_pyramid(
1124 memory_allocator: &Arc<StandardMemoryAllocator>,
1125
1126 size: f32,
1127 height: f32,
1128 ) -> Mesh {
1129 let mut vertices = Vec::new();
1130 let half = size / 2.0;
1131 let half_height = height / 2.0;
1132
1133 let b1 = [-half, -half, -half_height];
1135 let b2 = [half, -half, -half_height];
1136 let b3 = [half, half, -half_height];
1137 let b4 = [-half, half, -half_height];
1138
1139 let apex = [0.0, 0.0, half_height];
1141
1142 let base_normal = [0.0, 0.0, -1.0];
1144
1145 vertices.push(VertexPosColorUv {
1146 position: b1,
1147 normal: base_normal,
1148 uv: [1.0, 1.0],
1149 });
1150 vertices.push(VertexPosColorUv {
1151 position: b2,
1152 normal: base_normal,
1153 uv: [1.0, 1.0],
1154 });
1155 vertices.push(VertexPosColorUv {
1156 position: b3,
1157 normal: base_normal,
1158 uv: [1.0, 1.0],
1159 });
1160
1161 vertices.push(VertexPosColorUv {
1162 position: b3,
1163 normal: base_normal,
1164 uv: [1.0, 1.0],
1165 });
1166 vertices.push(VertexPosColorUv {
1167 position: b4,
1168 normal: base_normal,
1169 uv: [1.0, 1.0],
1170 });
1171 vertices.push(VertexPosColorUv {
1172 position: b1,
1173 normal: base_normal,
1174 uv: [1.0, 1.0],
1175 });
1176
1177 let side1_normal = calculate_normal(apex, b1, b2);
1179 let side2_normal = calculate_normal(apex, b2, b3);
1180 let side3_normal = calculate_normal(apex, b3, b4);
1181 let side4_normal = calculate_normal(apex, b4, b1);
1182
1183 vertices.push(VertexPosColorUv {
1185 position: apex,
1186 normal: side1_normal,
1187 uv: [1.0, 1.0],
1188 });
1189 vertices.push(VertexPosColorUv {
1190 position: b1,
1191 normal: side1_normal,
1192 uv: [1.0, 1.0],
1193 });
1194 vertices.push(VertexPosColorUv {
1195 position: b2,
1196 normal: side1_normal,
1197 uv: [1.0, 1.0],
1198 });
1199
1200 vertices.push(VertexPosColorUv {
1202 position: apex,
1203 normal: side2_normal,
1204 uv: [1.0, 1.0],
1205 });
1206 vertices.push(VertexPosColorUv {
1207 position: b2,
1208 normal: side2_normal,
1209 uv: [1.0, 1.0],
1210 });
1211 vertices.push(VertexPosColorUv {
1212 position: b3,
1213 normal: side2_normal,
1214 uv: [1.0, 1.0],
1215 });
1216
1217 vertices.push(VertexPosColorUv {
1219 position: apex,
1220 normal: side3_normal,
1221 uv: [1.0, 1.0],
1222 });
1223 vertices.push(VertexPosColorUv {
1224 position: b3,
1225 normal: side3_normal,
1226 uv: [1.0, 1.0],
1227 });
1228 vertices.push(VertexPosColorUv {
1229 position: b4,
1230 normal: side3_normal,
1231 uv: [1.0, 1.0],
1232 });
1233
1234 vertices.push(VertexPosColorUv {
1236 position: apex,
1237 normal: side4_normal,
1238 uv: [1.0, 1.0],
1239 });
1240 vertices.push(VertexPosColorUv {
1241 position: b4,
1242 normal: side4_normal,
1243 uv: [1.0, 1.0],
1244 });
1245 vertices.push(VertexPosColorUv {
1246 position: b1,
1247 normal: side4_normal,
1248 uv: [1.0, 1.0],
1249 });
1250
1251 Mesh::new(memory_allocator, &vertices, None)
1252 }
1253}