1use crate::render::gfx::types::{Format, VertexAttribute, VertexFormat, VertexLayout};
2use glam::{Vec2, Vec3};
3
4#[repr(C)]
5#[derive(Debug, Clone, Copy)]
6pub struct Vertex {
7 pub position: [f32; 3],
8 pub normal: [f32; 3],
9 pub uv: [f32; 2],
10 pub tangent: [f32; 4],
11}
12unsafe impl bytemuck::Pod for Vertex {}
13unsafe impl bytemuck::Zeroable for Vertex {}
14
15impl VertexFormat for Vertex {
17 fn layout() -> VertexLayout {
18 VertexLayout {
19 stride: size_of::<Self>() as u32,
20 attributes: vec![
21 VertexAttribute { location: 0, format: Format::Rgb32Float, offset: 0 }, VertexAttribute { location: 1, format: Format::Rgb32Float, offset: 12 }, VertexAttribute { location: 2, format: Format::Rg32Float, offset: 24 }, VertexAttribute { location: 3, format: Format::Rgba32Float, offset: 32 }, ],
26 }
27 }
28}
29
30#[derive(Debug, Clone, Copy)]
31pub struct Aabb {
32 pub min: Vec3,
33 pub max: Vec3,
34}
35
36impl Aabb {
37 pub fn from_vertices(vertices: &[Vertex]) -> Self {
38 let mut min = Vec3::splat(f32::MAX);
39 let mut max = Vec3::splat(f32::MIN);
40 for v in vertices {
41 let p = Vec3::from(v.position);
42 min = min.min(p);
43 max = max.max(p);
44 }
45 Self { min, max }
46 }
47
48 pub fn intersects_frustum(&self, planes: &[glam::Vec4; 6]) -> bool {
49 for plane in planes {
50 let normal = Vec3::new(plane.x, plane.y, plane.z);
51 let p = Vec3::new(
52 if normal.x >= 0.0 { self.max.x } else { self.min.x },
53 if normal.y >= 0.0 { self.max.y } else { self.min.y },
54 if normal.z >= 0.0 { self.max.z } else { self.min.z },
55 );
56 if normal.dot(p) + plane.w < 0.0 {
57 return false;
58 }
59 }
60 true
61 }
62}
63
64impl Vertex {
65 pub fn new(position: Vec3, normal: Vec3, uv: Vec2) -> Self {
66 Self { position: position.into(), normal: normal.into(), uv: uv.into(), tangent: [1.0, 0.0, 0.0, 1.0] }
67 }
68}
69
70#[derive(Debug, Clone)]
71pub struct CpuMesh {
72 pub vertices: Vec<Vertex>,
73 pub indices: Vec<u32>,
74 pub name: String,
75}
76
77impl CpuMesh {
78 pub fn new(name: impl Into<String>, vertices: Vec<Vertex>, indices: Vec<u32>) -> Self {
79 Self { vertices, indices, name: name.into() }
80 }
81
82 pub fn vertex_count(&self) -> u32 {
83 self.vertices.len() as u32
84 }
85 pub fn index_count(&self) -> u32 {
86 self.indices.len() as u32
87 }
88
89 pub fn triangle() -> Self {
90 let vertices = vec![
91 Vertex::new(Vec3::new(0.0, 0.5, 0.0), Vec3::Z, Vec2::new(0.5, 0.0)),
92 Vertex::new(Vec3::new(-0.5, -0.5, 0.0), Vec3::Z, Vec2::new(0.0, 1.0)),
93 Vertex::new(Vec3::new(0.5, -0.5, 0.0), Vec3::Z, Vec2::new(1.0, 1.0)),
94 ];
95 Self::new("triangle", vertices, vec![0, 1, 2])
96 }
97
98 pub fn cube() -> Self {
99 let faces: &[(Vec3, Vec3, Vec3)] = &[
100 (Vec3::Z, Vec3::X, Vec3::Y), (Vec3::NEG_Z, Vec3::NEG_X, Vec3::Y), (Vec3::X, Vec3::NEG_Z, Vec3::Y), (Vec3::NEG_X, Vec3::Z, Vec3::Y), (Vec3::Y, Vec3::X, Vec3::NEG_Z), (Vec3::NEG_Y, Vec3::X, Vec3::Z), ];
107
108 let uvs = [
109 Vec2::new(0.0, 1.0),
110 Vec2::new(1.0, 1.0),
111 Vec2::new(1.0, 0.0),
112 Vec2::new(0.0, 0.0),
113 ];
114
115 let mut vertices = Vec::new();
116 let mut indices = Vec::new();
117
118 for (normal, right, up) in faces {
119 let base = vertices.len() as u32;
120 let center = *normal * 0.5;
121 let corners = [
122 center - *right * 0.5 - *up * 0.5,
123 center + *right * 0.5 - *up * 0.5,
124 center + *right * 0.5 + *up * 0.5,
125 center - *right * 0.5 + *up * 0.5,
126 ];
127 for (pos, uv) in corners.iter().zip(uvs.iter()) {
128 vertices.push(Vertex::new(*pos, *normal, *uv));
129 }
130 indices.extend_from_slice(&[base, base + 1, base + 2, base, base + 2, base + 3]);
131 }
132
133 Self::new("cube", vertices, indices)
134 }
135
136 pub fn plane(size: f32, subdivisions: u32) -> Self {
137 let n = subdivisions + 1;
138 let mut vertices = Vec::new();
139 let mut indices = Vec::new();
140
141 for z in 0..n {
142 for x in 0..n {
143 let fx = x as f32 / subdivisions as f32;
144 let fz = z as f32 / subdivisions as f32;
145 vertices.push(Vertex::new(
146 Vec3::new((fx - 0.5) * size, 0.0, (fz - 0.5) * size),
147 Vec3::Y,
148 Vec2::new(fx, fz),
149 ));
150 }
151 }
152
153 for z in 0..subdivisions {
154 for x in 0..subdivisions {
155 let i = z * n + x;
156 indices.extend_from_slice(&[i, i + n, i + 1, i + 1, i + n, i + n + 1]);
157 }
158 }
159
160 Self::new(format!("plane_{size}"), vertices, indices)
161 }
162}