1use alloc::sync::Arc;
2use bevy_derive::EnumVariantMeta;
3use bevy_ecs::resource::Resource;
4use bevy_math::Vec3;
5#[cfg(feature = "serialize")]
6use bevy_platform::collections::HashMap;
7use bevy_platform::collections::HashSet;
8use bytemuck::{bytes_of, cast_slice};
9use core::hash::{Hash, Hasher};
10#[cfg(feature = "serialize")]
11use serde::{Deserialize, Serialize};
12use thiserror::Error;
13use wgpu_types::{BufferAddress, VertexAttribute, VertexFormat, VertexStepMode};
14
15#[derive(Debug, Clone, Copy, PartialEq)]
16pub struct MeshVertexAttribute {
17 pub name: &'static str,
19
20 pub id: MeshVertexAttributeId,
24
25 pub format: VertexFormat,
27}
28
29#[cfg(feature = "serialize")]
30#[derive(Debug, Clone, Serialize, Deserialize)]
31pub(crate) struct SerializedMeshVertexAttribute {
32 pub(crate) name: String,
33 pub(crate) id: MeshVertexAttributeId,
34 pub(crate) format: VertexFormat,
35}
36
37#[cfg(feature = "serialize")]
38impl SerializedMeshVertexAttribute {
39 pub(crate) fn from_mesh_vertex_attribute(attribute: MeshVertexAttribute) -> Self {
40 Self {
41 name: attribute.name.to_string(),
42 id: attribute.id,
43 format: attribute.format,
44 }
45 }
46
47 pub(crate) fn try_into_mesh_vertex_attribute(
48 self,
49 possible_attributes: &HashMap<Box<str>, MeshVertexAttribute>,
50 ) -> Option<MeshVertexAttribute> {
51 let attr = possible_attributes.get(self.name.as_str())?;
52 if attr.id == self.id {
53 Some(*attr)
54 } else {
55 None
56 }
57 }
58}
59
60impl MeshVertexAttribute {
61 pub const fn new(name: &'static str, id: u64, format: VertexFormat) -> Self {
62 Self {
63 name,
64 id: MeshVertexAttributeId(id),
65 format,
66 }
67 }
68
69 pub const fn at_shader_location(&self, shader_location: u32) -> VertexAttributeDescriptor {
70 VertexAttributeDescriptor::new(shader_location, self.id, self.name)
71 }
72}
73
74#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
75#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
76pub struct MeshVertexAttributeId(u64);
77
78impl From<MeshVertexAttribute> for MeshVertexAttributeId {
79 fn from(attribute: MeshVertexAttribute) -> Self {
80 attribute.id
81 }
82}
83
84#[derive(Debug, Clone, Hash, Eq, PartialEq)]
85pub struct MeshVertexBufferLayout {
86 pub(crate) attribute_ids: Vec<MeshVertexAttributeId>,
87 pub(crate) layout: VertexBufferLayout,
88}
89
90impl MeshVertexBufferLayout {
91 pub fn new(attribute_ids: Vec<MeshVertexAttributeId>, layout: VertexBufferLayout) -> Self {
92 Self {
93 attribute_ids,
94 layout,
95 }
96 }
97
98 #[inline]
99 pub fn contains(&self, attribute_id: impl Into<MeshVertexAttributeId>) -> bool {
100 self.attribute_ids.contains(&attribute_id.into())
101 }
102
103 #[inline]
104 pub fn attribute_ids(&self) -> &[MeshVertexAttributeId] {
105 &self.attribute_ids
106 }
107
108 #[inline]
109 pub fn layout(&self) -> &VertexBufferLayout {
110 &self.layout
111 }
112
113 pub fn get_layout(
114 &self,
115 attribute_descriptors: &[VertexAttributeDescriptor],
116 ) -> Result<VertexBufferLayout, MissingVertexAttributeError> {
117 let mut attributes = Vec::with_capacity(attribute_descriptors.len());
118 for attribute_descriptor in attribute_descriptors {
119 if let Some(index) = self
120 .attribute_ids
121 .iter()
122 .position(|id| *id == attribute_descriptor.id)
123 {
124 let layout_attribute = &self.layout.attributes[index];
125 attributes.push(VertexAttribute {
126 format: layout_attribute.format,
127 offset: layout_attribute.offset,
128 shader_location: attribute_descriptor.shader_location,
129 });
130 } else {
131 return Err(MissingVertexAttributeError {
132 id: attribute_descriptor.id,
133 name: attribute_descriptor.name,
134 pipeline_type: None,
135 });
136 }
137 }
138
139 Ok(VertexBufferLayout {
140 array_stride: self.layout.array_stride,
141 step_mode: self.layout.step_mode,
142 attributes,
143 })
144 }
145}
146
147#[derive(Error, Debug)]
148#[error("Mesh is missing requested attribute: {name} ({id:?}, pipeline type: {pipeline_type:?})")]
149pub struct MissingVertexAttributeError {
150 pub pipeline_type: Option<&'static str>,
151 id: MeshVertexAttributeId,
152 name: &'static str,
153}
154
155pub struct VertexAttributeDescriptor {
156 pub shader_location: u32,
157 pub id: MeshVertexAttributeId,
158 name: &'static str,
159}
160
161impl VertexAttributeDescriptor {
162 pub const fn new(shader_location: u32, id: MeshVertexAttributeId, name: &'static str) -> Self {
163 Self {
164 shader_location,
165 id,
166 name,
167 }
168 }
169}
170
171#[derive(Debug, Clone, PartialEq)]
172pub(crate) struct MeshAttributeData {
173 pub(crate) attribute: MeshVertexAttribute,
174 pub(crate) values: VertexAttributeValues,
175}
176
177#[cfg(feature = "serialize")]
178#[derive(Debug, Clone, Serialize, Deserialize)]
179pub(crate) struct SerializedMeshAttributeData {
180 pub(crate) attribute: SerializedMeshVertexAttribute,
181 pub(crate) values: VertexAttributeValues,
182}
183
184#[cfg(feature = "serialize")]
185impl SerializedMeshAttributeData {
186 pub(crate) fn from_mesh_attribute_data(data: MeshAttributeData) -> Self {
187 Self {
188 attribute: SerializedMeshVertexAttribute::from_mesh_vertex_attribute(data.attribute),
189 values: data.values,
190 }
191 }
192
193 pub(crate) fn try_into_mesh_attribute_data(
194 self,
195 possible_attributes: &HashMap<Box<str>, MeshVertexAttribute>,
196 ) -> Option<MeshAttributeData> {
197 let attribute = self
198 .attribute
199 .try_into_mesh_vertex_attribute(possible_attributes)?;
200 Some(MeshAttributeData {
201 attribute,
202 values: self.values,
203 })
204 }
205}
206
207#[inline]
222pub fn triangle_area_normal(a: [f32; 3], b: [f32; 3], c: [f32; 3]) -> [f32; 3] {
223 let (a, b, c) = (Vec3::from(a), Vec3::from(b), Vec3::from(c));
224 (b - a).cross(c - a).into()
225}
226
227#[inline]
229pub fn triangle_normal(a: [f32; 3], b: [f32; 3], c: [f32; 3]) -> [f32; 3] {
230 let (a, b, c) = (Vec3::from(a), Vec3::from(b), Vec3::from(c));
231 (b - a).cross(c - a).normalize_or_zero().into()
232}
233
234#[derive(Clone, Debug, EnumVariantMeta, PartialEq)]
237#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
238pub enum VertexAttributeValues {
239 Uint8(Vec<u8>),
241 Uint8x2(Vec<[u8; 2]>),
243 Uint8x4(Vec<[u8; 4]>),
245 Sint8(Vec<i8>),
247 Sint8x2(Vec<[i8; 2]>),
249 Sint8x4(Vec<[i8; 4]>),
251 Unorm8(Vec<u8>),
253 Unorm8x2(Vec<[u8; 2]>),
255 Unorm8x4(Vec<[u8; 4]>),
257 Snorm8(Vec<i8>),
259 Snorm8x2(Vec<[i8; 2]>),
261 Snorm8x4(Vec<[i8; 4]>),
263 Uint16(Vec<u16>),
265 Uint16x2(Vec<[u16; 2]>),
267 Uint16x4(Vec<[u16; 4]>),
269 Sint16(Vec<i16>),
271 Sint16x2(Vec<[i16; 2]>),
273 Sint16x4(Vec<[i16; 4]>),
275 Unorm16(Vec<u16>),
277 Unorm16x2(Vec<[u16; 2]>),
279 Unorm16x4(Vec<[u16; 4]>),
281 Snorm16(Vec<i16>),
283 Snorm16x2(Vec<[i16; 2]>),
285 Snorm16x4(Vec<[i16; 4]>),
287 Float16(Vec<half::f16>),
289 Float16x2(Vec<[half::f16; 2]>),
291 Float16x4(Vec<[half::f16; 4]>),
293 Float32(Vec<f32>),
295 Float32x2(Vec<[f32; 2]>),
297 Float32x3(Vec<[f32; 3]>),
299 Float32x4(Vec<[f32; 4]>),
301 Uint32(Vec<u32>),
303 Uint32x2(Vec<[u32; 2]>),
305 Uint32x3(Vec<[u32; 3]>),
307 Uint32x4(Vec<[u32; 4]>),
309 Sint32(Vec<i32>),
311 Sint32x2(Vec<[i32; 2]>),
313 Sint32x3(Vec<[i32; 3]>),
315 Sint32x4(Vec<[i32; 4]>),
317 Float64(Vec<f64>),
319 Float64x2(Vec<[f64; 2]>),
321 Float64x3(Vec<[f64; 3]>),
323 Float64x4(Vec<[f64; 4]>),
325 Unorm10_10_10_2(Vec<u32>),
327 Unorm8x4Bgra(Vec<[u8; 4]>),
329}
330
331impl VertexAttributeValues {
332 pub(crate) fn new(format: VertexFormat) -> Self {
334 match format {
335 VertexFormat::Uint8x2 => VertexAttributeValues::Uint8x2(Vec::new()),
336 VertexFormat::Uint8x4 => VertexAttributeValues::Uint8x4(Vec::new()),
337 VertexFormat::Sint8x2 => VertexAttributeValues::Sint8x2(Vec::new()),
338 VertexFormat::Sint8x4 => VertexAttributeValues::Sint8x4(Vec::new()),
339 VertexFormat::Unorm8x2 => VertexAttributeValues::Unorm8x2(Vec::new()),
340 VertexFormat::Unorm8x4 => VertexAttributeValues::Unorm8x4(Vec::new()),
341 VertexFormat::Snorm8x2 => VertexAttributeValues::Snorm8x2(Vec::new()),
342 VertexFormat::Snorm8x4 => VertexAttributeValues::Snorm8x4(Vec::new()),
343 VertexFormat::Uint16x2 => VertexAttributeValues::Uint16x2(Vec::new()),
344 VertexFormat::Uint16x4 => VertexAttributeValues::Uint16x4(Vec::new()),
345 VertexFormat::Sint16x2 => VertexAttributeValues::Sint16x2(Vec::new()),
346 VertexFormat::Sint16x4 => VertexAttributeValues::Sint16x4(Vec::new()),
347 VertexFormat::Unorm16x2 => VertexAttributeValues::Unorm16x2(Vec::new()),
348 VertexFormat::Unorm16x4 => VertexAttributeValues::Unorm16x4(Vec::new()),
349 VertexFormat::Snorm16x2 => VertexAttributeValues::Snorm16x2(Vec::new()),
350 VertexFormat::Snorm16x4 => VertexAttributeValues::Snorm16x4(Vec::new()),
351 VertexFormat::Float32 => VertexAttributeValues::Float32(Vec::new()),
352 VertexFormat::Float32x2 => VertexAttributeValues::Float32x2(Vec::new()),
353 VertexFormat::Float32x3 => VertexAttributeValues::Float32x3(Vec::new()),
354 VertexFormat::Float32x4 => VertexAttributeValues::Float32x4(Vec::new()),
355 VertexFormat::Uint32 => VertexAttributeValues::Uint32(Vec::new()),
356 VertexFormat::Uint32x2 => VertexAttributeValues::Uint32x2(Vec::new()),
357 VertexFormat::Uint32x3 => VertexAttributeValues::Uint32x3(Vec::new()),
358 VertexFormat::Uint32x4 => VertexAttributeValues::Uint32x4(Vec::new()),
359 VertexFormat::Sint32 => VertexAttributeValues::Sint32(Vec::new()),
360 VertexFormat::Sint32x2 => VertexAttributeValues::Sint32x2(Vec::new()),
361 VertexFormat::Sint32x3 => VertexAttributeValues::Sint32x3(Vec::new()),
362 VertexFormat::Sint32x4 => VertexAttributeValues::Sint32x4(Vec::new()),
363 VertexFormat::Uint8 => VertexAttributeValues::Uint8(Vec::new()),
364 VertexFormat::Sint8 => VertexAttributeValues::Sint8(Vec::new()),
365 VertexFormat::Snorm8 => VertexAttributeValues::Snorm8(Vec::new()),
366 VertexFormat::Unorm8 => VertexAttributeValues::Unorm8(Vec::new()),
367 VertexFormat::Uint16 => VertexAttributeValues::Uint16(Vec::new()),
368 VertexFormat::Sint16 => VertexAttributeValues::Sint16(Vec::new()),
369 VertexFormat::Snorm16 => VertexAttributeValues::Snorm16(Vec::new()),
370 VertexFormat::Unorm16 => VertexAttributeValues::Unorm16(Vec::new()),
371 VertexFormat::Float16 => VertexAttributeValues::Float16(Vec::new()),
372 VertexFormat::Float16x2 => VertexAttributeValues::Float16x2(Vec::new()),
373 VertexFormat::Float16x4 => VertexAttributeValues::Float16x4(Vec::new()),
374 VertexFormat::Float64 => VertexAttributeValues::Float64(Vec::new()),
375 VertexFormat::Float64x2 => VertexAttributeValues::Float64x2(Vec::new()),
376 VertexFormat::Float64x3 => VertexAttributeValues::Float64x3(Vec::new()),
377 VertexFormat::Float64x4 => VertexAttributeValues::Float64x4(Vec::new()),
378 VertexFormat::Unorm8x4Bgra => VertexAttributeValues::Unorm8x4Bgra(Vec::new()),
379 VertexFormat::Unorm10_10_10_2 => VertexAttributeValues::Unorm10_10_10_2(Vec::new()),
380 }
381 }
382
383 #[expect(
386 clippy::match_same_arms,
387 reason = "Although the `values` binding on some match arms may have matching types, each variant has different semantics; thus it's not guaranteed that they will use the same type forever."
388 )]
389 pub fn len(&self) -> usize {
390 match self {
391 VertexAttributeValues::Float32(values) => values.len(),
392 VertexAttributeValues::Sint32(values) => values.len(),
393 VertexAttributeValues::Uint32(values) => values.len(),
394 VertexAttributeValues::Float32x2(values) => values.len(),
395 VertexAttributeValues::Sint32x2(values) => values.len(),
396 VertexAttributeValues::Uint32x2(values) => values.len(),
397 VertexAttributeValues::Float32x3(values) => values.len(),
398 VertexAttributeValues::Sint32x3(values) => values.len(),
399 VertexAttributeValues::Uint32x3(values) => values.len(),
400 VertexAttributeValues::Float32x4(values) => values.len(),
401 VertexAttributeValues::Sint32x4(values) => values.len(),
402 VertexAttributeValues::Uint32x4(values) => values.len(),
403 VertexAttributeValues::Sint16x2(values) => values.len(),
404 VertexAttributeValues::Snorm16x2(values) => values.len(),
405 VertexAttributeValues::Uint16x2(values) => values.len(),
406 VertexAttributeValues::Unorm16x2(values) => values.len(),
407 VertexAttributeValues::Sint16x4(values) => values.len(),
408 VertexAttributeValues::Snorm16x4(values) => values.len(),
409 VertexAttributeValues::Uint16x4(values) => values.len(),
410 VertexAttributeValues::Unorm16x4(values) => values.len(),
411 VertexAttributeValues::Sint8x2(values) => values.len(),
412 VertexAttributeValues::Snorm8x2(values) => values.len(),
413 VertexAttributeValues::Uint8x2(values) => values.len(),
414 VertexAttributeValues::Unorm8x2(values) => values.len(),
415 VertexAttributeValues::Sint8x4(values) => values.len(),
416 VertexAttributeValues::Snorm8x4(values) => values.len(),
417 VertexAttributeValues::Uint8x4(values) => values.len(),
418 VertexAttributeValues::Unorm8x4(values) => values.len(),
419 VertexAttributeValues::Uint8(values) => values.len(),
420 VertexAttributeValues::Sint8(values) => values.len(),
421 VertexAttributeValues::Unorm8(values) => values.len(),
422 VertexAttributeValues::Snorm8(values) => values.len(),
423 VertexAttributeValues::Uint16(values) => values.len(),
424 VertexAttributeValues::Sint16(values) => values.len(),
425 VertexAttributeValues::Unorm16(values) => values.len(),
426 VertexAttributeValues::Snorm16(values) => values.len(),
427 VertexAttributeValues::Float16(values) => values.len(),
428 VertexAttributeValues::Float16x2(values) => values.len(),
429 VertexAttributeValues::Float16x4(values) => values.len(),
430 VertexAttributeValues::Float64(values) => values.len(),
431 VertexAttributeValues::Float64x2(values) => values.len(),
432 VertexAttributeValues::Float64x3(values) => values.len(),
433 VertexAttributeValues::Float64x4(values) => values.len(),
434 VertexAttributeValues::Unorm10_10_10_2(values) => values.len(),
435 VertexAttributeValues::Unorm8x4Bgra(values) => values.len(),
436 }
437 }
438
439 pub fn is_empty(&self) -> bool {
441 self.len() == 0
442 }
443
444 pub fn as_float3(&self) -> Option<&[[f32; 3]]> {
446 match self {
447 VertexAttributeValues::Float32x3(values) => Some(values),
448 _ => None,
449 }
450 }
451
452 #[expect(
456 clippy::match_same_arms,
457 reason = "Although the `values` binding on some match arms may have matching types, each variant has different semantics; thus it's not guaranteed that they will use the same type forever."
458 )]
459 pub fn get_bytes(&self) -> &[u8] {
460 match self {
461 VertexAttributeValues::Float32(values) => cast_slice(values),
462 VertexAttributeValues::Sint32(values) => cast_slice(values),
463 VertexAttributeValues::Uint32(values) => cast_slice(values),
464 VertexAttributeValues::Float32x2(values) => cast_slice(values),
465 VertexAttributeValues::Sint32x2(values) => cast_slice(values),
466 VertexAttributeValues::Uint32x2(values) => cast_slice(values),
467 VertexAttributeValues::Float32x3(values) => cast_slice(values),
468 VertexAttributeValues::Sint32x3(values) => cast_slice(values),
469 VertexAttributeValues::Uint32x3(values) => cast_slice(values),
470 VertexAttributeValues::Float32x4(values) => cast_slice(values),
471 VertexAttributeValues::Sint32x4(values) => cast_slice(values),
472 VertexAttributeValues::Uint32x4(values) => cast_slice(values),
473 VertexAttributeValues::Sint16x2(values) => cast_slice(values),
474 VertexAttributeValues::Snorm16x2(values) => cast_slice(values),
475 VertexAttributeValues::Uint16x2(values) => cast_slice(values),
476 VertexAttributeValues::Unorm16x2(values) => cast_slice(values),
477 VertexAttributeValues::Sint16x4(values) => cast_slice(values),
478 VertexAttributeValues::Snorm16x4(values) => cast_slice(values),
479 VertexAttributeValues::Uint16x4(values) => cast_slice(values),
480 VertexAttributeValues::Unorm16x4(values) => cast_slice(values),
481 VertexAttributeValues::Sint8x2(values) => cast_slice(values),
482 VertexAttributeValues::Snorm8x2(values) => cast_slice(values),
483 VertexAttributeValues::Uint8x2(values) => cast_slice(values),
484 VertexAttributeValues::Unorm8x2(values) => cast_slice(values),
485 VertexAttributeValues::Sint8x4(values) => cast_slice(values),
486 VertexAttributeValues::Snorm8x4(values) => cast_slice(values),
487 VertexAttributeValues::Uint8x4(values) => cast_slice(values),
488 VertexAttributeValues::Unorm8x4(values) => cast_slice(values),
489 VertexAttributeValues::Uint8(values) => cast_slice(values),
490 VertexAttributeValues::Sint8(values) => cast_slice(values),
491 VertexAttributeValues::Unorm8(values) => cast_slice(values),
492 VertexAttributeValues::Snorm8(values) => cast_slice(values),
493 VertexAttributeValues::Uint16(values) => cast_slice(values),
494 VertexAttributeValues::Sint16(values) => cast_slice(values),
495 VertexAttributeValues::Unorm16(values) => cast_slice(values),
496 VertexAttributeValues::Snorm16(values) => cast_slice(values),
497 VertexAttributeValues::Float16(values) => cast_slice(values),
498 VertexAttributeValues::Float16x2(values) => cast_slice(values),
499 VertexAttributeValues::Float16x4(values) => cast_slice(values),
500 VertexAttributeValues::Float64(values) => cast_slice(values),
501 VertexAttributeValues::Float64x2(values) => cast_slice(values),
502 VertexAttributeValues::Float64x3(values) => cast_slice(values),
503 VertexAttributeValues::Float64x4(values) => cast_slice(values),
504 VertexAttributeValues::Unorm10_10_10_2(values) => cast_slice(values),
505 VertexAttributeValues::Unorm8x4Bgra(values) => cast_slice(values),
506 }
507 }
508
509 #[expect(
510 clippy::match_same_arms,
511 reason = "Although the `values` binding on some match arms may have matching types, each variant has different semantics; thus it's not guaranteed that they will use the same type forever."
512 )]
513 pub(crate) fn get_bytes_at(&self, i: usize) -> &[u8] {
514 match self {
515 VertexAttributeValues::Float32(values) => bytes_of(&values[i]),
516 VertexAttributeValues::Sint32(values) => bytes_of(&values[i]),
517 VertexAttributeValues::Uint32(values) => bytes_of(&values[i]),
518 VertexAttributeValues::Float32x2(values) => bytes_of(&values[i]),
519 VertexAttributeValues::Sint32x2(values) => bytes_of(&values[i]),
520 VertexAttributeValues::Uint32x2(values) => bytes_of(&values[i]),
521 VertexAttributeValues::Float32x3(values) => bytes_of(&values[i]),
522 VertexAttributeValues::Sint32x3(values) => bytes_of(&values[i]),
523 VertexAttributeValues::Uint32x3(values) => bytes_of(&values[i]),
524 VertexAttributeValues::Float32x4(values) => bytes_of(&values[i]),
525 VertexAttributeValues::Sint32x4(values) => bytes_of(&values[i]),
526 VertexAttributeValues::Uint32x4(values) => bytes_of(&values[i]),
527 VertexAttributeValues::Sint16x2(values) => bytes_of(&values[i]),
528 VertexAttributeValues::Snorm16x2(values) => bytes_of(&values[i]),
529 VertexAttributeValues::Uint16x2(values) => bytes_of(&values[i]),
530 VertexAttributeValues::Unorm16x2(values) => bytes_of(&values[i]),
531 VertexAttributeValues::Sint16x4(values) => bytes_of(&values[i]),
532 VertexAttributeValues::Snorm16x4(values) => bytes_of(&values[i]),
533 VertexAttributeValues::Uint16x4(values) => bytes_of(&values[i]),
534 VertexAttributeValues::Unorm16x4(values) => bytes_of(&values[i]),
535 VertexAttributeValues::Sint8x2(values) => bytes_of(&values[i]),
536 VertexAttributeValues::Snorm8x2(values) => bytes_of(&values[i]),
537 VertexAttributeValues::Uint8x2(values) => bytes_of(&values[i]),
538 VertexAttributeValues::Unorm8x2(values) => bytes_of(&values[i]),
539 VertexAttributeValues::Sint8x4(values) => bytes_of(&values[i]),
540 VertexAttributeValues::Snorm8x4(values) => bytes_of(&values[i]),
541 VertexAttributeValues::Uint8x4(values) => bytes_of(&values[i]),
542 VertexAttributeValues::Unorm8x4(values) => bytes_of(&values[i]),
543 VertexAttributeValues::Uint8(values) => bytes_of(&values[i]),
544 VertexAttributeValues::Sint8(values) => bytes_of(&values[i]),
545 VertexAttributeValues::Unorm8(values) => bytes_of(&values[i]),
546 VertexAttributeValues::Snorm8(values) => bytes_of(&values[i]),
547 VertexAttributeValues::Uint16(values) => bytes_of(&values[i]),
548 VertexAttributeValues::Sint16(values) => bytes_of(&values[i]),
549 VertexAttributeValues::Unorm16(values) => bytes_of(&values[i]),
550 VertexAttributeValues::Snorm16(values) => bytes_of(&values[i]),
551 VertexAttributeValues::Float16(values) => bytes_of(&values[i]),
552 VertexAttributeValues::Float16x2(values) => bytes_of(&values[i]),
553 VertexAttributeValues::Float16x4(values) => bytes_of(&values[i]),
554 VertexAttributeValues::Float64(values) => bytes_of(&values[i]),
555 VertexAttributeValues::Float64x2(values) => bytes_of(&values[i]),
556 VertexAttributeValues::Float64x3(values) => bytes_of(&values[i]),
557 VertexAttributeValues::Float64x4(values) => bytes_of(&values[i]),
558 VertexAttributeValues::Unorm10_10_10_2(values) => bytes_of(&values[i]),
559 VertexAttributeValues::Unorm8x4Bgra(values) => bytes_of(&values[i]),
560 }
561 }
562
563 #[expect(
564 clippy::match_same_arms,
565 reason = "Although the `values` binding on some match arms may have matching types, each variant has different semantics; thus it's not guaranteed that they will use the same type forever."
566 )]
567 pub(crate) fn push_from(&mut self, source: &VertexAttributeValues, i: usize) {
568 match (self, source) {
569 (VertexAttributeValues::Float32(this), VertexAttributeValues::Float32(source)) => {
570 this.push(source[i]);
571 }
572 (VertexAttributeValues::Float32(_), _) => panic!("Mismatched vertex attribute values"),
573 (VertexAttributeValues::Sint32(this), VertexAttributeValues::Sint32(source)) => {
574 this.push(source[i]);
575 }
576 (VertexAttributeValues::Sint32(_), _) => panic!("Mismatched vertex attribute values"),
577 (VertexAttributeValues::Uint32(this), VertexAttributeValues::Uint32(source)) => {
578 this.push(source[i]);
579 }
580 (VertexAttributeValues::Uint32(_), _) => panic!("Mismatched vertex attribute values"),
581 (VertexAttributeValues::Float32x2(this), VertexAttributeValues::Float32x2(source)) => {
582 this.push(source[i]);
583 }
584 (VertexAttributeValues::Float32x2(_), _) => {
585 panic!("Mismatched vertex attribute values")
586 }
587 (VertexAttributeValues::Sint32x2(this), VertexAttributeValues::Sint32x2(source)) => {
588 this.push(source[i]);
589 }
590 (VertexAttributeValues::Sint32x2(_), _) => panic!("Mismatched vertex attribute values"),
591 (VertexAttributeValues::Uint32x2(this), VertexAttributeValues::Uint32x2(source)) => {
592 this.push(source[i]);
593 }
594 (VertexAttributeValues::Uint32x2(_), _) => panic!("Mismatched vertex attribute values"),
595 (VertexAttributeValues::Float32x3(this), VertexAttributeValues::Float32x3(source)) => {
596 this.push(source[i]);
597 }
598 (VertexAttributeValues::Float32x3(_), _) => {
599 panic!("Mismatched vertex attribute values")
600 }
601 (VertexAttributeValues::Sint32x3(this), VertexAttributeValues::Sint32x3(source)) => {
602 this.push(source[i]);
603 }
604 (VertexAttributeValues::Sint32x3(_), _) => panic!("Mismatched vertex attribute values"),
605 (VertexAttributeValues::Uint32x3(this), VertexAttributeValues::Uint32x3(source)) => {
606 this.push(source[i]);
607 }
608 (VertexAttributeValues::Uint32x3(_), _) => panic!("Mismatched vertex attribute values"),
609 (VertexAttributeValues::Float32x4(this), VertexAttributeValues::Float32x4(source)) => {
610 this.push(source[i]);
611 }
612 (VertexAttributeValues::Float32x4(_), _) => {
613 panic!("Mismatched vertex attribute values")
614 }
615 (VertexAttributeValues::Sint32x4(this), VertexAttributeValues::Sint32x4(source)) => {
616 this.push(source[i]);
617 }
618 (VertexAttributeValues::Sint32x4(_), _) => panic!("Mismatched vertex attribute values"),
619 (VertexAttributeValues::Uint32x4(this), VertexAttributeValues::Uint32x4(source)) => {
620 this.push(source[i]);
621 }
622 (VertexAttributeValues::Uint32x4(_), _) => panic!("Mismatched vertex attribute values"),
623 (VertexAttributeValues::Sint16x2(this), VertexAttributeValues::Sint16x2(source)) => {
624 this.push(source[i]);
625 }
626 (VertexAttributeValues::Sint16x2(_), _) => panic!("Mismatched vertex attribute values"),
627 (VertexAttributeValues::Snorm16x2(this), VertexAttributeValues::Snorm16x2(source)) => {
628 this.push(source[i]);
629 }
630 (VertexAttributeValues::Snorm16x2(_), _) => {
631 panic!("Mismatched vertex attribute values")
632 }
633 (VertexAttributeValues::Uint16x2(this), VertexAttributeValues::Uint16x2(source)) => {
634 this.push(source[i]);
635 }
636 (VertexAttributeValues::Uint16x2(_), _) => panic!("Mismatched vertex attribute values"),
637 (VertexAttributeValues::Unorm16x2(this), VertexAttributeValues::Unorm16x2(source)) => {
638 this.push(source[i]);
639 }
640 (VertexAttributeValues::Unorm16x2(_), _) => {
641 panic!("Mismatched vertex attribute values")
642 }
643 (VertexAttributeValues::Sint16x4(this), VertexAttributeValues::Sint16x4(source)) => {
644 this.push(source[i]);
645 }
646 (VertexAttributeValues::Sint16x4(_), _) => panic!("Mismatched vertex attribute values"),
647 (VertexAttributeValues::Snorm16x4(this), VertexAttributeValues::Snorm16x4(source)) => {
648 this.push(source[i]);
649 }
650 (VertexAttributeValues::Snorm16x4(_), _) => {
651 panic!("Mismatched vertex attribute values")
652 }
653 (VertexAttributeValues::Uint16x4(this), VertexAttributeValues::Uint16x4(source)) => {
654 this.push(source[i]);
655 }
656 (VertexAttributeValues::Uint16x4(_), _) => panic!("Mismatched vertex attribute values"),
657 (VertexAttributeValues::Unorm16x4(this), VertexAttributeValues::Unorm16x4(source)) => {
658 this.push(source[i]);
659 }
660 (VertexAttributeValues::Unorm16x4(_), _) => {
661 panic!("Mismatched vertex attribute values")
662 }
663 (VertexAttributeValues::Sint8x2(this), VertexAttributeValues::Sint8x2(source)) => {
664 this.push(source[i]);
665 }
666 (VertexAttributeValues::Sint8x2(_), _) => panic!("Mismatched vertex attribute values"),
667 (VertexAttributeValues::Snorm8x2(this), VertexAttributeValues::Snorm8x2(source)) => {
668 this.push(source[i]);
669 }
670 (VertexAttributeValues::Snorm8x2(_), _) => panic!("Mismatched vertex attribute values"),
671 (VertexAttributeValues::Uint8x2(this), VertexAttributeValues::Uint8x2(source)) => {
672 this.push(source[i]);
673 }
674 (VertexAttributeValues::Uint8x2(_), _) => panic!("Mismatched vertex attribute values"),
675 (VertexAttributeValues::Unorm8x2(this), VertexAttributeValues::Unorm8x2(source)) => {
676 this.push(source[i]);
677 }
678 (VertexAttributeValues::Unorm8x2(_), _) => panic!("Mismatched vertex attribute values"),
679 (VertexAttributeValues::Sint8x4(this), VertexAttributeValues::Sint8x4(source)) => {
680 this.push(source[i]);
681 }
682 (VertexAttributeValues::Sint8x4(_), _) => panic!("Mismatched vertex attribute values"),
683 (VertexAttributeValues::Snorm8x4(this), VertexAttributeValues::Snorm8x4(source)) => {
684 this.push(source[i]);
685 }
686 (VertexAttributeValues::Snorm8x4(_), _) => panic!("Mismatched vertex attribute values"),
687 (VertexAttributeValues::Uint8x4(this), VertexAttributeValues::Uint8x4(source)) => {
688 this.push(source[i]);
689 }
690 (VertexAttributeValues::Uint8x4(_), _) => panic!("Mismatched vertex attribute values"),
691 (VertexAttributeValues::Unorm8x4(this), VertexAttributeValues::Unorm8x4(source)) => {
692 this.push(source[i]);
693 }
694 (VertexAttributeValues::Unorm8x4(_), _) => panic!("Mismatched vertex attribute values"),
695 (VertexAttributeValues::Uint8(this), VertexAttributeValues::Uint8(source)) => {
696 this.push(source[i]);
697 }
698 (VertexAttributeValues::Uint8(_), _) => panic!("Mismatched vertex attribute values"),
699 (VertexAttributeValues::Sint8(this), VertexAttributeValues::Sint8(source)) => {
700 this.push(source[i]);
701 }
702 (VertexAttributeValues::Sint8(_), _) => panic!("Mismatched vertex attribute values"),
703 (VertexAttributeValues::Unorm8(this), VertexAttributeValues::Unorm8(source)) => {
704 this.push(source[i]);
705 }
706 (VertexAttributeValues::Unorm8(_), _) => panic!("Mismatched vertex attribute values"),
707 (VertexAttributeValues::Snorm8(this), VertexAttributeValues::Snorm8(source)) => {
708 this.push(source[i]);
709 }
710 (VertexAttributeValues::Snorm8(_), _) => panic!("Mismatched vertex attribute values"),
711 (VertexAttributeValues::Uint16(this), VertexAttributeValues::Uint16(source)) => {
712 this.push(source[i]);
713 }
714 (VertexAttributeValues::Uint16(_), _) => panic!("Mismatched vertex attribute values"),
715 (VertexAttributeValues::Sint16(this), VertexAttributeValues::Sint16(source)) => {
716 this.push(source[i]);
717 }
718 (VertexAttributeValues::Sint16(_), _) => panic!("Mismatched vertex attribute values"),
719 (VertexAttributeValues::Unorm16(this), VertexAttributeValues::Unorm16(source)) => {
720 this.push(source[i]);
721 }
722 (VertexAttributeValues::Unorm16(_), _) => panic!("Mismatched vertex attribute values"),
723 (VertexAttributeValues::Snorm16(this), VertexAttributeValues::Snorm16(source)) => {
724 this.push(source[i]);
725 }
726 (VertexAttributeValues::Snorm16(_), _) => panic!("Mismatched vertex attribute values"),
727 (VertexAttributeValues::Float16(this), VertexAttributeValues::Float16(source)) => {
728 this.push(source[i]);
729 }
730 (VertexAttributeValues::Float16(_), _) => panic!("Mismatched vertex attribute values"),
731 (VertexAttributeValues::Float16x2(this), VertexAttributeValues::Float16x2(source)) => {
732 this.push(source[i]);
733 }
734 (VertexAttributeValues::Float16x2(_), _) => {
735 panic!("Mismatched vertex attribute values")
736 }
737 (VertexAttributeValues::Float16x4(this), VertexAttributeValues::Float16x4(source)) => {
738 this.push(source[i]);
739 }
740 (VertexAttributeValues::Float16x4(_), _) => {
741 panic!("Mismatched vertex attribute values")
742 }
743 (VertexAttributeValues::Float64(this), VertexAttributeValues::Float64(source)) => {
744 this.push(source[i]);
745 }
746 (VertexAttributeValues::Float64(_), _) => panic!("Mismatched vertex attribute values"),
747 (VertexAttributeValues::Float64x2(this), VertexAttributeValues::Float64x2(source)) => {
748 this.push(source[i]);
749 }
750 (VertexAttributeValues::Float64x2(_), _) => {
751 panic!("Mismatched vertex attribute values")
752 }
753 (VertexAttributeValues::Float64x3(this), VertexAttributeValues::Float64x3(source)) => {
754 this.push(source[i]);
755 }
756 (VertexAttributeValues::Float64x3(_), _) => {
757 panic!("Mismatched vertex attribute values")
758 }
759 (VertexAttributeValues::Float64x4(this), VertexAttributeValues::Float64x4(source)) => {
760 this.push(source[i]);
761 }
762 (VertexAttributeValues::Float64x4(_), _) => {
763 panic!("Mismatched vertex attribute values")
764 }
765 (
766 VertexAttributeValues::Unorm10_10_10_2(this),
767 VertexAttributeValues::Unorm10_10_10_2(source),
768 ) => {
769 this.push(source[i]);
770 }
771 (VertexAttributeValues::Unorm10_10_10_2(_), _) => {
772 panic!("Mismatched vertex attribute values")
773 }
774 (
775 VertexAttributeValues::Unorm8x4Bgra(this),
776 VertexAttributeValues::Unorm8x4Bgra(source),
777 ) => {
778 this.push(source[i]);
779 }
780 (VertexAttributeValues::Unorm8x4Bgra(_), _) => {
781 panic!("Mismatched vertex attribute values")
782 }
783 }
784 }
785
786 #[expect(
787 clippy::match_same_arms,
788 reason = "Although the `values` binding on some match arms may have matching types, each variant has different semantics; thus it's not guaranteed that they will use the same type forever."
789 )]
790 pub(crate) fn shrink_to_fit(&mut self) {
791 match self {
792 VertexAttributeValues::Float32(v) => v.shrink_to_fit(),
793 VertexAttributeValues::Sint32(v) => v.shrink_to_fit(),
794 VertexAttributeValues::Uint32(v) => v.shrink_to_fit(),
795 VertexAttributeValues::Float32x2(v) => v.shrink_to_fit(),
796 VertexAttributeValues::Sint32x2(v) => v.shrink_to_fit(),
797 VertexAttributeValues::Uint32x2(v) => v.shrink_to_fit(),
798 VertexAttributeValues::Float32x3(v) => v.shrink_to_fit(),
799 VertexAttributeValues::Sint32x3(v) => v.shrink_to_fit(),
800 VertexAttributeValues::Uint32x3(v) => v.shrink_to_fit(),
801 VertexAttributeValues::Float32x4(v) => v.shrink_to_fit(),
802 VertexAttributeValues::Sint32x4(v) => v.shrink_to_fit(),
803 VertexAttributeValues::Uint32x4(v) => v.shrink_to_fit(),
804 VertexAttributeValues::Sint16x2(v) => v.shrink_to_fit(),
805 VertexAttributeValues::Snorm16x2(v) => v.shrink_to_fit(),
806 VertexAttributeValues::Uint16x2(v) => v.shrink_to_fit(),
807 VertexAttributeValues::Unorm16x2(v) => v.shrink_to_fit(),
808 VertexAttributeValues::Sint16x4(v) => v.shrink_to_fit(),
809 VertexAttributeValues::Snorm16x4(v) => v.shrink_to_fit(),
810 VertexAttributeValues::Uint16x4(v) => v.shrink_to_fit(),
811 VertexAttributeValues::Unorm16x4(v) => v.shrink_to_fit(),
812 VertexAttributeValues::Sint8x2(v) => v.shrink_to_fit(),
813 VertexAttributeValues::Snorm8x2(v) => v.shrink_to_fit(),
814 VertexAttributeValues::Uint8x2(v) => v.shrink_to_fit(),
815 VertexAttributeValues::Unorm8x2(v) => v.shrink_to_fit(),
816 VertexAttributeValues::Sint8x4(v) => v.shrink_to_fit(),
817 VertexAttributeValues::Snorm8x4(v) => v.shrink_to_fit(),
818 VertexAttributeValues::Uint8x4(v) => v.shrink_to_fit(),
819 VertexAttributeValues::Unorm8x4(v) => v.shrink_to_fit(),
820 VertexAttributeValues::Uint8(v) => v.shrink_to_fit(),
821 VertexAttributeValues::Sint8(v) => v.shrink_to_fit(),
822 VertexAttributeValues::Unorm8(v) => v.shrink_to_fit(),
823 VertexAttributeValues::Snorm8(v) => v.shrink_to_fit(),
824 VertexAttributeValues::Uint16(v) => v.shrink_to_fit(),
825 VertexAttributeValues::Sint16(v) => v.shrink_to_fit(),
826 VertexAttributeValues::Unorm16(v) => v.shrink_to_fit(),
827 VertexAttributeValues::Snorm16(v) => v.shrink_to_fit(),
828 VertexAttributeValues::Float16(v) => v.shrink_to_fit(),
829 VertexAttributeValues::Float16x2(v) => v.shrink_to_fit(),
830 VertexAttributeValues::Float16x4(v) => v.shrink_to_fit(),
831 VertexAttributeValues::Float64(v) => v.shrink_to_fit(),
832 VertexAttributeValues::Float64x2(v) => v.shrink_to_fit(),
833 VertexAttributeValues::Float64x3(v) => v.shrink_to_fit(),
834 VertexAttributeValues::Float64x4(v) => v.shrink_to_fit(),
835 VertexAttributeValues::Unorm10_10_10_2(v) => v.shrink_to_fit(),
836 VertexAttributeValues::Unorm8x4Bgra(v) => v.shrink_to_fit(),
837 }
838 }
839}
840
841impl From<&VertexAttributeValues> for VertexFormat {
842 fn from(values: &VertexAttributeValues) -> Self {
843 match values {
844 VertexAttributeValues::Float32(_) => VertexFormat::Float32,
845 VertexAttributeValues::Sint32(_) => VertexFormat::Sint32,
846 VertexAttributeValues::Uint32(_) => VertexFormat::Uint32,
847 VertexAttributeValues::Float32x2(_) => VertexFormat::Float32x2,
848 VertexAttributeValues::Sint32x2(_) => VertexFormat::Sint32x2,
849 VertexAttributeValues::Uint32x2(_) => VertexFormat::Uint32x2,
850 VertexAttributeValues::Float32x3(_) => VertexFormat::Float32x3,
851 VertexAttributeValues::Sint32x3(_) => VertexFormat::Sint32x3,
852 VertexAttributeValues::Uint32x3(_) => VertexFormat::Uint32x3,
853 VertexAttributeValues::Float32x4(_) => VertexFormat::Float32x4,
854 VertexAttributeValues::Sint32x4(_) => VertexFormat::Sint32x4,
855 VertexAttributeValues::Uint32x4(_) => VertexFormat::Uint32x4,
856 VertexAttributeValues::Sint16x2(_) => VertexFormat::Sint16x2,
857 VertexAttributeValues::Snorm16x2(_) => VertexFormat::Snorm16x2,
858 VertexAttributeValues::Uint16x2(_) => VertexFormat::Uint16x2,
859 VertexAttributeValues::Unorm16x2(_) => VertexFormat::Unorm16x2,
860 VertexAttributeValues::Sint16x4(_) => VertexFormat::Sint16x4,
861 VertexAttributeValues::Snorm16x4(_) => VertexFormat::Snorm16x4,
862 VertexAttributeValues::Uint16x4(_) => VertexFormat::Uint16x4,
863 VertexAttributeValues::Unorm16x4(_) => VertexFormat::Unorm16x4,
864 VertexAttributeValues::Sint8x2(_) => VertexFormat::Sint8x2,
865 VertexAttributeValues::Snorm8x2(_) => VertexFormat::Snorm8x2,
866 VertexAttributeValues::Uint8x2(_) => VertexFormat::Uint8x2,
867 VertexAttributeValues::Unorm8x2(_) => VertexFormat::Unorm8x2,
868 VertexAttributeValues::Sint8x4(_) => VertexFormat::Sint8x4,
869 VertexAttributeValues::Snorm8x4(_) => VertexFormat::Snorm8x4,
870 VertexAttributeValues::Uint8x4(_) => VertexFormat::Uint8x4,
871 VertexAttributeValues::Unorm8x4(_) => VertexFormat::Unorm8x4,
872 VertexAttributeValues::Uint8(_) => VertexFormat::Uint8,
873 VertexAttributeValues::Sint8(_) => VertexFormat::Sint8,
874 VertexAttributeValues::Unorm8(_) => VertexFormat::Unorm8,
875 VertexAttributeValues::Snorm8(_) => VertexFormat::Snorm8,
876 VertexAttributeValues::Uint16(_) => VertexFormat::Uint16,
877 VertexAttributeValues::Sint16(_) => VertexFormat::Sint16,
878 VertexAttributeValues::Unorm16(_) => VertexFormat::Unorm16,
879 VertexAttributeValues::Snorm16(_) => VertexFormat::Snorm16,
880 VertexAttributeValues::Float16(_) => VertexFormat::Float16,
881 VertexAttributeValues::Float16x2(_) => VertexFormat::Float16x2,
882 VertexAttributeValues::Float16x4(_) => VertexFormat::Float16x4,
883 VertexAttributeValues::Float64(_) => VertexFormat::Float64,
884 VertexAttributeValues::Float64x2(_) => VertexFormat::Float64x2,
885 VertexAttributeValues::Float64x3(_) => VertexFormat::Float64x3,
886 VertexAttributeValues::Float64x4(_) => VertexFormat::Float64x4,
887 VertexAttributeValues::Unorm10_10_10_2(_) => VertexFormat::Unorm10_10_10_2,
888 VertexAttributeValues::Unorm8x4Bgra(_) => VertexFormat::Unorm8x4Bgra,
889 }
890 }
891}
892
893#[derive(Default, Clone, Debug, Hash, Eq, PartialEq)]
895pub struct VertexBufferLayout {
896 pub array_stride: BufferAddress,
898 pub step_mode: VertexStepMode,
900 pub attributes: Vec<VertexAttribute>,
902}
903
904impl VertexBufferLayout {
905 pub fn from_vertex_formats<T: IntoIterator<Item = VertexFormat>>(
910 step_mode: VertexStepMode,
911 vertex_formats: T,
912 ) -> Self {
913 let mut offset = 0;
914 let mut attributes = Vec::new();
915 for (shader_location, format) in vertex_formats.into_iter().enumerate() {
916 attributes.push(VertexAttribute {
917 format,
918 offset,
919 shader_location: shader_location as u32,
920 });
921 offset += format.size();
922 }
923
924 VertexBufferLayout {
925 array_stride: offset,
926 step_mode,
927 attributes,
928 }
929 }
930
931 pub fn offset_locations_by(mut self, location: u32) -> Self {
934 self.attributes.iter_mut().for_each(|attr| {
935 attr.shader_location += location;
936 });
937 self
938 }
939}
940
941#[derive(Clone, Debug)]
951pub struct MeshVertexBufferLayoutRef(pub Arc<MeshVertexBufferLayout>);
952
953#[derive(Clone, Default, Resource)]
955pub struct MeshVertexBufferLayouts(HashSet<Arc<MeshVertexBufferLayout>>);
956
957impl MeshVertexBufferLayouts {
958 pub fn insert(&mut self, layout: MeshVertexBufferLayout) -> MeshVertexBufferLayoutRef {
962 MeshVertexBufferLayoutRef(
967 self.0
968 .get_or_insert_with(&layout, |layout| Arc::new(layout.clone()))
969 .clone(),
970 )
971 }
972}
973
974impl PartialEq for MeshVertexBufferLayoutRef {
975 fn eq(&self, other: &Self) -> bool {
976 Arc::ptr_eq(&self.0, &other.0)
977 }
978}
979
980impl Eq for MeshVertexBufferLayoutRef {}
981
982impl Hash for MeshVertexBufferLayoutRef {
983 fn hash<H: Hasher>(&self, state: &mut H) {
984 (Arc::as_ptr(&self.0) as usize).hash(state);
987 }
988}