Skip to main content

rusting_engine/geometry/
mod.rs

1// ! SHAPE AND MESH SYSTEM - Defines geometry and scene organization
2// More I do this, more I understand and respect all developers that created a blender, unity, unreal engine and etc. just F for every man that did something like that and biggest F for that people, who did it opensource. F
3pub 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;
8// * Trait combining all requirements for vertex types
9pub trait VertexType: Vertex + bytemuck::Pod + bytemuck::Zeroable + Send + Sync {}
10
11// ! VERTEX WITH POSITION AND COLOR - Basic vertex format
12#[repr(C)]
13#[derive(Copy, Clone, Debug, Vertex, bytemuck::Pod, bytemuck::Zeroable)]
14pub struct VertexPosColor {
15    #[format(R32G32B32_SFLOAT)]
16    pub position: [f32; 3], // XYZ position
17    #[format(R32G32B32_SFLOAT)]
18    pub color: [f32; 3], // RGB color
19    #[format(R32G32B32_SFLOAT)]
20    pub barycentric: [f32; 3],
21}
22
23impl VertexType for VertexPosColor {}
24
25// ! VERTEX WITH UV COORDINATES - For textured objects (future use)
26#[repr(C)]
27#[derive(Copy, Clone, Debug, Vertex, bytemuck::Pod, bytemuck::Zeroable)]
28pub struct VertexPosColorUv {
29    #[format(R32G32B32_SFLOAT)]
30    pub position: [f32; 3], // XYZ position
31    #[format(R32G32B32_SFLOAT)]
32    pub normal: [f32; 3], // Normals
33    #[format(R32G32_SFLOAT)]
34    pub uv: [f32; 2], // Texture coordinates
35}
36
37impl VertexType for VertexPosColorUv {}
38
39// ! VERTEX WITH NORMALS - For lighting calculations
40#[repr(C)]
41#[derive(Copy, Clone, Debug, Vertex, bytemuck::Pod, bytemuck::Zeroable)]
42pub struct VertexPosColorNormal {
43    #[format(R32G32B32_SFLOAT)]
44    pub position: [f32; 3], // XYZ position
45    #[format(R32G32B32_SFLOAT)]
46    pub color: [f32; 3], // RGB color
47    #[format(R32G32B32_SFLOAT)]
48    pub normal: [f32; 3], // Normals(for light)
49    #[format(R32G32B32_SFLOAT)]
50    pub barycentric: [f32; 3], // yes
51}
52
53impl VertexType for VertexPosColorNormal {}
54
55// ! MESH - Container for vertex and index data on the GPU
56#[derive(Clone)]
57pub struct Mesh {
58    pub vertices: Subbuffer<[VertexPosColorUv]>, // GPU buffer of vertices
59    pub indices: Option<Subbuffer<[u32]>>,       // Optional index buffer (for reuse)
60    pub vertex_count: u32,                       // Number of vertices
61    pub index_count: u32,                        // Number of indices (if using)
62    pub base_color_texture: Option<usize>,
63}
64
65impl Mesh {
66    // * Create a new mesh from CPU-side data
67    pub fn new(
68        memory_allocator: &Arc<StandardMemoryAllocator>,
69        vertices: &[VertexPosColorUv],
70        indices: Option<&[u32]>,
71    ) -> Self {
72        // Upload vertices to GPU
73        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        // Upload indices if provided
90        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    // * Create a mesh with indexed geometry (more efficient for complex shapes)
119    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
128// ? Why am I even writing a comments if I am the only one who read it, am I schizophrenic?
129
130// ! PRIMITIVE SHAPES - Factory functions for creating common meshes
131pub mod shapes {
132    use super::*;
133    use std::f32::consts::PI;
134
135    // Helper function to normalize a vector
136    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        // Cross product
150        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    // Helper function to add a triangle with barycentric coordinates
160    fn add_triangle(
161        vertices: &mut Vec<VertexPosColorUv>,
162        p1: [f32; 3],
163        p2: [f32; 3],
164        p3: [f32; 3],
165    ) {
166        // Calculate face normal
167        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    // * Wrong Normal triangle
187    fn add_wrong_triangle(
188        vertices: &mut Vec<VertexPosColorUv>,
189        p1: [f32; 3],
190        p2: [f32; 3],
191        p3: [f32; 3],
192    ) {
193        // Calculate face normal
194        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    // Helper function to add a quad as two triangles
216    // I dont know who will use it, maybe some chill guy                      or lady....
217    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        // Calculate normal for first triangle
225        let normal1 = calculate_normal(p1, p2, p3);
226        // Calculate normal for second triangle
227        let normal2 = calculate_normal(p3, p4, p1);
228
229        // First triangle
230        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        // Second triangle
247        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        // Normal for a flat triangle in XY plane
270        add_triangle(&mut vertices, v[0], v[1], v[2]);
271
272        Mesh::new(memory_allocator, &vertices, None)
273    }
274
275    // * Create a unit cube centered at origin
276    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        // Front face (+Z)
293        add_triangle(&mut vertices, v[0], v[1], v[2]);
294        add_triangle(&mut vertices, v[2], v[3], v[0]);
295
296        // Right face (+X)
297        add_triangle(&mut vertices, v[1], v[5], v[6]);
298        add_triangle(&mut vertices, v[6], v[2], v[1]);
299
300        // Back face (-Z)
301        add_triangle(&mut vertices, v[5], v[4], v[7]);
302        add_triangle(&mut vertices, v[7], v[6], v[5]);
303
304        // Left face (-X)
305        add_triangle(&mut vertices, v[4], v[0], v[3]);
306        add_triangle(&mut vertices, v[3], v[7], v[4]);
307
308        // Top face (+Y)
309        add_triangle(&mut vertices, v[3], v[2], v[6]);
310        add_triangle(&mut vertices, v[6], v[7], v[3]);
311
312        // Bottom face (-Y)
313        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    // * Wrong Cube, to test normals
320    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        // Front face (+Z)
335        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        // Right face (+X)
339        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        // Back face (-Z)
343        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        // Left face (-X)
347        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        // Top face (+Y)
351        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        // Bottom face (-Y)
355        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    // * Create a sphere by subdividing into sectors and stacks,
362    // ! DO NOT WRITE 16 OR 32, IT IS NOT TOTAL SUBDIVIDES!!!, write like 2-4 max
363    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                // For smooth shading, normal is the normalized position vector
384                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        // Reorder vertices based on indices to avoid indexed rendering
413        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    // * Create a sphere using icosahedron subdivision (better distribution)
427    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        // Normalize all vertices to lie on sphere
456        let mut normalized_vertices: Vec<[f32; 3]> =
457            initial_vertices.iter().map(|v| normalize(*v)).collect();
458
459        // Subdivide
460        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                // Get or create midpoints
472                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                // Create 4 triangles
506                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        // Create final vertex list with normals (normalized position for smooth shading)
515        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            // For smooth shading, normal is the normalized position
522            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    // * Create a tetrahedron
547    pub fn create_tetrahedron(memory_allocator: &Arc<StandardMemoryAllocator>) -> Mesh {
548        let mut vertices = Vec::new();
549        let a = 0.5;
550
551        // Four vertices of a regular tetrahedron
552        let v = [[a, a, a], [a, -a, -a], [-a, a, -a], [-a, -a, a]];
553
554        // Four faces (each triangle)
555        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    // * Create an octahedron
564    pub fn create_octahedron(memory_allocator: &Arc<StandardMemoryAllocator>) -> Mesh {
565        let mut vertices = Vec::new();
566        let a = 0.5;
567
568        // Six vertices
569        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        // Top half (4 triangles)
579        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        // Bottom half (4 triangles)
585        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    // * Create a dodecahedron
594    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; // Golden ratio
597        let a = 0.3;
598        let b = a / phi;
599        let c = a * phi;
600
601        // 20 vertices
602        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        // 12 pentagonal faces (each split into 3 triangles)
626        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            // Triangulate pentagon (fan from first vertex)
643            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    // * Create an icosahedron
652    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        // 12 vertices (normalize to sphere for better shape)
658        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        // Normalize vertices to lie on sphere
674        let v: Vec<[f32; 3]> = v_raw.iter().map(|&p| normalize(p)).collect();
675
676        // 20 triangular faces
677        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    // * Create a torus, this shit has sick formula
708    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                // Calculate the four corners of the quad
737                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                // Create two triangles for the quad
762                add_triangle(&mut vertices, p1, p2, p3);
763                add_triangle(&mut vertices, p3, p4, p1); // ! Change to add_quad, but now right now, bc I dont want to
764            }
765        }
766
767        Mesh::new(memory_allocator, &vertices, None)
768    }
769
770    // * Create a cylinder
771    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        // Create vertices around the circle
782        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        // Side faces (quads) - normals point radially outward
789        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            // For sides, we need radial normals
815            let normal = normalize([
816                circle_points[current_idx][0],
817                circle_points[current_idx][1],
818                0.0,
819            ]);
820
821            // Add triangles with proper normals
822            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        // Top cap (triangles from center) - normal points up (+Y)
856        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        // Bottom cap (triangles from center) - normal points down (-Y)
890        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    // * Create a cone
928    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        // Create vertices around the circle
939        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        // Tip of cone
946        let tip = [0.0, 0.0, half_height];
947
948        // Side faces (triangles) - normals are perpendicular to the cone surface
949        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            // Calculate normal for side face
965            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        // Bottom cap (triangles from center) - normal points down (-Y)
985        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    // * Create a flat plane
1022    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        // Plane normal points up (+Z)
1037        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    // * Create a grid of lines (useful for debugging/visualization)
1076    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        // For lines, normals don't matter much, but we'll set them to zero
1087        let normal = [0.0, 0.0, 0.0];
1088
1089        // Lines along X axis
1090        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        // Lines along Y axis
1105        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    // * Create a pyramid (square base)
1123    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        // Base(after base) vertices
1134        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        // Apex, like a game, haha, ha?
1140        let apex = [0.0, 0.0, half_height];
1141
1142        // Base (two triangles) - normal points down (-Z)
1143        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        // Four sides - calculate normals for each face
1178        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        // Side 1
1184        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        // Side 2
1201        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        // Side 3
1218        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        // Side 4
1235        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}