1use crate::aabb::Aabb;
2
3#[repr(C)]
5#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
6pub struct MeshVertex {
7 pub position: [f32; 3],
8 pub normal: [f32; 3],
9 pub uv: [f32; 2],
10 pub tangent: [f32; 4],
11}
12
13impl MeshVertex {
14 pub const SIZE: usize = std::mem::size_of::<Self>();
15 pub const ATTRIB_COUNT: usize = 4;
16}
17
18#[derive(Debug, Clone)]
20pub struct SubMesh {
21 pub material_index: usize,
22 pub index_offset: u32,
23 pub index_count: u32,
24}
25
26#[derive(Debug, Clone)]
28pub struct Mesh {
29 pub name: String,
30 pub vertices: Vec<MeshVertex>,
31 pub indices: Vec<u32>,
32 pub sub_meshes: Vec<SubMesh>,
33 pub aabb: Aabb,
34}
35
36impl Mesh {
37 pub fn extract_edge_indices(&self) -> Vec<u32> {
40 let mut edge_indices = Vec::with_capacity(self.indices.len() * 2);
41 for tri in self.indices.chunks(3) {
42 if tri.len() == 3 {
43 edge_indices.extend_from_slice(&[tri[0], tri[1], tri[1], tri[2], tri[2], tri[0]]);
44 }
45 }
46 edge_indices
47 }
48}
49
50pub fn create_cube_mesh() -> Mesh {
52 let mut vertices = Vec::new();
53 let mut indices = Vec::new();
54 let mut aabb = Aabb::empty();
55
56 let faces: [([f32; 3], [f32; 3], [f32; 4]); 6] = [
58 ([0.0, 1.0, 0.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0, 1.0]),
60 ([0.0, -1.0, 0.0], [0.0, -1.0, 0.0], [-1.0, 0.0, 0.0, 1.0]),
62 ([1.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, -1.0, 1.0]),
64 ([-1.0, 0.0, 0.0], [-1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 1.0]),
66 ([0.0, 0.0, 1.0], [0.0, 0.0, 1.0], [1.0, 0.0, 0.0, 1.0]),
68 ([0.0, 0.0, -1.0], [0.0, 0.0, -1.0], [-1.0, 0.0, 0.0, 1.0]),
70 ];
71
72 let face_vertices: [[([f32; 3], [f32; 2]); 4]; 6] = [
73 [
75 ([-0.5, 0.5, -0.5], [0.0, 0.0]),
76 ([0.5, 0.5, -0.5], [1.0, 0.0]),
77 ([0.5, 0.5, 0.5], [1.0, 1.0]),
78 ([-0.5, 0.5, 0.5], [0.0, 1.0]),
79 ],
80 [
82 ([-0.5, -0.5, 0.5], [0.0, 0.0]),
83 ([0.5, -0.5, 0.5], [1.0, 0.0]),
84 ([0.5, -0.5, -0.5], [1.0, 1.0]),
85 ([-0.5, -0.5, -0.5], [0.0, 1.0]),
86 ],
87 [
89 ([0.5, -0.5, -0.5], [0.0, 0.0]),
90 ([0.5, -0.5, 0.5], [1.0, 0.0]),
91 ([0.5, 0.5, 0.5], [1.0, 1.0]),
92 ([0.5, 0.5, -0.5], [0.0, 1.0]),
93 ],
94 [
96 ([-0.5, -0.5, 0.5], [0.0, 0.0]),
97 ([-0.5, -0.5, -0.5], [1.0, 0.0]),
98 ([-0.5, 0.5, -0.5], [1.0, 1.0]),
99 ([-0.5, 0.5, 0.5], [0.0, 1.0]),
100 ],
101 [
103 ([0.5, -0.5, 0.5], [0.0, 0.0]),
104 ([-0.5, -0.5, 0.5], [1.0, 0.0]),
105 ([-0.5, 0.5, 0.5], [1.0, 1.0]),
106 ([0.5, 0.5, 0.5], [0.0, 1.0]),
107 ],
108 [
110 ([-0.5, -0.5, -0.5], [0.0, 0.0]),
111 ([0.5, -0.5, -0.5], [1.0, 0.0]),
112 ([0.5, 0.5, -0.5], [1.0, 1.0]),
113 ([-0.5, 0.5, -0.5], [0.0, 1.0]),
114 ],
115 ];
116
117 for (face_idx, (normal, _, tangent)) in faces.iter().enumerate() {
118 let base = vertices.len() as u32;
119 for (pos, uv) in &face_vertices[face_idx] {
120 vertices.push(MeshVertex {
121 position: *pos,
122 normal: *normal,
123 uv: *uv,
124 tangent: *tangent,
125 });
126 aabb.extend_pos(*pos);
127 }
128 indices.extend_from_slice(&[
129 base, base + 2, base + 1,
130 base, base + 3, base + 2,
131 ]);
132 }
133
134 let index_count = indices.len() as u32;
135 Mesh {
136 name: "Cube".to_string(),
137 vertices,
138 indices,
139 sub_meshes: vec![SubMesh {
140 material_index: 0,
141 index_offset: 0,
142 index_count,
143 }],
144 aabb,
145 }
146}
147
148impl Aabb {
149 fn extend_pos(&mut self, pos: [f32; 3]) {
150 let v = glam::Vec3::from(pos);
151 self.min = self.min.min(v);
152 self.max = self.max.max(v);
153 }
154}