Skip to main content

bevy_mesh/
vertex.rs

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    /// The friendly name of the vertex attribute
18    pub name: &'static str,
19
20    /// The _unique_ id of the vertex attribute. This will also determine sort ordering
21    /// when generating vertex buffers. Built-in / standard attributes will use "close to zero"
22    /// indices. When in doubt, use a random / very large u64 to avoid conflicts.
23    pub id: MeshVertexAttributeId,
24
25    /// The format of the vertex attribute.
26    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/// Compute a vector whose direction is the normal of the triangle formed by
208/// points a, b, c, and whose magnitude is double the area of the triangle. This
209/// is useful for computing smooth normals where the contributing normals are
210/// proportionate to the areas of the triangles as [discussed
211/// here](https://iquilezles.org/articles/normals/).
212///
213/// Question: Why double the area? Because the area of a triangle _A_ is
214/// determined by this equation:
215///
216/// _A = |(b - a) x (c - a)| / 2_
217///
218/// By computing _2 A_ we avoid a division operation, and when calculating the
219/// the sum of these vectors which are then normalized, a constant multiple has
220/// no effect.
221#[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/// Compute the normal of a face made of three points: a, b, and c.
228#[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/// Contains an array where each entry describes a property of a single vertex.
235/// Matches the [`VertexFormats`](VertexFormat).
236#[derive(Clone, Debug, EnumVariantMeta, PartialEq)]
237#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
238pub enum VertexAttributeValues {
239    /// One unsigned byte (u8). `u32` in shaders.
240    Uint8(Vec<u8>),
241    /// Two unsigned bytes (u8). `vec2<u32>` in shaders.
242    Uint8x2(Vec<[u8; 2]>),
243    /// Four unsigned bytes (u8). `vec4<u32>` in shaders.
244    Uint8x4(Vec<[u8; 4]>),
245    /// One signed byte (i8). `i32` in shaders.
246    Sint8(Vec<i8>),
247    /// Two signed bytes (i8). `vec2<i32>` in shaders.
248    Sint8x2(Vec<[i8; 2]>),
249    /// Four signed bytes (i8). `vec4<i32>` in shaders.
250    Sint8x4(Vec<[i8; 4]>),
251    /// One unsigned byte (u8). [0, 255] converted to float [0, 1] `f32` in shaders.
252    Unorm8(Vec<u8>),
253    /// Two unsigned bytes (u8). [0, 255] converted to float [0, 1] `vec2<f32>` in shaders.
254    Unorm8x2(Vec<[u8; 2]>),
255    /// Four unsigned bytes (u8). [0, 255] converted to float [0, 1] `vec4<f32>` in shaders.
256    Unorm8x4(Vec<[u8; 4]>),
257    /// One signed byte (i8). [&minus;127, 127] converted to float [&minus;1, 1] `f32` in shaders.
258    Snorm8(Vec<i8>),
259    /// Two signed bytes (i8). [&minus;127, 127] converted to float [&minus;1, 1] `vec2<f32>` in shaders.
260    Snorm8x2(Vec<[i8; 2]>),
261    /// Four signed bytes (i8). [&minus;127, 127] converted to float [&minus;1, 1] `vec4<f32>` in shaders.
262    Snorm8x4(Vec<[i8; 4]>),
263    /// One unsigned short (u16). `u32` in shaders.
264    Uint16(Vec<u16>),
265    /// Two unsigned shorts (u16). `vec2<u32>` in shaders.
266    Uint16x2(Vec<[u16; 2]>),
267    /// Four unsigned shorts (u16). `vec4<u32>` in shaders.
268    Uint16x4(Vec<[u16; 4]>),
269    /// One signed short (i16). `i32` in shaders.
270    Sint16(Vec<i16>),
271    /// Two signed shorts (i16). `vec2<i32>` in shaders.
272    Sint16x2(Vec<[i16; 2]>),
273    /// Four signed shorts (i16). `vec4<i32>` in shaders.
274    Sint16x4(Vec<[i16; 4]>),
275    /// One unsigned short (u16). [0, 65535] converted to float [0, 1] `f32` in shaders.
276    Unorm16(Vec<u16>),
277    /// Two unsigned shorts (u16). [0, 65535] converted to float [0, 1] `vec2<f32>` in shaders.
278    Unorm16x2(Vec<[u16; 2]>),
279    /// Four unsigned shorts (u16). [0, 65535] converted to float [0, 1] `vec4<f32>` in shaders.
280    Unorm16x4(Vec<[u16; 4]>),
281    /// One signed short (i16). [&minus;32767, 32767] converted to float [&minus;1, 1] `f32` in shaders.
282    Snorm16(Vec<i16>),
283    /// Two signed shorts (i16). [&minus;32767, 32767] converted to float [&minus;1, 1] `vec2<f32>` in shaders.
284    Snorm16x2(Vec<[i16; 2]>),
285    /// Four signed shorts (i16). [&minus;32767, 32767] converted to float [&minus;1, 1] `vec4<f32>` in shaders.
286    Snorm16x4(Vec<[i16; 4]>),
287    /// One half-precision float (no Rust equiv). `f32` in shaders.
288    Float16(Vec<half::f16>),
289    /// Two half-precision floats (no Rust equiv). `vec2<f32>` in shaders.
290    Float16x2(Vec<[half::f16; 2]>),
291    /// Four half-precision floats (no Rust equiv). `vec4<f32>` in shaders.
292    Float16x4(Vec<[half::f16; 4]>),
293    /// One single-precision float (f32). `f32` in shaders.
294    Float32(Vec<f32>),
295    /// Two single-precision floats (f32). `vec2<f32>` in shaders.
296    Float32x2(Vec<[f32; 2]>),
297    /// Three single-precision floats (f32). `vec3<f32>` in shaders.
298    Float32x3(Vec<[f32; 3]>),
299    /// Four single-precision floats (f32). `vec4<f32>` in shaders.
300    Float32x4(Vec<[f32; 4]>),
301    /// One unsigned int (u32). `u32` in shaders.
302    Uint32(Vec<u32>),
303    /// Two unsigned ints (u32). `vec2<u32>` in shaders.
304    Uint32x2(Vec<[u32; 2]>),
305    /// Three unsigned ints (u32). `vec3<u32>` in shaders.
306    Uint32x3(Vec<[u32; 3]>),
307    /// Four unsigned ints (u32). `vec4<u32>` in shaders.
308    Uint32x4(Vec<[u32; 4]>),
309    /// One signed int (i32). `i32` in shaders.
310    Sint32(Vec<i32>),
311    /// Two signed ints (i32). `vec2<i32>` in shaders.
312    Sint32x2(Vec<[i32; 2]>),
313    /// Three signed ints (i32). `vec3<i32>` in shaders.
314    Sint32x3(Vec<[i32; 3]>),
315    /// Four signed ints (i32). `vec4<i32>` in shaders.
316    Sint32x4(Vec<[i32; 4]>),
317    /// One double-precision float (f64). `f32` in shaders. Requires [`wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT`].
318    Float64(Vec<f64>),
319    /// Two double-precision floats (f64). `vec2<f32>` in shaders. Requires [`wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT`].
320    Float64x2(Vec<[f64; 2]>),
321    /// Three double-precision floats (f64). `vec3<f32>` in shaders. Requires [`wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT`].
322    Float64x3(Vec<[f64; 3]>),
323    /// Four double-precision floats (f64). `vec4<f32>` in shaders. Requires [`wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT`].
324    Float64x4(Vec<[f64; 4]>),
325    /// Three unsigned 10-bit integers and one 2-bit integer, packed into a 32-bit integer (u32). [0, 1023] and [0, 3] converted to float [0, 1] `vec4<f32>` in shaders.
326    Unorm10_10_10_2(Vec<u32>),
327    /// Four unsigned 8-bit integers (u8) in BGRA. [0, 255] converted to float [0, 1] `vec4<f32>` RGBA in shaders.
328    Unorm8x4Bgra(Vec<[u8; 4]>),
329}
330
331impl VertexAttributeValues {
332    /// Creates a new [`VertexAttributeValues`] with the storage for given [`VertexFormat`].
333    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    /// Returns the number of vertices in this [`VertexAttributeValues`]. For a single
384    /// mesh, all of the [`VertexAttributeValues`] must have the same length.
385    #[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    /// Returns `true` if there are no vertices in this [`VertexAttributeValues`].
440    pub fn is_empty(&self) -> bool {
441        self.len() == 0
442    }
443
444    /// Returns the values as float triples if possible.
445    pub fn as_float3(&self) -> Option<&[[f32; 3]]> {
446        match self {
447            VertexAttributeValues::Float32x3(values) => Some(values),
448            _ => None,
449        }
450    }
451
452    // TODO: add vertex format as parameter here and perform type conversions
453    /// Flattens the [`VertexAttributeValues`] into a sequence of bytes. This is
454    /// useful for serialization and sending to the GPU.
455    #[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/// Describes how the vertex buffer is interpreted.
894#[derive(Default, Clone, Debug, Hash, Eq, PartialEq)]
895pub struct VertexBufferLayout {
896    /// The stride, in bytes, between elements of this buffer.
897    pub array_stride: BufferAddress,
898    /// How often this vertex buffer is "stepped" forward.
899    pub step_mode: VertexStepMode,
900    /// The list of attributes which comprise a single vertex.
901    pub attributes: Vec<VertexAttribute>,
902}
903
904impl VertexBufferLayout {
905    /// Creates a new densely packed [`VertexBufferLayout`] from an iterator of vertex formats.
906    /// Iteration order determines the `shader_location` and `offset` of the [`VertexAttributes`](VertexAttribute).
907    /// The first iterated item will have a `shader_location` and `offset` of zero.
908    /// The `array_stride` is the sum of the size of the iterated [`VertexFormats`](VertexFormat) (in bytes).
909    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    /// Returns a [`VertexBufferLayout`] with the shader location of every attribute offset by
932    /// `location`.
933    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/// Describes the layout of the mesh vertices in GPU memory.
942///
943/// At most one copy of a mesh vertex buffer layout ever exists in GPU memory at
944/// once. Therefore, comparing these for equality requires only a single pointer
945/// comparison, and this type's [`PartialEq`] and [`Hash`] implementations take
946/// advantage of this. To that end, this type doesn't implement
947/// [`bevy_derive::Deref`] or [`bevy_derive::DerefMut`] in order to reduce the
948/// possibility of accidental deep comparisons, which would be needlessly
949/// expensive.
950#[derive(Clone, Debug)]
951pub struct MeshVertexBufferLayoutRef(pub Arc<MeshVertexBufferLayout>);
952
953/// Stores the single copy of each mesh vertex buffer layout.
954#[derive(Clone, Default, Resource)]
955pub struct MeshVertexBufferLayouts(HashSet<Arc<MeshVertexBufferLayout>>);
956
957impl MeshVertexBufferLayouts {
958    /// Inserts a new mesh vertex buffer layout in the store and returns a
959    /// reference to it, reusing the existing reference if this mesh vertex
960    /// buffer layout was already in the store.
961    pub fn insert(&mut self, layout: MeshVertexBufferLayout) -> MeshVertexBufferLayoutRef {
962        // Because the special `PartialEq` and `Hash` implementations that
963        // compare by pointer are on `MeshVertexBufferLayoutRef`, not on
964        // `Arc<MeshVertexBufferLayout>`, this compares the mesh vertex buffer
965        // structurally, not by pointer.
966        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        // Hash the address of the underlying data, so two layouts that share the same
985        // `MeshVertexBufferLayout` will have the same hash.
986        (Arc::as_ptr(&self.0) as usize).hash(state);
987    }
988}