1use glam::{Vec3, Vec4};
6use wgpu::util::DeviceExt;
7
8use crate::surface_mesh_render::MeshUniforms;
9
10pub struct SliceMeshRenderData {
14 vertex_buffer: wgpu::Buffer,
16 index_buffer: wgpu::Buffer,
18 normal_buffer: wgpu::Buffer,
20 _barycentric_buffer: wgpu::Buffer,
22 color_buffer: wgpu::Buffer,
24 _edge_is_real_buffer: wgpu::Buffer,
26 uniform_buffer: wgpu::Buffer,
28 bind_group: wgpu::BindGroup,
30 num_indices: u32,
32}
33
34impl SliceMeshRenderData {
35 #[must_use]
45 pub fn new(
46 device: &wgpu::Device,
47 bind_group_layout: &wgpu::BindGroupLayout,
48 camera_buffer: &wgpu::Buffer,
49 vertices: &[Vec3],
50 normals: &[Vec3],
51 colors: &[Vec4],
52 ) -> Self {
53 let num_vertices = vertices.len() as u32;
54 let num_indices = num_vertices;
55
56 let mut position_data: Vec<f32> = Vec::with_capacity(vertices.len() * 4);
58 let mut normal_data: Vec<f32> = Vec::with_capacity(normals.len() * 4);
59 let mut color_data: Vec<f32> = Vec::with_capacity(colors.len() * 4);
60 let mut barycentric_data: Vec<f32> = Vec::with_capacity(vertices.len() * 4);
61 let mut edge_is_real_data: Vec<f32> = Vec::with_capacity(vertices.len() * 4);
62
63 for (i, v) in vertices.iter().enumerate() {
64 position_data.extend_from_slice(&[v.x, v.y, v.z, 1.0]);
65
66 let n = normals[i];
67 normal_data.extend_from_slice(&[n.x, n.y, n.z, 0.0]);
68
69 let c = colors[i];
70 color_data.extend_from_slice(&c.to_array());
71
72 let bary = match i % 3 {
74 0 => [1.0, 0.0, 0.0],
75 1 => [0.0, 1.0, 0.0],
76 _ => [0.0, 0.0, 1.0],
77 };
78 barycentric_data.extend_from_slice(&[bary[0], bary[1], bary[2], 0.0]);
79
80 edge_is_real_data.extend_from_slice(&[1.0, 1.0, 1.0, 0.0]);
82 }
83
84 let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
86 label: Some("slice mesh vertices"),
87 contents: bytemuck::cast_slice(&position_data),
88 usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST,
89 });
90
91 let index_data: Vec<u32> = (0..num_indices).collect();
92 let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
93 label: Some("slice mesh indices"),
94 contents: bytemuck::cast_slice(&index_data),
95 usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
96 });
97
98 let normal_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
99 label: Some("slice mesh normals"),
100 contents: bytemuck::cast_slice(&normal_data),
101 usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST,
102 });
103
104 let barycentric_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
105 label: Some("slice mesh barycentrics"),
106 contents: bytemuck::cast_slice(&barycentric_data),
107 usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST,
108 });
109
110 let color_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
111 label: Some("slice mesh colors"),
112 contents: bytemuck::cast_slice(&color_data),
113 usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST,
114 });
115
116 let edge_is_real_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
117 label: Some("slice mesh edge_is_real"),
118 contents: bytemuck::cast_slice(&edge_is_real_data),
119 usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST,
120 });
121
122 let mut uniforms = MeshUniforms::default();
124 uniforms.shade_style = 1; uniforms.show_edges = 0; uniforms.backface_policy = 0; let uniform_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
129 label: Some("slice mesh uniforms"),
130 contents: bytemuck::cast_slice(&[uniforms]),
131 usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
132 });
133
134 let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
136 label: Some("slice mesh bind group"),
137 layout: bind_group_layout,
138 entries: &[
139 wgpu::BindGroupEntry {
140 binding: 0,
141 resource: camera_buffer.as_entire_binding(),
142 },
143 wgpu::BindGroupEntry {
144 binding: 1,
145 resource: uniform_buffer.as_entire_binding(),
146 },
147 wgpu::BindGroupEntry {
148 binding: 2,
149 resource: vertex_buffer.as_entire_binding(),
150 },
151 wgpu::BindGroupEntry {
152 binding: 3,
153 resource: normal_buffer.as_entire_binding(),
154 },
155 wgpu::BindGroupEntry {
156 binding: 4,
157 resource: barycentric_buffer.as_entire_binding(),
158 },
159 wgpu::BindGroupEntry {
160 binding: 5,
161 resource: color_buffer.as_entire_binding(),
162 },
163 wgpu::BindGroupEntry {
164 binding: 6,
165 resource: edge_is_real_buffer.as_entire_binding(),
166 },
167 ],
168 });
169
170 Self {
171 vertex_buffer,
172 index_buffer,
173 normal_buffer,
174 _barycentric_buffer: barycentric_buffer,
175 color_buffer,
176 _edge_is_real_buffer: edge_is_real_buffer,
177 uniform_buffer,
178 bind_group,
179 num_indices,
180 }
181 }
182
183 pub fn update(
187 &mut self,
188 device: &wgpu::Device,
189 queue: &wgpu::Queue,
190 bind_group_layout: &wgpu::BindGroupLayout,
191 camera_buffer: &wgpu::Buffer,
192 vertices: &[Vec3],
193 normals: &[Vec3],
194 colors: &[Vec4],
195 ) {
196 let new_num_indices = vertices.len() as u32;
198 if new_num_indices != self.num_indices {
199 *self = Self::new(
200 device,
201 bind_group_layout,
202 camera_buffer,
203 vertices,
204 normals,
205 colors,
206 );
207 return;
208 }
209
210 let mut position_data: Vec<f32> = Vec::with_capacity(vertices.len() * 4);
212 let mut normal_data: Vec<f32> = Vec::with_capacity(normals.len() * 4);
213 let mut color_data: Vec<f32> = Vec::with_capacity(colors.len() * 4);
214
215 for (i, v) in vertices.iter().enumerate() {
216 position_data.extend_from_slice(&[v.x, v.y, v.z, 1.0]);
217
218 let n = normals[i];
219 normal_data.extend_from_slice(&[n.x, n.y, n.z, 0.0]);
220
221 let c = colors[i];
222 color_data.extend_from_slice(&c.to_array());
223 }
224
225 queue.write_buffer(&self.vertex_buffer, 0, bytemuck::cast_slice(&position_data));
226 queue.write_buffer(&self.normal_buffer, 0, bytemuck::cast_slice(&normal_data));
227 queue.write_buffer(&self.color_buffer, 0, bytemuck::cast_slice(&color_data));
228 }
229
230 pub fn update_uniforms(&self, queue: &wgpu::Queue, color: Vec3) {
232 let mut uniforms = MeshUniforms::default();
233 uniforms.shade_style = 1; uniforms.show_edges = 0;
235 uniforms.surface_color = [color.x, color.y, color.z, 1.0];
236 uniforms.backface_policy = 0;
237
238 queue.write_buffer(&self.uniform_buffer, 0, bytemuck::cast_slice(&[uniforms]));
239 }
240
241 #[must_use]
243 pub fn bind_group(&self) -> &wgpu::BindGroup {
244 &self.bind_group
245 }
246
247 #[must_use]
249 pub fn index_buffer(&self) -> &wgpu::Buffer {
250 &self.index_buffer
251 }
252
253 #[must_use]
255 pub fn num_indices(&self) -> u32 {
256 self.num_indices
257 }
258
259 #[must_use]
261 pub fn is_empty(&self) -> bool {
262 self.num_indices == 0
263 }
264}