1use crate::resources::*;
2
3impl DeviceResources {
4 pub fn update_gizmo_mesh(
9 &mut self,
10 device: &wgpu::Device,
11 queue: &wgpu::Queue,
12 mode: crate::interaction::manipulation::gizmo::GizmoMode,
13 hovered: crate::interaction::manipulation::gizmo::GizmoAxis,
14 space_orientation: glam::Quat,
15 ) {
16 let (verts, indices) = crate::interaction::manipulation::gizmo::build_gizmo_mesh(
17 mode,
18 hovered,
19 space_orientation,
20 );
21
22 let vert_bytes: &[u8] = bytemuck::cast_slice(&verts);
23 let idx_bytes: &[u8] = bytemuck::cast_slice(&indices);
24
25 if vert_bytes.len() as u64 > self.gizmo_vertex_buffer.size() {
27 self.gizmo_vertex_buffer = device.create_buffer(&wgpu::BufferDescriptor {
28 label: Some("gizmo_vertex_buf"),
29 size: vert_bytes.len() as u64,
30 usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
31 mapped_at_creation: false,
32 });
33 }
34 if idx_bytes.len() as u64 > self.gizmo_index_buffer.size() {
35 self.gizmo_index_buffer = device.create_buffer(&wgpu::BufferDescriptor {
36 label: Some("gizmo_index_buf"),
37 size: idx_bytes.len() as u64,
38 usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
39 mapped_at_creation: false,
40 });
41 }
42
43 queue.write_buffer(&self.gizmo_vertex_buffer, 0, vert_bytes);
44 queue.write_buffer(&self.gizmo_index_buffer, 0, idx_bytes);
45 self.gizmo_index_count = indices.len() as u32;
46 }
47
48 pub fn update_gizmo_uniform(&self, queue: &wgpu::Queue, model: glam::Mat4) {
50 let uniform = crate::interaction::manipulation::gizmo::GizmoUniform {
51 model: model.to_cols_array_2d(),
52 };
53 queue.write_buffer(&self.gizmo_uniform_buf, 0, bytemuck::cast_slice(&[uniform]));
54 }
55
56 pub fn create_constraint_overlay(
58 &self,
59 device: &wgpu::Device,
60 overlay: &crate::interaction::query::snap::ConstraintOverlay,
61 ) -> (
62 wgpu::Buffer,
63 wgpu::Buffer,
64 u32,
65 wgpu::Buffer,
66 wgpu::BindGroup,
67 ) {
68 use bytemuck::cast_slice;
69
70 let (vertices, colour): (Vec<OverlayVertex>, [f32; 4]) = match overlay {
71 crate::interaction::query::snap::ConstraintOverlay::AxisLine {
72 origin,
73 direction,
74 colour,
75 } => (
76 vec![
77 OverlayVertex {
78 position: (*origin - *direction).to_array(),
79 },
80 OverlayVertex {
81 position: (*origin + *direction).to_array(),
82 },
83 ],
84 *colour,
85 ),
86 crate::interaction::query::snap::ConstraintOverlay::Plane {
87 origin,
88 axis_a,
89 axis_b,
90 colour,
91 } => (
92 vec![
93 OverlayVertex {
94 position: (*origin - *axis_a).to_array(),
95 },
96 OverlayVertex {
97 position: (*origin + *axis_a).to_array(),
98 },
99 OverlayVertex {
100 position: (*origin - *axis_b).to_array(),
101 },
102 OverlayVertex {
103 position: (*origin + *axis_b).to_array(),
104 },
105 ],
106 *colour,
107 ),
108 };
109 let indices: Vec<u32> = (0..vertices.len() as u32).collect();
110
111 let vertex_buffer = device.create_buffer(&wgpu::BufferDescriptor {
112 label: Some("constraint_overlay_vbuf"),
113 size: (std::mem::size_of::<OverlayVertex>() * vertices.len()) as u64,
114 usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
115 mapped_at_creation: true,
116 });
117 vertex_buffer
118 .slice(..)
119 .get_mapped_range_mut()
120 .copy_from_slice(cast_slice(&vertices));
121 vertex_buffer.unmap();
122
123 let index_buffer = device.create_buffer(&wgpu::BufferDescriptor {
124 label: Some("constraint_overlay_ibuf"),
125 size: (std::mem::size_of::<u32>() * indices.len()) as u64,
126 usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
127 mapped_at_creation: true,
128 });
129 index_buffer
130 .slice(..)
131 .get_mapped_range_mut()
132 .copy_from_slice(cast_slice(&indices));
133 index_buffer.unmap();
134
135 let uniform_data = OverlayUniform {
136 model: glam::Mat4::IDENTITY.to_cols_array_2d(),
137 colour,
138 };
139 let uniform_buffer = device.create_buffer(&wgpu::BufferDescriptor {
140 label: Some("constraint_overlay_ubuf"),
141 size: std::mem::size_of::<OverlayUniform>() as u64,
142 usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
143 mapped_at_creation: true,
144 });
145 uniform_buffer
146 .slice(..)
147 .get_mapped_range_mut()
148 .copy_from_slice(cast_slice(&[uniform_data]));
149 uniform_buffer.unmap();
150
151 let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
152 label: Some("constraint_overlay_bg"),
153 layout: &self.overlay_bind_group_layout,
154 entries: &[wgpu::BindGroupEntry {
155 binding: 0,
156 resource: uniform_buffer.as_entire_binding(),
157 }],
158 });
159
160 (
161 vertex_buffer,
162 index_buffer,
163 indices.len() as u32,
164 uniform_buffer,
165 bind_group,
166 )
167 }
168
169 pub(crate) fn create_clip_plane_fill_overlay(
173 &self,
174 device: &wgpu::Device,
175 overlay: &crate::interaction::manipulation::clip_plane::ClipPlaneOverlay,
176 ) -> (
177 wgpu::Buffer,
178 wgpu::Buffer,
179 u32,
180 wgpu::Buffer,
181 wgpu::BindGroup,
182 ) {
183 use crate::interaction::manipulation::clip_plane::plane_tangents;
184 use bytemuck::cast_slice;
185
186 let (t1, t2) = plane_tangents(overlay.normal);
187 let e = overlay.extent;
188 let c = overlay.center;
189
190 let corners = [
192 c + e * t1 + e * t2,
193 c - e * t1 + e * t2,
194 c - e * t1 - e * t2,
195 c + e * t1 - e * t2,
196 ];
197
198 let vertices: Vec<OverlayVertex> = corners
199 .iter()
200 .map(|p| OverlayVertex {
201 position: p.to_array(),
202 })
203 .collect();
204 let indices: Vec<u32> = vec![0, 1, 2, 0, 2, 3];
206
207 let vertex_buffer = device.create_buffer(&wgpu::BufferDescriptor {
208 label: Some("clip_plane_fill_vbuf"),
209 size: (std::mem::size_of::<OverlayVertex>() * vertices.len()) as u64,
210 usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
211 mapped_at_creation: true,
212 });
213 vertex_buffer
214 .slice(..)
215 .get_mapped_range_mut()
216 .copy_from_slice(cast_slice(&vertices));
217 vertex_buffer.unmap();
218
219 let index_buffer = device.create_buffer(&wgpu::BufferDescriptor {
220 label: Some("clip_plane_fill_ibuf"),
221 size: (std::mem::size_of::<u32>() * indices.len()) as u64,
222 usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
223 mapped_at_creation: true,
224 });
225 index_buffer
226 .slice(..)
227 .get_mapped_range_mut()
228 .copy_from_slice(cast_slice(&indices));
229 index_buffer.unmap();
230
231 let uniform_data = OverlayUniform {
232 model: glam::Mat4::IDENTITY.to_cols_array_2d(),
233 colour: overlay.fill_colour,
234 };
235 let uniform_buffer = device.create_buffer(&wgpu::BufferDescriptor {
236 label: Some("clip_plane_fill_ubuf"),
237 size: std::mem::size_of::<OverlayUniform>() as u64,
238 usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
239 mapped_at_creation: true,
240 });
241 uniform_buffer
242 .slice(..)
243 .get_mapped_range_mut()
244 .copy_from_slice(cast_slice(&[uniform_data]));
245 uniform_buffer.unmap();
246
247 let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
248 label: Some("clip_plane_fill_bg"),
249 layout: &self.overlay_bind_group_layout,
250 entries: &[wgpu::BindGroupEntry {
251 binding: 0,
252 resource: uniform_buffer.as_entire_binding(),
253 }],
254 });
255
256 (
257 vertex_buffer,
258 index_buffer,
259 indices.len() as u32,
260 uniform_buffer,
261 bind_group,
262 )
263 }
264
265 pub(crate) fn create_clip_plane_line_overlay(
269 &self,
270 device: &wgpu::Device,
271 overlay: &crate::interaction::manipulation::clip_plane::ClipPlaneOverlay,
272 ) -> (
273 wgpu::Buffer,
274 wgpu::Buffer,
275 u32,
276 wgpu::Buffer,
277 wgpu::BindGroup,
278 ) {
279 use crate::interaction::manipulation::clip_plane::plane_tangents;
280 use bytemuck::cast_slice;
281
282 let (t1, t2) = plane_tangents(overlay.normal);
283 let e = overlay.extent;
284 let c = overlay.center;
285
286 let c0 = c + e * t1 + e * t2;
288 let c1 = c - e * t1 + e * t2;
289 let c2 = c - e * t1 - e * t2;
290 let c3 = c + e * t1 - e * t2;
291
292 let n_tip = c + overlay.normal * (e * 0.5);
294
295 let vertices: Vec<OverlayVertex> = vec![
298 OverlayVertex {
300 position: c0.to_array(),
301 },
302 OverlayVertex {
303 position: c1.to_array(),
304 },
305 OverlayVertex {
307 position: c1.to_array(),
308 },
309 OverlayVertex {
310 position: c2.to_array(),
311 },
312 OverlayVertex {
314 position: c2.to_array(),
315 },
316 OverlayVertex {
317 position: c3.to_array(),
318 },
319 OverlayVertex {
321 position: c3.to_array(),
322 },
323 OverlayVertex {
324 position: c0.to_array(),
325 },
326 OverlayVertex {
328 position: c.to_array(),
329 },
330 OverlayVertex {
331 position: n_tip.to_array(),
332 },
333 ];
334 let indices: Vec<u32> = (0..vertices.len() as u32).collect();
335
336 let vertex_buffer = device.create_buffer(&wgpu::BufferDescriptor {
337 label: Some("clip_plane_line_vbuf"),
338 size: (std::mem::size_of::<OverlayVertex>() * vertices.len()) as u64,
339 usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
340 mapped_at_creation: true,
341 });
342 vertex_buffer
343 .slice(..)
344 .get_mapped_range_mut()
345 .copy_from_slice(cast_slice(&vertices));
346 vertex_buffer.unmap();
347
348 let index_buffer = device.create_buffer(&wgpu::BufferDescriptor {
349 label: Some("clip_plane_line_ibuf"),
350 size: (std::mem::size_of::<u32>() * indices.len()) as u64,
351 usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
352 mapped_at_creation: true,
353 });
354 index_buffer
355 .slice(..)
356 .get_mapped_range_mut()
357 .copy_from_slice(cast_slice(&indices));
358 index_buffer.unmap();
359
360 let uniform_data = OverlayUniform {
361 model: glam::Mat4::IDENTITY.to_cols_array_2d(),
362 colour: overlay.border_colour,
363 };
364 let uniform_buffer = device.create_buffer(&wgpu::BufferDescriptor {
365 label: Some("clip_plane_line_ubuf"),
366 size: std::mem::size_of::<OverlayUniform>() as u64,
367 usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
368 mapped_at_creation: true,
369 });
370 uniform_buffer
371 .slice(..)
372 .get_mapped_range_mut()
373 .copy_from_slice(cast_slice(&[uniform_data]));
374 uniform_buffer.unmap();
375
376 let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
377 label: Some("clip_plane_line_bg"),
378 layout: &self.overlay_bind_group_layout,
379 entries: &[wgpu::BindGroupEntry {
380 binding: 0,
381 resource: uniform_buffer.as_entire_binding(),
382 }],
383 });
384
385 (
386 vertex_buffer,
387 index_buffer,
388 indices.len() as u32,
389 uniform_buffer,
390 bind_group,
391 )
392 }
393
394 pub(crate) fn upload_cap_geometry(
398 &self,
399 device: &wgpu::Device,
400 cap: &crate::geometry::cap_geometry::CapMesh,
401 colour: [f32; 4],
402 ) -> (
403 wgpu::Buffer,
404 wgpu::Buffer,
405 u32,
406 wgpu::Buffer,
407 wgpu::BindGroup,
408 ) {
409 use bytemuck::cast_slice;
410
411 let vertices: Vec<OverlayVertex> = cap
412 .positions
413 .iter()
414 .map(|p| OverlayVertex { position: *p })
415 .collect();
416
417 let vertex_buffer = device.create_buffer(&wgpu::BufferDescriptor {
418 label: Some("cap_vbuf"),
419 size: (std::mem::size_of::<OverlayVertex>() * vertices.len()) as u64,
420 usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
421 mapped_at_creation: true,
422 });
423 vertex_buffer
424 .slice(..)
425 .get_mapped_range_mut()
426 .copy_from_slice(cast_slice(&vertices));
427 vertex_buffer.unmap();
428
429 let index_buffer = device.create_buffer(&wgpu::BufferDescriptor {
430 label: Some("cap_ibuf"),
431 size: (std::mem::size_of::<u32>() * cap.indices.len()) as u64,
432 usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
433 mapped_at_creation: true,
434 });
435 index_buffer
436 .slice(..)
437 .get_mapped_range_mut()
438 .copy_from_slice(cast_slice(&cap.indices));
439 index_buffer.unmap();
440
441 let uniform_data = OverlayUniform {
442 model: glam::Mat4::IDENTITY.to_cols_array_2d(),
443 colour,
444 };
445 let uniform_buffer = device.create_buffer(&wgpu::BufferDescriptor {
446 label: Some("cap_ubuf"),
447 size: std::mem::size_of::<OverlayUniform>() as u64,
448 usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
449 mapped_at_creation: true,
450 });
451 uniform_buffer
452 .slice(..)
453 .get_mapped_range_mut()
454 .copy_from_slice(cast_slice(&[uniform_data]));
455 uniform_buffer.unmap();
456
457 let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
458 label: Some("cap_bg"),
459 layout: &self.overlay_bind_group_layout,
460 entries: &[wgpu::BindGroupEntry {
461 binding: 0,
462 resource: uniform_buffer.as_entire_binding(),
463 }],
464 });
465
466 let idx_count = cap.indices.len() as u32;
467 (
468 vertex_buffer,
469 index_buffer,
470 idx_count,
471 uniform_buffer,
472 bind_group,
473 )
474 }
475}
476
477#[repr(C)]
482#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
483pub struct OverlayVertex {
484 pub position: [f32; 3],
486}
487
488impl OverlayVertex {
489 pub fn buffer_layout() -> wgpu::VertexBufferLayout<'static> {
491 wgpu::VertexBufferLayout {
492 array_stride: std::mem::size_of::<OverlayVertex>() as wgpu::BufferAddress,
493 step_mode: wgpu::VertexStepMode::Vertex,
494 attributes: &[wgpu::VertexAttribute {
495 offset: 0,
496 shader_location: 0,
497 format: wgpu::VertexFormat::Float32x3,
498 }],
499 }
500 }
501}
502
503#[repr(C)]
505#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
506pub(crate) struct OverlayUniform {
507 pub(crate) model: [[f32; 4]; 4],
508 pub(crate) colour: [f32; 4], }
510pub(crate) struct BackdropBlurState {
517 #[allow(dead_code)]
521 pub intermediate_texture: wgpu::Texture,
522 pub intermediate_view: wgpu::TextureView,
523 #[allow(dead_code)]
525 pub blur_a_texture: wgpu::Texture,
526 pub blur_a_view: wgpu::TextureView,
527 #[allow(dead_code)]
529 pub blur_b_texture: wgpu::Texture,
530 pub blur_b_view: wgpu::TextureView,
531 pub size: [u32; 2],
533 pub format: wgpu::TextureFormat,
535}
536
537#[repr(C)]
541#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
542pub(crate) struct GroundPlaneUniform {
543 pub view_proj: [[f32; 4]; 4], pub cam_right: [f32; 4], pub cam_up: [f32; 4], pub cam_back: [f32; 4], pub eye_pos: [f32; 3], pub height: f32, pub colour: [f32; 4], pub shadow_colour: [f32; 4], pub light_vp: [[f32; 4]; 4], pub tan_half_fov: f32, pub aspect: f32, pub tile_size: f32, pub shadow_bias: f32, pub mode: u32, pub shadow_opacity: f32, pub _pad: [f32; 2], pub colour2: [f32; 4], } #[repr(C)]
568#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
569pub(crate) struct GridUniform {
570 pub view_proj: [[f32; 4]; 4], pub cam_to_world: [[f32; 4]; 3], pub tan_half_fov: f32, pub aspect: f32, pub _pad_ivp: [f32; 2], pub eye_pos: [f32; 3], pub grid_z: f32, pub spacing_minor: f32, pub spacing_major: f32, pub snap_origin: [f32; 2], pub colour_minor: [f32; 4], pub colour_major: [f32; 4], }