Skip to main content

bevy_mesh/
vertex.rs

1use alloc::sync::Arc;
2use bevy_derive::EnumVariantMeta;
3use bevy_ecs::resource::Resource;
4use bevy_math::{vec2, Vec2, Vec3, Vec3A, Vec3Swizzles};
5#[cfg(feature = "serialize")]
6use bevy_platform::collections::HashMap;
7use bevy_platform::collections::HashSet;
8use bevy_shape::{Aabb2d, Aabb3d, BoundingVolume};
9use bytemuck::{bytes_of, cast_slice};
10use core::hash::{Hash, Hasher};
11#[cfg(feature = "serialize")]
12use serde::{Deserialize, Serialize};
13use thiserror::Error;
14use wgpu_types::{BufferAddress, VertexAttribute, VertexFormat, VertexStepMode};
15
16use crate::MeshAttributeCompressionFlags;
17
18#[derive(#[automatically_derived]
impl ::core::fmt::Debug for MeshVertexAttribute {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "MeshVertexAttribute", "name", &self.name, "id", &self.id,
            "format", &&self.format)
    }
}Debug, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for MeshVertexAttribute { }
#[automatically_derived]
impl ::core::clone::Clone for MeshVertexAttribute {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<&'static str>;
        let _: ::core::clone::AssertParamIsClone<MeshVertexAttributeId>;
        let _: ::core::clone::AssertParamIsClone<VertexFormat>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for MeshVertexAttribute { }Copy, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for MeshVertexAttribute { }
#[automatically_derived]
impl ::core::cmp::PartialEq for MeshVertexAttribute {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        self.name == other.name && self.id == other.id &&
            self.format == other.format
    }
}PartialEq)]
19pub struct MeshVertexAttribute {
20    /// The friendly name of the vertex attribute
21    pub name: &'static str,
22
23    /// The _unique_ id of the vertex attribute. This will also determine sort ordering
24    /// when generating vertex buffers. Built-in / standard attributes will use "close to zero"
25    /// indices. When in doubt, use a random / very large u64 to avoid conflicts.
26    pub id: MeshVertexAttributeId,
27
28    /// The format of the vertex attribute.
29    pub format: VertexFormat,
30}
31
32#[cfg(feature = "serialize")]
33#[derive(#[automatically_derived]
impl ::core::fmt::Debug for SerializedMeshVertexAttribute {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "SerializedMeshVertexAttribute", "name", &self.name, "id",
            &self.id, "format", &&self.format)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for SerializedMeshVertexAttribute {
    #[inline]
    fn clone(&self) -> Self {
        Self {
            name: ::core::clone::Clone::clone(&self.name),
            id: ::core::clone::Clone::clone(&self.id),
            format: ::core::clone::Clone::clone(&self.format),
        }
    }
}Clone, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for SerializedMeshVertexAttribute {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private229::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "SerializedMeshVertexAttribute",
                            false as usize + 1 + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "name", &self.name)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "id", &self.id)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "format", &self.format)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for SerializedMeshVertexAttribute {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private229::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field { __field0, __field1, __field2, __ignore, }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private229::Formatter)
                        -> _serde::__private229::fmt::Result {
                        _serde::__private229::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private229::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private229::Ok(__Field::__field0),
                            1u64 => _serde::__private229::Ok(__Field::__field1),
                            2u64 => _serde::__private229::Ok(__Field::__field2),
                            _ => _serde::__private229::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private229::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "name" => _serde::__private229::Ok(__Field::__field0),
                            "id" => _serde::__private229::Ok(__Field::__field1),
                            "format" => _serde::__private229::Ok(__Field::__field2),
                            _ => { _serde::__private229::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private229::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"name" => _serde::__private229::Ok(__Field::__field0),
                            b"id" => _serde::__private229::Ok(__Field::__field1),
                            b"format" => _serde::__private229::Ok(__Field::__field2),
                            _ => { _serde::__private229::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private229::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private229::PhantomData<SerializedMeshVertexAttribute>,
                    lifetime: _serde::__private229::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = SerializedMeshVertexAttribute;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private229::Formatter)
                        -> _serde::__private229::fmt::Result {
                        _serde::__private229::Formatter::write_str(__formatter,
                            "struct SerializedMeshVertexAttribute")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private229::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<String>(&mut __seq)?
                                {
                                _serde::__private229::Some(__value) => __value,
                                _serde::__private229::None =>
                                    return _serde::__private229::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct SerializedMeshVertexAttribute with 3 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<MeshVertexAttributeId>(&mut __seq)?
                                {
                                _serde::__private229::Some(__value) => __value,
                                _serde::__private229::None =>
                                    return _serde::__private229::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct SerializedMeshVertexAttribute with 3 elements")),
                            };
                        let __field2 =
                            match _serde::de::SeqAccess::next_element::<VertexFormat>(&mut __seq)?
                                {
                                _serde::__private229::Some(__value) => __value,
                                _serde::__private229::None =>
                                    return _serde::__private229::Err(_serde::de::Error::invalid_length(2usize,
                                                &"struct SerializedMeshVertexAttribute with 3 elements")),
                            };
                        _serde::__private229::Ok(SerializedMeshVertexAttribute {
                                name: __field0,
                                id: __field1,
                                format: __field2,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private229::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0: _serde::__private229::Option<String> =
                            _serde::__private229::None;
                        let mut __field1:
                                _serde::__private229::Option<MeshVertexAttributeId> =
                            _serde::__private229::None;
                        let mut __field2:
                                _serde::__private229::Option<VertexFormat> =
                            _serde::__private229::None;
                        while let _serde::__private229::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private229::Option::is_some(&__field0) {
                                        return _serde::__private229::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("name"));
                                    }
                                    __field0 =
                                        _serde::__private229::Some(_serde::de::MapAccess::next_value::<String>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private229::Option::is_some(&__field1) {
                                        return _serde::__private229::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("id"));
                                    }
                                    __field1 =
                                        _serde::__private229::Some(_serde::de::MapAccess::next_value::<MeshVertexAttributeId>(&mut __map)?);
                                }
                                __Field::__field2 => {
                                    if _serde::__private229::Option::is_some(&__field2) {
                                        return _serde::__private229::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("format"));
                                    }
                                    __field2 =
                                        _serde::__private229::Some(_serde::de::MapAccess::next_value::<VertexFormat>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private229::Some(__field0) => __field0,
                                _serde::__private229::None =>
                                    _serde::__private229::de::missing_field("name")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private229::Some(__field1) => __field1,
                                _serde::__private229::None =>
                                    _serde::__private229::de::missing_field("id")?,
                            };
                        let __field2 =
                            match __field2 {
                                _serde::__private229::Some(__field2) => __field2,
                                _serde::__private229::None =>
                                    _serde::__private229::de::missing_field("format")?,
                            };
                        _serde::__private229::Ok(SerializedMeshVertexAttribute {
                                name: __field0,
                                id: __field1,
                                format: __field2,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] =
                    &["name", "id", "format"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "SerializedMeshVertexAttribute", FIELDS,
                    __Visitor {
                        marker: _serde::__private229::PhantomData::<SerializedMeshVertexAttribute>,
                        lifetime: _serde::__private229::PhantomData,
                    })
            }
        }
    };Deserialize)]
34pub(crate) struct SerializedMeshVertexAttribute {
35    pub(crate) name: String,
36    pub(crate) id: MeshVertexAttributeId,
37    pub(crate) format: VertexFormat,
38}
39
40#[cfg(feature = "serialize")]
41impl SerializedMeshVertexAttribute {
42    pub(crate) fn from_mesh_vertex_attribute(attribute: MeshVertexAttribute) -> Self {
43        Self {
44            name: attribute.name.to_string(),
45            id: attribute.id,
46            format: attribute.format,
47        }
48    }
49
50    pub(crate) fn try_into_mesh_vertex_attribute(
51        self,
52        possible_attributes: &HashMap<Box<str>, MeshVertexAttribute>,
53    ) -> Option<MeshVertexAttribute> {
54        let attr = possible_attributes.get(self.name.as_str())?;
55        if attr.id == self.id {
56            Some(*attr)
57        } else {
58            None
59        }
60    }
61}
62
63impl MeshVertexAttribute {
64    pub const fn new(name: &'static str, id: u64, format: VertexFormat) -> Self {
65        Self {
66            name,
67            id: MeshVertexAttributeId(id),
68            format,
69        }
70    }
71
72    pub const fn at_shader_location(&self, shader_location: u32) -> VertexAttributeDescriptor {
73        VertexAttributeDescriptor::new(shader_location, self.id, self.name)
74    }
75}
76
77#[derive(#[automatically_derived]
impl ::core::fmt::Debug for MeshVertexAttributeId {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f,
            "MeshVertexAttributeId", &&self.0)
    }
}Debug, #[automatically_derived]
impl ::core::marker::Copy for MeshVertexAttributeId { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for MeshVertexAttributeId { }
#[automatically_derived]
impl ::core::clone::Clone for MeshVertexAttributeId {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<u64>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for MeshVertexAttributeId { }
#[automatically_derived]
impl ::core::cmp::PartialEq for MeshVertexAttributeId {
    #[inline]
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for MeshVertexAttributeId {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u64>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::Ord for MeshVertexAttributeId {
    #[inline]
    fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
        ::core::cmp::Ord::cmp(&self.0, &other.0)
    }
}Ord, #[automatically_derived]
impl ::core::cmp::PartialOrd for MeshVertexAttributeId {
    #[inline]
    fn partial_cmp(&self, other: &Self)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd, #[automatically_derived]
impl ::core::hash::Hash for MeshVertexAttributeId {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}Hash)]
78#[cfg_attr(feature = "serialize", derive(#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for MeshVertexAttributeId {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private229::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                _serde::Serializer::serialize_newtype_struct(__serializer,
                    "MeshVertexAttributeId", &self.0)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for MeshVertexAttributeId {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private229::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private229::PhantomData<MeshVertexAttributeId>,
                    lifetime: _serde::__private229::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = MeshVertexAttributeId;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private229::Formatter)
                        -> _serde::__private229::fmt::Result {
                        _serde::__private229::Formatter::write_str(__formatter,
                            "tuple struct MeshVertexAttributeId")
                    }
                    #[inline]
                    fn visit_newtype_struct<__E>(self, __e: __E)
                        -> _serde::__private229::Result<Self::Value, __E::Error>
                        where __E: _serde::Deserializer<'de> {
                        let __field0: u64 =
                            <u64 as _serde::Deserialize>::deserialize(__e)?;
                        _serde::__private229::Ok(MeshVertexAttributeId(__field0))
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private229::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<u64>(&mut __seq)?
                                {
                                _serde::__private229::Some(__value) => __value,
                                _serde::__private229::None =>
                                    return _serde::__private229::Err(_serde::de::Error::invalid_length(0usize,
                                                &"tuple struct MeshVertexAttributeId with 1 element")),
                            };
                        _serde::__private229::Ok(MeshVertexAttributeId(__field0))
                    }
                }
                _serde::Deserializer::deserialize_newtype_struct(__deserializer,
                    "MeshVertexAttributeId",
                    __Visitor {
                        marker: _serde::__private229::PhantomData::<MeshVertexAttributeId>,
                        lifetime: _serde::__private229::PhantomData,
                    })
            }
        }
    };Deserialize))]
79pub struct MeshVertexAttributeId(u64);
80
81impl From<MeshVertexAttribute> for MeshVertexAttributeId {
82    fn from(attribute: MeshVertexAttribute) -> Self {
83        attribute.id
84    }
85}
86
87#[derive(#[automatically_derived]
impl ::core::fmt::Debug for MeshVertexBufferLayout {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "MeshVertexBufferLayout", "attribute_ids", &self.attribute_ids,
            "attribute_compression", &self.attribute_compression, "layout",
            &&self.layout)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for MeshVertexBufferLayout {
    #[inline]
    fn clone(&self) -> Self {
        Self {
            attribute_ids: ::core::clone::Clone::clone(&self.attribute_ids),
            attribute_compression: ::core::clone::Clone::clone(&self.attribute_compression),
            layout: ::core::clone::Clone::clone(&self.layout),
        }
    }
}Clone, #[automatically_derived]
impl ::core::hash::Hash for MeshVertexBufferLayout {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.attribute_ids, state);
        ::core::hash::Hash::hash(&self.attribute_compression, state);
        ::core::hash::Hash::hash(&self.layout, state)
    }
}Hash, #[automatically_derived]
impl ::core::cmp::Eq for MeshVertexBufferLayout {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Vec<MeshVertexAttributeId>>;
        let _: ::core::cmp::AssertParamIsEq<MeshAttributeCompressionFlags>;
        let _: ::core::cmp::AssertParamIsEq<VertexBufferLayout>;
    }
}Eq, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for MeshVertexBufferLayout { }
#[automatically_derived]
impl ::core::cmp::PartialEq for MeshVertexBufferLayout {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        self.attribute_ids == other.attribute_ids &&
                self.attribute_compression == other.attribute_compression &&
            self.layout == other.layout
    }
}PartialEq)]
88pub struct MeshVertexBufferLayout {
89    pub(crate) attribute_ids: Vec<MeshVertexAttributeId>,
90    pub(crate) attribute_compression: MeshAttributeCompressionFlags,
91    pub(crate) layout: VertexBufferLayout,
92}
93
94impl MeshVertexBufferLayout {
95    pub fn new(
96        attribute_ids: Vec<MeshVertexAttributeId>,
97        layout: VertexBufferLayout,
98        attribute_compression: MeshAttributeCompressionFlags,
99    ) -> Self {
100        Self {
101            attribute_ids,
102            attribute_compression,
103            layout,
104        }
105    }
106
107    #[inline]
108    pub fn contains(&self, attribute_id: impl Into<MeshVertexAttributeId>) -> bool {
109        self.attribute_ids.contains(&attribute_id.into())
110    }
111
112    #[inline]
113    pub fn attribute_ids(&self) -> &[MeshVertexAttributeId] {
114        &self.attribute_ids
115    }
116
117    #[inline]
118    pub fn layout(&self) -> &VertexBufferLayout {
119        &self.layout
120    }
121
122    pub fn get_attribute_compression(&self) -> MeshAttributeCompressionFlags {
123        self.attribute_compression
124    }
125
126    pub fn get_layout(
127        &self,
128        attribute_descriptors: &[VertexAttributeDescriptor],
129    ) -> Result<VertexBufferLayout, MissingVertexAttributeError> {
130        let mut attributes = Vec::with_capacity(attribute_descriptors.len());
131        for attribute_descriptor in attribute_descriptors {
132            if let Some(index) = self
133                .attribute_ids
134                .iter()
135                .position(|id| *id == attribute_descriptor.id)
136            {
137                let layout_attribute = &self.layout.attributes[index];
138                attributes.push(VertexAttribute {
139                    format: layout_attribute.format,
140                    offset: layout_attribute.offset,
141                    shader_location: attribute_descriptor.shader_location,
142                });
143            } else {
144                return Err(MissingVertexAttributeError {
145                    id: attribute_descriptor.id,
146                    name: attribute_descriptor.name,
147                    pipeline_type: None,
148                });
149            }
150        }
151
152        Ok(VertexBufferLayout {
153            array_stride: self.layout.array_stride,
154            step_mode: self.layout.step_mode,
155            attributes,
156        })
157    }
158}
159
160#[derive(#[allow(unused_qualifications)]
#[automatically_derived]
impl ::thiserror::__private21::Error for MissingVertexAttributeError { }
#[allow(unused_qualifications)]
#[automatically_derived]
impl ::core::fmt::Display for MissingVertexAttributeError {
    #[allow(clippy :: used_underscore_binding)]
    fn fmt(&self, __formatter: &mut ::core::fmt::Formatter)
        -> ::core::fmt::Result {
        use ::thiserror::__private21::AsDisplay as _;
        #[allow(unused_variables, deprecated)]
        let Self { pipeline_type, id, name } = self;
        match (name.as_display(), id, pipeline_type) {
            (__display_name, __field_id, __field_pipeline_type) =>
                __formatter.write_fmt(format_args!("Mesh is missing requested attribute: {0} ({1:?}, pipeline type: {2:?})",
                        __display_name, __field_id, __field_pipeline_type)),
        }
    }
}Error, #[automatically_derived]
impl ::core::fmt::Debug for MissingVertexAttributeError {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "MissingVertexAttributeError", "pipeline_type",
            &self.pipeline_type, "id", &self.id, "name", &&self.name)
    }
}Debug)]
161#[error("Mesh is missing requested attribute: {name} ({id:?}, pipeline type: {pipeline_type:?})")]
162pub struct MissingVertexAttributeError {
163    pub pipeline_type: Option<&'static str>,
164    id: MeshVertexAttributeId,
165    name: &'static str,
166}
167
168pub struct VertexAttributeDescriptor {
169    pub shader_location: u32,
170    pub id: MeshVertexAttributeId,
171    name: &'static str,
172}
173
174impl VertexAttributeDescriptor {
175    pub const fn new(shader_location: u32, id: MeshVertexAttributeId, name: &'static str) -> Self {
176        Self {
177            shader_location,
178            id,
179            name,
180        }
181    }
182}
183
184#[derive(#[automatically_derived]
impl ::core::fmt::Debug for MeshAttributeData {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "MeshAttributeData", "attribute", &self.attribute, "values",
            &&self.values)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for MeshAttributeData {
    #[inline]
    fn clone(&self) -> Self {
        Self {
            attribute: ::core::clone::Clone::clone(&self.attribute),
            values: ::core::clone::Clone::clone(&self.values),
        }
    }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for MeshAttributeData { }
#[automatically_derived]
impl ::core::cmp::PartialEq for MeshAttributeData {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        self.attribute == other.attribute && self.values == other.values
    }
}PartialEq)]
185pub(crate) struct MeshAttributeData {
186    pub(crate) attribute: MeshVertexAttribute,
187    pub(crate) values: VertexAttributeValues,
188}
189
190#[cfg(feature = "serialize")]
191#[derive(#[automatically_derived]
impl ::core::fmt::Debug for SerializedMeshAttributeData {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "SerializedMeshAttributeData", "attribute", &self.attribute,
            "values", &&self.values)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for SerializedMeshAttributeData {
    #[inline]
    fn clone(&self) -> Self {
        Self {
            attribute: ::core::clone::Clone::clone(&self.attribute),
            values: ::core::clone::Clone::clone(&self.values),
        }
    }
}Clone, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for SerializedMeshAttributeData {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private229::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "SerializedMeshAttributeData", false as usize + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "attribute", &self.attribute)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "values", &self.values)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for SerializedMeshAttributeData {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private229::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field { __field0, __field1, __ignore, }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private229::Formatter)
                        -> _serde::__private229::fmt::Result {
                        _serde::__private229::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private229::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private229::Ok(__Field::__field0),
                            1u64 => _serde::__private229::Ok(__Field::__field1),
                            _ => _serde::__private229::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private229::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "attribute" => _serde::__private229::Ok(__Field::__field0),
                            "values" => _serde::__private229::Ok(__Field::__field1),
                            _ => { _serde::__private229::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private229::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"attribute" => _serde::__private229::Ok(__Field::__field0),
                            b"values" => _serde::__private229::Ok(__Field::__field1),
                            _ => { _serde::__private229::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private229::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private229::PhantomData<SerializedMeshAttributeData>,
                    lifetime: _serde::__private229::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = SerializedMeshAttributeData;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private229::Formatter)
                        -> _serde::__private229::fmt::Result {
                        _serde::__private229::Formatter::write_str(__formatter,
                            "struct SerializedMeshAttributeData")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private229::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<SerializedMeshVertexAttribute>(&mut __seq)?
                                {
                                _serde::__private229::Some(__value) => __value,
                                _serde::__private229::None =>
                                    return _serde::__private229::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct SerializedMeshAttributeData with 2 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<VertexAttributeValues>(&mut __seq)?
                                {
                                _serde::__private229::Some(__value) => __value,
                                _serde::__private229::None =>
                                    return _serde::__private229::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct SerializedMeshAttributeData with 2 elements")),
                            };
                        _serde::__private229::Ok(SerializedMeshAttributeData {
                                attribute: __field0,
                                values: __field1,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private229::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0:
                                _serde::__private229::Option<SerializedMeshVertexAttribute> =
                            _serde::__private229::None;
                        let mut __field1:
                                _serde::__private229::Option<VertexAttributeValues> =
                            _serde::__private229::None;
                        while let _serde::__private229::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private229::Option::is_some(&__field0) {
                                        return _serde::__private229::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("attribute"));
                                    }
                                    __field0 =
                                        _serde::__private229::Some(_serde::de::MapAccess::next_value::<SerializedMeshVertexAttribute>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private229::Option::is_some(&__field1) {
                                        return _serde::__private229::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("values"));
                                    }
                                    __field1 =
                                        _serde::__private229::Some(_serde::de::MapAccess::next_value::<VertexAttributeValues>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private229::Some(__field0) => __field0,
                                _serde::__private229::None =>
                                    _serde::__private229::de::missing_field("attribute")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private229::Some(__field1) => __field1,
                                _serde::__private229::None =>
                                    _serde::__private229::de::missing_field("values")?,
                            };
                        _serde::__private229::Ok(SerializedMeshAttributeData {
                                attribute: __field0,
                                values: __field1,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] =
                    &["attribute", "values"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "SerializedMeshAttributeData", FIELDS,
                    __Visitor {
                        marker: _serde::__private229::PhantomData::<SerializedMeshAttributeData>,
                        lifetime: _serde::__private229::PhantomData,
                    })
            }
        }
    };Deserialize)]
192pub(crate) struct SerializedMeshAttributeData {
193    pub(crate) attribute: SerializedMeshVertexAttribute,
194    pub(crate) values: VertexAttributeValues,
195}
196
197#[cfg(feature = "serialize")]
198impl SerializedMeshAttributeData {
199    pub(crate) fn from_mesh_attribute_data(data: MeshAttributeData) -> Self {
200        Self {
201            attribute: SerializedMeshVertexAttribute::from_mesh_vertex_attribute(data.attribute),
202            values: data.values,
203        }
204    }
205
206    pub(crate) fn try_into_mesh_attribute_data(
207        self,
208        possible_attributes: &HashMap<Box<str>, MeshVertexAttribute>,
209    ) -> Option<MeshAttributeData> {
210        let attribute = self
211            .attribute
212            .try_into_mesh_vertex_attribute(possible_attributes)?;
213        Some(MeshAttributeData {
214            attribute,
215            values: self.values,
216        })
217    }
218}
219
220/// Compute a vector whose direction is the normal of the triangle formed by
221/// points a, b, c, and whose magnitude is double the area of the triangle. This
222/// is useful for computing smooth normals where the contributing normals are
223/// proportionate to the areas of the triangles as [discussed
224/// here](https://iquilezles.org/articles/normals/).
225///
226/// Question: Why double the area? Because the area of a triangle _A_ is
227/// determined by this equation:
228///
229/// _A = |(b - a) x (c - a)| / 2_
230///
231/// By computing _2 A_ we avoid a division operation, and when calculating the
232/// the sum of these vectors which are then normalized, a constant multiple has
233/// no effect.
234#[inline]
235pub fn triangle_area_normal(a: [f32; 3], b: [f32; 3], c: [f32; 3]) -> [f32; 3] {
236    let (a, b, c) = (Vec3::from(a), Vec3::from(b), Vec3::from(c));
237    (b - a).cross(c - a).into()
238}
239
240/// Compute the normal of a face made of three points: a, b, and c.
241#[inline]
242pub fn triangle_normal(a: [f32; 3], b: [f32; 3], c: [f32; 3]) -> [f32; 3] {
243    let (a, b, c) = (Vec3::from(a), Vec3::from(b), Vec3::from(c));
244    (b - a).cross(c - a).normalize_or_zero().into()
245}
246
247/// Vertex format that can be quantized from Float32.
248#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for AttributeQuantization { }
#[automatically_derived]
impl ::core::clone::Clone for AttributeQuantization {
    #[inline]
    fn clone(&self) -> Self { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for AttributeQuantization { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for AttributeQuantization {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                AttributeQuantization::Unorm8 => "Unorm8",
                AttributeQuantization::Snorm8 => "Snorm8",
                AttributeQuantization::Unorm16 => "Unorm16",
                AttributeQuantization::Snorm16 => "Snorm16",
                AttributeQuantization::Float16 => "Float16",
            })
    }
}Debug, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for AttributeQuantization { }
#[automatically_derived]
impl ::core::cmp::PartialEq for AttributeQuantization {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
            ::core::intrinsics::discriminant_value(other)
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for AttributeQuantization { }Eq)]
249#[cfg_attr(feature = "serialize", derive(#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for AttributeQuantization {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private229::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                match *self {
                    AttributeQuantization::Unorm8 =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "AttributeQuantization", 0u32, "Unorm8"),
                    AttributeQuantization::Snorm8 =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "AttributeQuantization", 1u32, "Snorm8"),
                    AttributeQuantization::Unorm16 =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "AttributeQuantization", 2u32, "Unorm16"),
                    AttributeQuantization::Snorm16 =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "AttributeQuantization", 3u32, "Snorm16"),
                    AttributeQuantization::Float16 =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "AttributeQuantization", 4u32, "Float16"),
                }
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for AttributeQuantization {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private229::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field {
                    __field0,
                    __field1,
                    __field2,
                    __field3,
                    __field4,
                }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private229::Formatter)
                        -> _serde::__private229::fmt::Result {
                        _serde::__private229::Formatter::write_str(__formatter,
                            "variant identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private229::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private229::Ok(__Field::__field0),
                            1u64 => _serde::__private229::Ok(__Field::__field1),
                            2u64 => _serde::__private229::Ok(__Field::__field2),
                            3u64 => _serde::__private229::Ok(__Field::__field3),
                            4u64 => _serde::__private229::Ok(__Field::__field4),
                            _ =>
                                _serde::__private229::Err(_serde::de::Error::invalid_value(_serde::de::Unexpected::Unsigned(__value),
                                        &"variant index 0 <= i < 5")),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private229::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "Unorm8" => _serde::__private229::Ok(__Field::__field0),
                            "Snorm8" => _serde::__private229::Ok(__Field::__field1),
                            "Unorm16" => _serde::__private229::Ok(__Field::__field2),
                            "Snorm16" => _serde::__private229::Ok(__Field::__field3),
                            "Float16" => _serde::__private229::Ok(__Field::__field4),
                            _ => {
                                _serde::__private229::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private229::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"Unorm8" => _serde::__private229::Ok(__Field::__field0),
                            b"Snorm8" => _serde::__private229::Ok(__Field::__field1),
                            b"Unorm16" => _serde::__private229::Ok(__Field::__field2),
                            b"Snorm16" => _serde::__private229::Ok(__Field::__field3),
                            b"Float16" => _serde::__private229::Ok(__Field::__field4),
                            _ => {
                                let __value =
                                    &_serde::__private229::from_utf8_lossy(__value);
                                _serde::__private229::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private229::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private229::PhantomData<AttributeQuantization>,
                    lifetime: _serde::__private229::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = AttributeQuantization;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private229::Formatter)
                        -> _serde::__private229::fmt::Result {
                        _serde::__private229::Formatter::write_str(__formatter,
                            "enum AttributeQuantization")
                    }
                    fn visit_enum<__A>(self, __data: __A)
                        -> _serde::__private229::Result<Self::Value, __A::Error>
                        where __A: _serde::de::EnumAccess<'de> {
                        match _serde::de::EnumAccess::variant(__data) {
                            _serde::__private229::Ok((__Field::__field0, __variant)) =>
                                {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private229::Ok(AttributeQuantization::Unorm8)
                            }
                            _serde::__private229::Ok((__Field::__field1, __variant)) =>
                                {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private229::Ok(AttributeQuantization::Snorm8)
                            }
                            _serde::__private229::Ok((__Field::__field2, __variant)) =>
                                {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private229::Ok(AttributeQuantization::Unorm16)
                            }
                            _serde::__private229::Ok((__Field::__field3, __variant)) =>
                                {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private229::Ok(AttributeQuantization::Snorm16)
                            }
                            _serde::__private229::Ok((__Field::__field4, __variant)) =>
                                {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private229::Ok(AttributeQuantization::Float16)
                            }
                            _serde::__private229::Err(__err) =>
                                _serde::__private229::Err(__err),
                        }
                    }
                }
                #[doc(hidden)]
                const VARIANTS: &'static [&'static str] =
                    &["Unorm8", "Snorm8", "Unorm16", "Snorm16", "Float16"];
                _serde::Deserializer::deserialize_enum(__deserializer,
                    "AttributeQuantization", VARIANTS,
                    __Visitor {
                        marker: _serde::__private229::PhantomData::<AttributeQuantization>,
                        lifetime: _serde::__private229::PhantomData,
                    })
            }
        }
    };Deserialize))]
250pub enum AttributeQuantization {
251    Unorm8,
252    Snorm8,
253    Unorm16,
254    Snorm16,
255    Float16,
256}
257
258impl AttributeQuantization {
259    /// Create a [`VertexAttributeValues`] with `values` quantized to the format of this quantization.
260    pub(crate) fn quantize_f32_values<const N: usize>(
261        &self,
262        values: &[[f32; N]],
263    ) -> VertexAttributeValues {
264        const {
265            if !(N == 1 || N == 2 || N == 4) {
    ::core::panicking::panic("assertion failed: N == 1 || N == 2 || N == 4")
};assert!(N == 1 || N == 2 || N == 4);
266        }
267        match self {
268            AttributeQuantization::Unorm8 => {
269                let values = values.iter().map(|v| arr_f32_to_unorm8(*v)).collect();
270                match N {
271                    1 => VertexAttributeValues::Unorm8(bytemuck::cast_vec(values)),
272                    2 => VertexAttributeValues::Unorm8x2(bytemuck::cast_vec(values)),
273                    4 => VertexAttributeValues::Unorm8x4(bytemuck::cast_vec(values)),
274                    _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
275                }
276            }
277            AttributeQuantization::Snorm8 => {
278                let values = values.iter().map(|v| arr_f32_to_snorm8(*v)).collect();
279                match N {
280                    1 => VertexAttributeValues::Snorm8(bytemuck::cast_vec(values)),
281                    2 => VertexAttributeValues::Snorm8x2(bytemuck::cast_vec(values)),
282                    4 => VertexAttributeValues::Snorm8x4(bytemuck::cast_vec(values)),
283                    _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
284                }
285            }
286            AttributeQuantization::Unorm16 => {
287                let values = values.iter().map(|v| arr_f32_to_unorm16(*v)).collect();
288                match N {
289                    1 => VertexAttributeValues::Unorm16(bytemuck::cast_vec(values)),
290                    2 => VertexAttributeValues::Unorm16x2(bytemuck::cast_vec(values)),
291                    4 => VertexAttributeValues::Unorm16x4(bytemuck::cast_vec(values)),
292                    _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
293                }
294            }
295            AttributeQuantization::Snorm16 => {
296                let values = values.iter().map(|v| arr_f32_to_snorm16(*v)).collect();
297                match N {
298                    1 => VertexAttributeValues::Snorm16(bytemuck::cast_vec(values)),
299                    2 => VertexAttributeValues::Snorm16x2(bytemuck::cast_vec(values)),
300                    4 => VertexAttributeValues::Snorm16x4(bytemuck::cast_vec(values)),
301                    _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
302                }
303            }
304            AttributeQuantization::Float16 => {
305                let values = values.iter().map(|v| arr_f32_to_float16(*v)).collect();
306                match N {
307                    1 => VertexAttributeValues::Float16(bytemuck::cast_vec(values)),
308                    2 => VertexAttributeValues::Float16x2(bytemuck::cast_vec(values)),
309                    4 => VertexAttributeValues::Float16x4(bytemuck::cast_vec(values)),
310                    _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
311                }
312            }
313        }
314    }
315}
316
317/// Contains an array where each entry describes a property of a single vertex.
318/// Matches the [`VertexFormats`](VertexFormat).
319#[derive(#[automatically_derived]
impl ::core::clone::Clone for VertexAttributeValues {
    #[inline]
    fn clone(&self) -> Self {
        match self {
            Self::Uint8(__self_0) =>
                Self::Uint8(::core::clone::Clone::clone(__self_0)),
            Self::Uint8x2(__self_0) =>
                Self::Uint8x2(::core::clone::Clone::clone(__self_0)),
            Self::Uint8x4(__self_0) =>
                Self::Uint8x4(::core::clone::Clone::clone(__self_0)),
            Self::Sint8(__self_0) =>
                Self::Sint8(::core::clone::Clone::clone(__self_0)),
            Self::Sint8x2(__self_0) =>
                Self::Sint8x2(::core::clone::Clone::clone(__self_0)),
            Self::Sint8x4(__self_0) =>
                Self::Sint8x4(::core::clone::Clone::clone(__self_0)),
            Self::Unorm8(__self_0) =>
                Self::Unorm8(::core::clone::Clone::clone(__self_0)),
            Self::Unorm8x2(__self_0) =>
                Self::Unorm8x2(::core::clone::Clone::clone(__self_0)),
            Self::Unorm8x4(__self_0) =>
                Self::Unorm8x4(::core::clone::Clone::clone(__self_0)),
            Self::Snorm8(__self_0) =>
                Self::Snorm8(::core::clone::Clone::clone(__self_0)),
            Self::Snorm8x2(__self_0) =>
                Self::Snorm8x2(::core::clone::Clone::clone(__self_0)),
            Self::Snorm8x4(__self_0) =>
                Self::Snorm8x4(::core::clone::Clone::clone(__self_0)),
            Self::Uint16(__self_0) =>
                Self::Uint16(::core::clone::Clone::clone(__self_0)),
            Self::Uint16x2(__self_0) =>
                Self::Uint16x2(::core::clone::Clone::clone(__self_0)),
            Self::Uint16x4(__self_0) =>
                Self::Uint16x4(::core::clone::Clone::clone(__self_0)),
            Self::Sint16(__self_0) =>
                Self::Sint16(::core::clone::Clone::clone(__self_0)),
            Self::Sint16x2(__self_0) =>
                Self::Sint16x2(::core::clone::Clone::clone(__self_0)),
            Self::Sint16x4(__self_0) =>
                Self::Sint16x4(::core::clone::Clone::clone(__self_0)),
            Self::Unorm16(__self_0) =>
                Self::Unorm16(::core::clone::Clone::clone(__self_0)),
            Self::Unorm16x2(__self_0) =>
                Self::Unorm16x2(::core::clone::Clone::clone(__self_0)),
            Self::Unorm16x4(__self_0) =>
                Self::Unorm16x4(::core::clone::Clone::clone(__self_0)),
            Self::Snorm16(__self_0) =>
                Self::Snorm16(::core::clone::Clone::clone(__self_0)),
            Self::Snorm16x2(__self_0) =>
                Self::Snorm16x2(::core::clone::Clone::clone(__self_0)),
            Self::Snorm16x4(__self_0) =>
                Self::Snorm16x4(::core::clone::Clone::clone(__self_0)),
            Self::Float16(__self_0) =>
                Self::Float16(::core::clone::Clone::clone(__self_0)),
            Self::Float16x2(__self_0) =>
                Self::Float16x2(::core::clone::Clone::clone(__self_0)),
            Self::Float16x4(__self_0) =>
                Self::Float16x4(::core::clone::Clone::clone(__self_0)),
            Self::Float32(__self_0) =>
                Self::Float32(::core::clone::Clone::clone(__self_0)),
            Self::Float32x2(__self_0) =>
                Self::Float32x2(::core::clone::Clone::clone(__self_0)),
            Self::Float32x3(__self_0) =>
                Self::Float32x3(::core::clone::Clone::clone(__self_0)),
            Self::Float32x4(__self_0) =>
                Self::Float32x4(::core::clone::Clone::clone(__self_0)),
            Self::Uint32(__self_0) =>
                Self::Uint32(::core::clone::Clone::clone(__self_0)),
            Self::Uint32x2(__self_0) =>
                Self::Uint32x2(::core::clone::Clone::clone(__self_0)),
            Self::Uint32x3(__self_0) =>
                Self::Uint32x3(::core::clone::Clone::clone(__self_0)),
            Self::Uint32x4(__self_0) =>
                Self::Uint32x4(::core::clone::Clone::clone(__self_0)),
            Self::Sint32(__self_0) =>
                Self::Sint32(::core::clone::Clone::clone(__self_0)),
            Self::Sint32x2(__self_0) =>
                Self::Sint32x2(::core::clone::Clone::clone(__self_0)),
            Self::Sint32x3(__self_0) =>
                Self::Sint32x3(::core::clone::Clone::clone(__self_0)),
            Self::Sint32x4(__self_0) =>
                Self::Sint32x4(::core::clone::Clone::clone(__self_0)),
            Self::Float64(__self_0) =>
                Self::Float64(::core::clone::Clone::clone(__self_0)),
            Self::Float64x2(__self_0) =>
                Self::Float64x2(::core::clone::Clone::clone(__self_0)),
            Self::Float64x3(__self_0) =>
                Self::Float64x3(::core::clone::Clone::clone(__self_0)),
            Self::Float64x4(__self_0) =>
                Self::Float64x4(::core::clone::Clone::clone(__self_0)),
            Self::Unorm10_10_10_2(__self_0) =>
                Self::Unorm10_10_10_2(::core::clone::Clone::clone(__self_0)),
            Self::Unorm8x4Bgra(__self_0) =>
                Self::Unorm8x4Bgra(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for VertexAttributeValues {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::Uint8(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Uint8",
                    &__self_0),
            Self::Uint8x2(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Uint8x2", &__self_0),
            Self::Uint8x4(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Uint8x4", &__self_0),
            Self::Sint8(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Sint8",
                    &__self_0),
            Self::Sint8x2(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Sint8x2", &__self_0),
            Self::Sint8x4(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Sint8x4", &__self_0),
            Self::Unorm8(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Unorm8",
                    &__self_0),
            Self::Unorm8x2(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Unorm8x2", &__self_0),
            Self::Unorm8x4(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Unorm8x4", &__self_0),
            Self::Snorm8(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Snorm8",
                    &__self_0),
            Self::Snorm8x2(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Snorm8x2", &__self_0),
            Self::Snorm8x4(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Snorm8x4", &__self_0),
            Self::Uint16(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Uint16",
                    &__self_0),
            Self::Uint16x2(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Uint16x2", &__self_0),
            Self::Uint16x4(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Uint16x4", &__self_0),
            Self::Sint16(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Sint16",
                    &__self_0),
            Self::Sint16x2(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Sint16x2", &__self_0),
            Self::Sint16x4(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Sint16x4", &__self_0),
            Self::Unorm16(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Unorm16", &__self_0),
            Self::Unorm16x2(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Unorm16x2", &__self_0),
            Self::Unorm16x4(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Unorm16x4", &__self_0),
            Self::Snorm16(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Snorm16", &__self_0),
            Self::Snorm16x2(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Snorm16x2", &__self_0),
            Self::Snorm16x4(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Snorm16x4", &__self_0),
            Self::Float16(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Float16", &__self_0),
            Self::Float16x2(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Float16x2", &__self_0),
            Self::Float16x4(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Float16x4", &__self_0),
            Self::Float32(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Float32", &__self_0),
            Self::Float32x2(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Float32x2", &__self_0),
            Self::Float32x3(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Float32x3", &__self_0),
            Self::Float32x4(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Float32x4", &__self_0),
            Self::Uint32(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Uint32",
                    &__self_0),
            Self::Uint32x2(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Uint32x2", &__self_0),
            Self::Uint32x3(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Uint32x3", &__self_0),
            Self::Uint32x4(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Uint32x4", &__self_0),
            Self::Sint32(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Sint32",
                    &__self_0),
            Self::Sint32x2(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Sint32x2", &__self_0),
            Self::Sint32x3(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Sint32x3", &__self_0),
            Self::Sint32x4(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Sint32x4", &__self_0),
            Self::Float64(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Float64", &__self_0),
            Self::Float64x2(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Float64x2", &__self_0),
            Self::Float64x3(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Float64x3", &__self_0),
            Self::Float64x4(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Float64x4", &__self_0),
            Self::Unorm10_10_10_2(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Unorm10_10_10_2", &__self_0),
            Self::Unorm8x4Bgra(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Unorm8x4Bgra", &__self_0),
        }
    }
}Debug, impl VertexAttributeValues {
    pub fn enum_variant_index(&self) -> usize {
        match self {
            VertexAttributeValues::Uint8 { .. } => 0usize,
            VertexAttributeValues::Uint8x2 { .. } => 1usize,
            VertexAttributeValues::Uint8x4 { .. } => 2usize,
            VertexAttributeValues::Sint8 { .. } => 3usize,
            VertexAttributeValues::Sint8x2 { .. } => 4usize,
            VertexAttributeValues::Sint8x4 { .. } => 5usize,
            VertexAttributeValues::Unorm8 { .. } => 6usize,
            VertexAttributeValues::Unorm8x2 { .. } => 7usize,
            VertexAttributeValues::Unorm8x4 { .. } => 8usize,
            VertexAttributeValues::Snorm8 { .. } => 9usize,
            VertexAttributeValues::Snorm8x2 { .. } => 10usize,
            VertexAttributeValues::Snorm8x4 { .. } => 11usize,
            VertexAttributeValues::Uint16 { .. } => 12usize,
            VertexAttributeValues::Uint16x2 { .. } => 13usize,
            VertexAttributeValues::Uint16x4 { .. } => 14usize,
            VertexAttributeValues::Sint16 { .. } => 15usize,
            VertexAttributeValues::Sint16x2 { .. } => 16usize,
            VertexAttributeValues::Sint16x4 { .. } => 17usize,
            VertexAttributeValues::Unorm16 { .. } => 18usize,
            VertexAttributeValues::Unorm16x2 { .. } => 19usize,
            VertexAttributeValues::Unorm16x4 { .. } => 20usize,
            VertexAttributeValues::Snorm16 { .. } => 21usize,
            VertexAttributeValues::Snorm16x2 { .. } => 22usize,
            VertexAttributeValues::Snorm16x4 { .. } => 23usize,
            VertexAttributeValues::Float16 { .. } => 24usize,
            VertexAttributeValues::Float16x2 { .. } => 25usize,
            VertexAttributeValues::Float16x4 { .. } => 26usize,
            VertexAttributeValues::Float32 { .. } => 27usize,
            VertexAttributeValues::Float32x2 { .. } => 28usize,
            VertexAttributeValues::Float32x3 { .. } => 29usize,
            VertexAttributeValues::Float32x4 { .. } => 30usize,
            VertexAttributeValues::Uint32 { .. } => 31usize,
            VertexAttributeValues::Uint32x2 { .. } => 32usize,
            VertexAttributeValues::Uint32x3 { .. } => 33usize,
            VertexAttributeValues::Uint32x4 { .. } => 34usize,
            VertexAttributeValues::Sint32 { .. } => 35usize,
            VertexAttributeValues::Sint32x2 { .. } => 36usize,
            VertexAttributeValues::Sint32x3 { .. } => 37usize,
            VertexAttributeValues::Sint32x4 { .. } => 38usize,
            VertexAttributeValues::Float64 { .. } => 39usize,
            VertexAttributeValues::Float64x2 { .. } => 40usize,
            VertexAttributeValues::Float64x3 { .. } => 41usize,
            VertexAttributeValues::Float64x4 { .. } => 42usize,
            VertexAttributeValues::Unorm10_10_10_2 { .. } => 43usize,
            VertexAttributeValues::Unorm8x4Bgra { .. } => 44usize,
        }
    }
    pub fn enum_variant_name(&self) -> &'static str {
        static variants: &[&str] =
            &["Uint8", "Uint8x2", "Uint8x4", "Sint8", "Sint8x2", "Sint8x4",
                        "Unorm8", "Unorm8x2", "Unorm8x4", "Snorm8", "Snorm8x2",
                        "Snorm8x4", "Uint16", "Uint16x2", "Uint16x4", "Sint16",
                        "Sint16x2", "Sint16x4", "Unorm16", "Unorm16x2", "Unorm16x4",
                        "Snorm16", "Snorm16x2", "Snorm16x4", "Float16", "Float16x2",
                        "Float16x4", "Float32", "Float32x2", "Float32x3",
                        "Float32x4", "Uint32", "Uint32x2", "Uint32x3", "Uint32x4",
                        "Sint32", "Sint32x2", "Sint32x3", "Sint32x4", "Float64",
                        "Float64x2", "Float64x3", "Float64x4", "Unorm10_10_10_2",
                        "Unorm8x4Bgra"];
        let index = self.enum_variant_index();
        variants[index]
    }
}EnumVariantMeta, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for VertexAttributeValues { }
#[automatically_derived]
impl ::core::cmp::PartialEq for VertexAttributeValues {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
                ::core::intrinsics::discriminant_value(other) &&
            match (self, other) {
                (Self::Uint8(__self_0), Self::Uint8(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Uint8x2(__self_0), Self::Uint8x2(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Uint8x4(__self_0), Self::Uint8x4(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Sint8(__self_0), Self::Sint8(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Sint8x2(__self_0), Self::Sint8x2(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Sint8x4(__self_0), Self::Sint8x4(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Unorm8(__self_0), Self::Unorm8(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Unorm8x2(__self_0), Self::Unorm8x2(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Unorm8x4(__self_0), Self::Unorm8x4(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Snorm8(__self_0), Self::Snorm8(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Snorm8x2(__self_0), Self::Snorm8x2(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Snorm8x4(__self_0), Self::Snorm8x4(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Uint16(__self_0), Self::Uint16(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Uint16x2(__self_0), Self::Uint16x2(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Uint16x4(__self_0), Self::Uint16x4(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Sint16(__self_0), Self::Sint16(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Sint16x2(__self_0), Self::Sint16x2(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Sint16x4(__self_0), Self::Sint16x4(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Unorm16(__self_0), Self::Unorm16(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Unorm16x2(__self_0), Self::Unorm16x2(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Unorm16x4(__self_0), Self::Unorm16x4(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Snorm16(__self_0), Self::Snorm16(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Snorm16x2(__self_0), Self::Snorm16x2(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Snorm16x4(__self_0), Self::Snorm16x4(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Float16(__self_0), Self::Float16(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Float16x2(__self_0), Self::Float16x2(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Float16x4(__self_0), Self::Float16x4(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Float32(__self_0), Self::Float32(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Float32x2(__self_0), Self::Float32x2(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Float32x3(__self_0), Self::Float32x3(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Float32x4(__self_0), Self::Float32x4(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Uint32(__self_0), Self::Uint32(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Uint32x2(__self_0), Self::Uint32x2(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Uint32x3(__self_0), Self::Uint32x3(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Uint32x4(__self_0), Self::Uint32x4(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Sint32(__self_0), Self::Sint32(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Sint32x2(__self_0), Self::Sint32x2(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Sint32x3(__self_0), Self::Sint32x3(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Sint32x4(__self_0), Self::Sint32x4(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Float64(__self_0), Self::Float64(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Float64x2(__self_0), Self::Float64x2(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Float64x3(__self_0), Self::Float64x3(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Float64x4(__self_0), Self::Float64x4(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Unorm10_10_10_2(__self_0),
                    Self::Unorm10_10_10_2(__arg1_0)) => __self_0 == __arg1_0,
                (Self::Unorm8x4Bgra(__self_0), Self::Unorm8x4Bgra(__arg1_0))
                    => __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq)]
320#[cfg_attr(feature = "serialize", derive(#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for VertexAttributeValues {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private229::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                match *self {
                    VertexAttributeValues::Uint8(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 0u32, "Uint8", __field0),
                    VertexAttributeValues::Uint8x2(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 1u32, "Uint8x2", __field0),
                    VertexAttributeValues::Uint8x4(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 2u32, "Uint8x4", __field0),
                    VertexAttributeValues::Sint8(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 3u32, "Sint8", __field0),
                    VertexAttributeValues::Sint8x2(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 4u32, "Sint8x2", __field0),
                    VertexAttributeValues::Sint8x4(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 5u32, "Sint8x4", __field0),
                    VertexAttributeValues::Unorm8(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 6u32, "Unorm8", __field0),
                    VertexAttributeValues::Unorm8x2(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 7u32, "Unorm8x2", __field0),
                    VertexAttributeValues::Unorm8x4(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 8u32, "Unorm8x4", __field0),
                    VertexAttributeValues::Snorm8(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 9u32, "Snorm8", __field0),
                    VertexAttributeValues::Snorm8x2(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 10u32, "Snorm8x2", __field0),
                    VertexAttributeValues::Snorm8x4(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 11u32, "Snorm8x4", __field0),
                    VertexAttributeValues::Uint16(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 12u32, "Uint16", __field0),
                    VertexAttributeValues::Uint16x2(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 13u32, "Uint16x2", __field0),
                    VertexAttributeValues::Uint16x4(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 14u32, "Uint16x4", __field0),
                    VertexAttributeValues::Sint16(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 15u32, "Sint16", __field0),
                    VertexAttributeValues::Sint16x2(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 16u32, "Sint16x2", __field0),
                    VertexAttributeValues::Sint16x4(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 17u32, "Sint16x4", __field0),
                    VertexAttributeValues::Unorm16(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 18u32, "Unorm16", __field0),
                    VertexAttributeValues::Unorm16x2(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 19u32, "Unorm16x2", __field0),
                    VertexAttributeValues::Unorm16x4(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 20u32, "Unorm16x4", __field0),
                    VertexAttributeValues::Snorm16(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 21u32, "Snorm16", __field0),
                    VertexAttributeValues::Snorm16x2(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 22u32, "Snorm16x2", __field0),
                    VertexAttributeValues::Snorm16x4(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 23u32, "Snorm16x4", __field0),
                    VertexAttributeValues::Float16(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 24u32, "Float16", __field0),
                    VertexAttributeValues::Float16x2(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 25u32, "Float16x2", __field0),
                    VertexAttributeValues::Float16x4(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 26u32, "Float16x4", __field0),
                    VertexAttributeValues::Float32(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 27u32, "Float32", __field0),
                    VertexAttributeValues::Float32x2(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 28u32, "Float32x2", __field0),
                    VertexAttributeValues::Float32x3(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 29u32, "Float32x3", __field0),
                    VertexAttributeValues::Float32x4(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 30u32, "Float32x4", __field0),
                    VertexAttributeValues::Uint32(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 31u32, "Uint32", __field0),
                    VertexAttributeValues::Uint32x2(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 32u32, "Uint32x2", __field0),
                    VertexAttributeValues::Uint32x3(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 33u32, "Uint32x3", __field0),
                    VertexAttributeValues::Uint32x4(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 34u32, "Uint32x4", __field0),
                    VertexAttributeValues::Sint32(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 35u32, "Sint32", __field0),
                    VertexAttributeValues::Sint32x2(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 36u32, "Sint32x2", __field0),
                    VertexAttributeValues::Sint32x3(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 37u32, "Sint32x3", __field0),
                    VertexAttributeValues::Sint32x4(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 38u32, "Sint32x4", __field0),
                    VertexAttributeValues::Float64(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 39u32, "Float64", __field0),
                    VertexAttributeValues::Float64x2(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 40u32, "Float64x2", __field0),
                    VertexAttributeValues::Float64x3(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 41u32, "Float64x3", __field0),
                    VertexAttributeValues::Float64x4(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 42u32, "Float64x4", __field0),
                    VertexAttributeValues::Unorm10_10_10_2(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 43u32, "Unorm10_10_10_2",
                            __field0),
                    VertexAttributeValues::Unorm8x4Bgra(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "VertexAttributeValues", 44u32, "Unorm8x4Bgra", __field0),
                }
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for VertexAttributeValues {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private229::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field {
                    __field0,
                    __field1,
                    __field2,
                    __field3,
                    __field4,
                    __field5,
                    __field6,
                    __field7,
                    __field8,
                    __field9,
                    __field10,
                    __field11,
                    __field12,
                    __field13,
                    __field14,
                    __field15,
                    __field16,
                    __field17,
                    __field18,
                    __field19,
                    __field20,
                    __field21,
                    __field22,
                    __field23,
                    __field24,
                    __field25,
                    __field26,
                    __field27,
                    __field28,
                    __field29,
                    __field30,
                    __field31,
                    __field32,
                    __field33,
                    __field34,
                    __field35,
                    __field36,
                    __field37,
                    __field38,
                    __field39,
                    __field40,
                    __field41,
                    __field42,
                    __field43,
                    __field44,
                }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private229::Formatter)
                        -> _serde::__private229::fmt::Result {
                        _serde::__private229::Formatter::write_str(__formatter,
                            "variant identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private229::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private229::Ok(__Field::__field0),
                            1u64 => _serde::__private229::Ok(__Field::__field1),
                            2u64 => _serde::__private229::Ok(__Field::__field2),
                            3u64 => _serde::__private229::Ok(__Field::__field3),
                            4u64 => _serde::__private229::Ok(__Field::__field4),
                            5u64 => _serde::__private229::Ok(__Field::__field5),
                            6u64 => _serde::__private229::Ok(__Field::__field6),
                            7u64 => _serde::__private229::Ok(__Field::__field7),
                            8u64 => _serde::__private229::Ok(__Field::__field8),
                            9u64 => _serde::__private229::Ok(__Field::__field9),
                            10u64 => _serde::__private229::Ok(__Field::__field10),
                            11u64 => _serde::__private229::Ok(__Field::__field11),
                            12u64 => _serde::__private229::Ok(__Field::__field12),
                            13u64 => _serde::__private229::Ok(__Field::__field13),
                            14u64 => _serde::__private229::Ok(__Field::__field14),
                            15u64 => _serde::__private229::Ok(__Field::__field15),
                            16u64 => _serde::__private229::Ok(__Field::__field16),
                            17u64 => _serde::__private229::Ok(__Field::__field17),
                            18u64 => _serde::__private229::Ok(__Field::__field18),
                            19u64 => _serde::__private229::Ok(__Field::__field19),
                            20u64 => _serde::__private229::Ok(__Field::__field20),
                            21u64 => _serde::__private229::Ok(__Field::__field21),
                            22u64 => _serde::__private229::Ok(__Field::__field22),
                            23u64 => _serde::__private229::Ok(__Field::__field23),
                            24u64 => _serde::__private229::Ok(__Field::__field24),
                            25u64 => _serde::__private229::Ok(__Field::__field25),
                            26u64 => _serde::__private229::Ok(__Field::__field26),
                            27u64 => _serde::__private229::Ok(__Field::__field27),
                            28u64 => _serde::__private229::Ok(__Field::__field28),
                            29u64 => _serde::__private229::Ok(__Field::__field29),
                            30u64 => _serde::__private229::Ok(__Field::__field30),
                            31u64 => _serde::__private229::Ok(__Field::__field31),
                            32u64 => _serde::__private229::Ok(__Field::__field32),
                            33u64 => _serde::__private229::Ok(__Field::__field33),
                            34u64 => _serde::__private229::Ok(__Field::__field34),
                            35u64 => _serde::__private229::Ok(__Field::__field35),
                            36u64 => _serde::__private229::Ok(__Field::__field36),
                            37u64 => _serde::__private229::Ok(__Field::__field37),
                            38u64 => _serde::__private229::Ok(__Field::__field38),
                            39u64 => _serde::__private229::Ok(__Field::__field39),
                            40u64 => _serde::__private229::Ok(__Field::__field40),
                            41u64 => _serde::__private229::Ok(__Field::__field41),
                            42u64 => _serde::__private229::Ok(__Field::__field42),
                            43u64 => _serde::__private229::Ok(__Field::__field43),
                            44u64 => _serde::__private229::Ok(__Field::__field44),
                            _ =>
                                _serde::__private229::Err(_serde::de::Error::invalid_value(_serde::de::Unexpected::Unsigned(__value),
                                        &"variant index 0 <= i < 45")),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private229::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "Uint8" => _serde::__private229::Ok(__Field::__field0),
                            "Uint8x2" => _serde::__private229::Ok(__Field::__field1),
                            "Uint8x4" => _serde::__private229::Ok(__Field::__field2),
                            "Sint8" => _serde::__private229::Ok(__Field::__field3),
                            "Sint8x2" => _serde::__private229::Ok(__Field::__field4),
                            "Sint8x4" => _serde::__private229::Ok(__Field::__field5),
                            "Unorm8" => _serde::__private229::Ok(__Field::__field6),
                            "Unorm8x2" => _serde::__private229::Ok(__Field::__field7),
                            "Unorm8x4" => _serde::__private229::Ok(__Field::__field8),
                            "Snorm8" => _serde::__private229::Ok(__Field::__field9),
                            "Snorm8x2" => _serde::__private229::Ok(__Field::__field10),
                            "Snorm8x4" => _serde::__private229::Ok(__Field::__field11),
                            "Uint16" => _serde::__private229::Ok(__Field::__field12),
                            "Uint16x2" => _serde::__private229::Ok(__Field::__field13),
                            "Uint16x4" => _serde::__private229::Ok(__Field::__field14),
                            "Sint16" => _serde::__private229::Ok(__Field::__field15),
                            "Sint16x2" => _serde::__private229::Ok(__Field::__field16),
                            "Sint16x4" => _serde::__private229::Ok(__Field::__field17),
                            "Unorm16" => _serde::__private229::Ok(__Field::__field18),
                            "Unorm16x2" => _serde::__private229::Ok(__Field::__field19),
                            "Unorm16x4" => _serde::__private229::Ok(__Field::__field20),
                            "Snorm16" => _serde::__private229::Ok(__Field::__field21),
                            "Snorm16x2" => _serde::__private229::Ok(__Field::__field22),
                            "Snorm16x4" => _serde::__private229::Ok(__Field::__field23),
                            "Float16" => _serde::__private229::Ok(__Field::__field24),
                            "Float16x2" => _serde::__private229::Ok(__Field::__field25),
                            "Float16x4" => _serde::__private229::Ok(__Field::__field26),
                            "Float32" => _serde::__private229::Ok(__Field::__field27),
                            "Float32x2" => _serde::__private229::Ok(__Field::__field28),
                            "Float32x3" => _serde::__private229::Ok(__Field::__field29),
                            "Float32x4" => _serde::__private229::Ok(__Field::__field30),
                            "Uint32" => _serde::__private229::Ok(__Field::__field31),
                            "Uint32x2" => _serde::__private229::Ok(__Field::__field32),
                            "Uint32x3" => _serde::__private229::Ok(__Field::__field33),
                            "Uint32x4" => _serde::__private229::Ok(__Field::__field34),
                            "Sint32" => _serde::__private229::Ok(__Field::__field35),
                            "Sint32x2" => _serde::__private229::Ok(__Field::__field36),
                            "Sint32x3" => _serde::__private229::Ok(__Field::__field37),
                            "Sint32x4" => _serde::__private229::Ok(__Field::__field38),
                            "Float64" => _serde::__private229::Ok(__Field::__field39),
                            "Float64x2" => _serde::__private229::Ok(__Field::__field40),
                            "Float64x3" => _serde::__private229::Ok(__Field::__field41),
                            "Float64x4" => _serde::__private229::Ok(__Field::__field42),
                            "Unorm10_10_10_2" =>
                                _serde::__private229::Ok(__Field::__field43),
                            "Unorm8x4Bgra" =>
                                _serde::__private229::Ok(__Field::__field44),
                            _ => {
                                _serde::__private229::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private229::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"Uint8" => _serde::__private229::Ok(__Field::__field0),
                            b"Uint8x2" => _serde::__private229::Ok(__Field::__field1),
                            b"Uint8x4" => _serde::__private229::Ok(__Field::__field2),
                            b"Sint8" => _serde::__private229::Ok(__Field::__field3),
                            b"Sint8x2" => _serde::__private229::Ok(__Field::__field4),
                            b"Sint8x4" => _serde::__private229::Ok(__Field::__field5),
                            b"Unorm8" => _serde::__private229::Ok(__Field::__field6),
                            b"Unorm8x2" => _serde::__private229::Ok(__Field::__field7),
                            b"Unorm8x4" => _serde::__private229::Ok(__Field::__field8),
                            b"Snorm8" => _serde::__private229::Ok(__Field::__field9),
                            b"Snorm8x2" => _serde::__private229::Ok(__Field::__field10),
                            b"Snorm8x4" => _serde::__private229::Ok(__Field::__field11),
                            b"Uint16" => _serde::__private229::Ok(__Field::__field12),
                            b"Uint16x2" => _serde::__private229::Ok(__Field::__field13),
                            b"Uint16x4" => _serde::__private229::Ok(__Field::__field14),
                            b"Sint16" => _serde::__private229::Ok(__Field::__field15),
                            b"Sint16x2" => _serde::__private229::Ok(__Field::__field16),
                            b"Sint16x4" => _serde::__private229::Ok(__Field::__field17),
                            b"Unorm16" => _serde::__private229::Ok(__Field::__field18),
                            b"Unorm16x2" =>
                                _serde::__private229::Ok(__Field::__field19),
                            b"Unorm16x4" =>
                                _serde::__private229::Ok(__Field::__field20),
                            b"Snorm16" => _serde::__private229::Ok(__Field::__field21),
                            b"Snorm16x2" =>
                                _serde::__private229::Ok(__Field::__field22),
                            b"Snorm16x4" =>
                                _serde::__private229::Ok(__Field::__field23),
                            b"Float16" => _serde::__private229::Ok(__Field::__field24),
                            b"Float16x2" =>
                                _serde::__private229::Ok(__Field::__field25),
                            b"Float16x4" =>
                                _serde::__private229::Ok(__Field::__field26),
                            b"Float32" => _serde::__private229::Ok(__Field::__field27),
                            b"Float32x2" =>
                                _serde::__private229::Ok(__Field::__field28),
                            b"Float32x3" =>
                                _serde::__private229::Ok(__Field::__field29),
                            b"Float32x4" =>
                                _serde::__private229::Ok(__Field::__field30),
                            b"Uint32" => _serde::__private229::Ok(__Field::__field31),
                            b"Uint32x2" => _serde::__private229::Ok(__Field::__field32),
                            b"Uint32x3" => _serde::__private229::Ok(__Field::__field33),
                            b"Uint32x4" => _serde::__private229::Ok(__Field::__field34),
                            b"Sint32" => _serde::__private229::Ok(__Field::__field35),
                            b"Sint32x2" => _serde::__private229::Ok(__Field::__field36),
                            b"Sint32x3" => _serde::__private229::Ok(__Field::__field37),
                            b"Sint32x4" => _serde::__private229::Ok(__Field::__field38),
                            b"Float64" => _serde::__private229::Ok(__Field::__field39),
                            b"Float64x2" =>
                                _serde::__private229::Ok(__Field::__field40),
                            b"Float64x3" =>
                                _serde::__private229::Ok(__Field::__field41),
                            b"Float64x4" =>
                                _serde::__private229::Ok(__Field::__field42),
                            b"Unorm10_10_10_2" =>
                                _serde::__private229::Ok(__Field::__field43),
                            b"Unorm8x4Bgra" =>
                                _serde::__private229::Ok(__Field::__field44),
                            _ => {
                                let __value =
                                    &_serde::__private229::from_utf8_lossy(__value);
                                _serde::__private229::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private229::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private229::PhantomData<VertexAttributeValues>,
                    lifetime: _serde::__private229::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = VertexAttributeValues;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private229::Formatter)
                        -> _serde::__private229::fmt::Result {
                        _serde::__private229::Formatter::write_str(__formatter,
                            "enum VertexAttributeValues")
                    }
                    fn visit_enum<__A>(self, __data: __A)
                        -> _serde::__private229::Result<Self::Value, __A::Error>
                        where __A: _serde::de::EnumAccess<'de> {
                        match _serde::de::EnumAccess::variant(__data) {
                            _serde::__private229::Ok((__Field::__field0, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<u8>>(__variant),
                                    VertexAttributeValues::Uint8),
                            _serde::__private229::Ok((__Field::__field1, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[u8; 2]>>(__variant),
                                    VertexAttributeValues::Uint8x2),
                            _serde::__private229::Ok((__Field::__field2, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[u8; 4]>>(__variant),
                                    VertexAttributeValues::Uint8x4),
                            _serde::__private229::Ok((__Field::__field3, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<i8>>(__variant),
                                    VertexAttributeValues::Sint8),
                            _serde::__private229::Ok((__Field::__field4, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[i8; 2]>>(__variant),
                                    VertexAttributeValues::Sint8x2),
                            _serde::__private229::Ok((__Field::__field5, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[i8; 4]>>(__variant),
                                    VertexAttributeValues::Sint8x4),
                            _serde::__private229::Ok((__Field::__field6, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<u8>>(__variant),
                                    VertexAttributeValues::Unorm8),
                            _serde::__private229::Ok((__Field::__field7, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[u8; 2]>>(__variant),
                                    VertexAttributeValues::Unorm8x2),
                            _serde::__private229::Ok((__Field::__field8, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[u8; 4]>>(__variant),
                                    VertexAttributeValues::Unorm8x4),
                            _serde::__private229::Ok((__Field::__field9, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<i8>>(__variant),
                                    VertexAttributeValues::Snorm8),
                            _serde::__private229::Ok((__Field::__field10, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[i8; 2]>>(__variant),
                                    VertexAttributeValues::Snorm8x2),
                            _serde::__private229::Ok((__Field::__field11, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[i8; 4]>>(__variant),
                                    VertexAttributeValues::Snorm8x4),
                            _serde::__private229::Ok((__Field::__field12, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<u16>>(__variant),
                                    VertexAttributeValues::Uint16),
                            _serde::__private229::Ok((__Field::__field13, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[u16; 2]>>(__variant),
                                    VertexAttributeValues::Uint16x2),
                            _serde::__private229::Ok((__Field::__field14, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[u16; 4]>>(__variant),
                                    VertexAttributeValues::Uint16x4),
                            _serde::__private229::Ok((__Field::__field15, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<i16>>(__variant),
                                    VertexAttributeValues::Sint16),
                            _serde::__private229::Ok((__Field::__field16, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[i16; 2]>>(__variant),
                                    VertexAttributeValues::Sint16x2),
                            _serde::__private229::Ok((__Field::__field17, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[i16; 4]>>(__variant),
                                    VertexAttributeValues::Sint16x4),
                            _serde::__private229::Ok((__Field::__field18, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<u16>>(__variant),
                                    VertexAttributeValues::Unorm16),
                            _serde::__private229::Ok((__Field::__field19, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[u16; 2]>>(__variant),
                                    VertexAttributeValues::Unorm16x2),
                            _serde::__private229::Ok((__Field::__field20, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[u16; 4]>>(__variant),
                                    VertexAttributeValues::Unorm16x4),
                            _serde::__private229::Ok((__Field::__field21, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<i16>>(__variant),
                                    VertexAttributeValues::Snorm16),
                            _serde::__private229::Ok((__Field::__field22, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[i16; 2]>>(__variant),
                                    VertexAttributeValues::Snorm16x2),
                            _serde::__private229::Ok((__Field::__field23, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[i16; 4]>>(__variant),
                                    VertexAttributeValues::Snorm16x4),
                            _serde::__private229::Ok((__Field::__field24, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<half::f16>>(__variant),
                                    VertexAttributeValues::Float16),
                            _serde::__private229::Ok((__Field::__field25, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[half::f16; 2]>>(__variant),
                                    VertexAttributeValues::Float16x2),
                            _serde::__private229::Ok((__Field::__field26, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[half::f16; 4]>>(__variant),
                                    VertexAttributeValues::Float16x4),
                            _serde::__private229::Ok((__Field::__field27, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<f32>>(__variant),
                                    VertexAttributeValues::Float32),
                            _serde::__private229::Ok((__Field::__field28, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[f32; 2]>>(__variant),
                                    VertexAttributeValues::Float32x2),
                            _serde::__private229::Ok((__Field::__field29, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[f32; 3]>>(__variant),
                                    VertexAttributeValues::Float32x3),
                            _serde::__private229::Ok((__Field::__field30, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[f32; 4]>>(__variant),
                                    VertexAttributeValues::Float32x4),
                            _serde::__private229::Ok((__Field::__field31, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<u32>>(__variant),
                                    VertexAttributeValues::Uint32),
                            _serde::__private229::Ok((__Field::__field32, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[u32; 2]>>(__variant),
                                    VertexAttributeValues::Uint32x2),
                            _serde::__private229::Ok((__Field::__field33, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[u32; 3]>>(__variant),
                                    VertexAttributeValues::Uint32x3),
                            _serde::__private229::Ok((__Field::__field34, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[u32; 4]>>(__variant),
                                    VertexAttributeValues::Uint32x4),
                            _serde::__private229::Ok((__Field::__field35, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<i32>>(__variant),
                                    VertexAttributeValues::Sint32),
                            _serde::__private229::Ok((__Field::__field36, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[i32; 2]>>(__variant),
                                    VertexAttributeValues::Sint32x2),
                            _serde::__private229::Ok((__Field::__field37, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[i32; 3]>>(__variant),
                                    VertexAttributeValues::Sint32x3),
                            _serde::__private229::Ok((__Field::__field38, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[i32; 4]>>(__variant),
                                    VertexAttributeValues::Sint32x4),
                            _serde::__private229::Ok((__Field::__field39, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<f64>>(__variant),
                                    VertexAttributeValues::Float64),
                            _serde::__private229::Ok((__Field::__field40, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[f64; 2]>>(__variant),
                                    VertexAttributeValues::Float64x2),
                            _serde::__private229::Ok((__Field::__field41, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[f64; 3]>>(__variant),
                                    VertexAttributeValues::Float64x3),
                            _serde::__private229::Ok((__Field::__field42, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[f64; 4]>>(__variant),
                                    VertexAttributeValues::Float64x4),
                            _serde::__private229::Ok((__Field::__field43, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<u32>>(__variant),
                                    VertexAttributeValues::Unorm10_10_10_2),
                            _serde::__private229::Ok((__Field::__field44, __variant)) =>
                                _serde::__private229::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<[u8; 4]>>(__variant),
                                    VertexAttributeValues::Unorm8x4Bgra),
                            _serde::__private229::Err(__err) =>
                                _serde::__private229::Err(__err),
                        }
                    }
                }
                #[doc(hidden)]
                const VARIANTS: &'static [&'static str] =
                    &["Uint8", "Uint8x2", "Uint8x4", "Sint8", "Sint8x2",
                                "Sint8x4", "Unorm8", "Unorm8x2", "Unorm8x4", "Snorm8",
                                "Snorm8x2", "Snorm8x4", "Uint16", "Uint16x2", "Uint16x4",
                                "Sint16", "Sint16x2", "Sint16x4", "Unorm16", "Unorm16x2",
                                "Unorm16x4", "Snorm16", "Snorm16x2", "Snorm16x4", "Float16",
                                "Float16x2", "Float16x4", "Float32", "Float32x2",
                                "Float32x3", "Float32x4", "Uint32", "Uint32x2", "Uint32x3",
                                "Uint32x4", "Sint32", "Sint32x2", "Sint32x3", "Sint32x4",
                                "Float64", "Float64x2", "Float64x3", "Float64x4",
                                "Unorm10_10_10_2", "Unorm8x4Bgra"];
                _serde::Deserializer::deserialize_enum(__deserializer,
                    "VertexAttributeValues", VARIANTS,
                    __Visitor {
                        marker: _serde::__private229::PhantomData::<VertexAttributeValues>,
                        lifetime: _serde::__private229::PhantomData,
                    })
            }
        }
    };Deserialize))]
321pub enum VertexAttributeValues {
322    /// One unsigned byte (u8). `u32` in shaders.
323    Uint8(Vec<u8>),
324    /// Two unsigned bytes (u8). `vec2<u32>` in shaders.
325    Uint8x2(Vec<[u8; 2]>),
326    /// Four unsigned bytes (u8). `vec4<u32>` in shaders.
327    Uint8x4(Vec<[u8; 4]>),
328    /// One signed byte (i8). `i32` in shaders.
329    Sint8(Vec<i8>),
330    /// Two signed bytes (i8). `vec2<i32>` in shaders.
331    Sint8x2(Vec<[i8; 2]>),
332    /// Four signed bytes (i8). `vec4<i32>` in shaders.
333    Sint8x4(Vec<[i8; 4]>),
334    /// One unsigned byte (u8). [0, 255] converted to float [0, 1] `f32` in shaders.
335    Unorm8(Vec<u8>),
336    /// Two unsigned bytes (u8). [0, 255] converted to float [0, 1] `vec2<f32>` in shaders.
337    Unorm8x2(Vec<[u8; 2]>),
338    /// Four unsigned bytes (u8). [0, 255] converted to float [0, 1] `vec4<f32>` in shaders.
339    Unorm8x4(Vec<[u8; 4]>),
340    /// One signed byte (i8). [&minus;127, 127] converted to float [&minus;1, 1] `f32` in shaders.
341    Snorm8(Vec<i8>),
342    /// Two signed bytes (i8). [&minus;127, 127] converted to float [&minus;1, 1] `vec2<f32>` in shaders.
343    Snorm8x2(Vec<[i8; 2]>),
344    /// Four signed bytes (i8). [&minus;127, 127] converted to float [&minus;1, 1] `vec4<f32>` in shaders.
345    Snorm8x4(Vec<[i8; 4]>),
346    /// One unsigned short (u16). `u32` in shaders.
347    Uint16(Vec<u16>),
348    /// Two unsigned shorts (u16). `vec2<u32>` in shaders.
349    Uint16x2(Vec<[u16; 2]>),
350    /// Four unsigned shorts (u16). `vec4<u32>` in shaders.
351    Uint16x4(Vec<[u16; 4]>),
352    /// One signed short (i16). `i32` in shaders.
353    Sint16(Vec<i16>),
354    /// Two signed shorts (i16). `vec2<i32>` in shaders.
355    Sint16x2(Vec<[i16; 2]>),
356    /// Four signed shorts (i16). `vec4<i32>` in shaders.
357    Sint16x4(Vec<[i16; 4]>),
358    /// One unsigned short (u16). [0, 65535] converted to float [0, 1] `f32` in shaders.
359    Unorm16(Vec<u16>),
360    /// Two unsigned shorts (u16). [0, 65535] converted to float [0, 1] `vec2<f32>` in shaders.
361    Unorm16x2(Vec<[u16; 2]>),
362    /// Four unsigned shorts (u16). [0, 65535] converted to float [0, 1] `vec4<f32>` in shaders.
363    Unorm16x4(Vec<[u16; 4]>),
364    /// One signed short (i16). [&minus;32767, 32767] converted to float [&minus;1, 1] `f32` in shaders.
365    Snorm16(Vec<i16>),
366    /// Two signed shorts (i16). [&minus;32767, 32767] converted to float [&minus;1, 1] `vec2<f32>` in shaders.
367    Snorm16x2(Vec<[i16; 2]>),
368    /// Four signed shorts (i16). [&minus;32767, 32767] converted to float [&minus;1, 1] `vec4<f32>` in shaders.
369    Snorm16x4(Vec<[i16; 4]>),
370    /// One half-precision float (no Rust equiv). `f32` in shaders.
371    Float16(Vec<half::f16>),
372    /// Two half-precision floats (no Rust equiv). `vec2<f32>` in shaders.
373    Float16x2(Vec<[half::f16; 2]>),
374    /// Four half-precision floats (no Rust equiv). `vec4<f32>` in shaders.
375    Float16x4(Vec<[half::f16; 4]>),
376    /// One single-precision float (f32). `f32` in shaders.
377    Float32(Vec<f32>),
378    /// Two single-precision floats (f32). `vec2<f32>` in shaders.
379    Float32x2(Vec<[f32; 2]>),
380    /// Three single-precision floats (f32). `vec3<f32>` in shaders.
381    Float32x3(Vec<[f32; 3]>),
382    /// Four single-precision floats (f32). `vec4<f32>` in shaders.
383    Float32x4(Vec<[f32; 4]>),
384    /// One unsigned int (u32). `u32` in shaders.
385    Uint32(Vec<u32>),
386    /// Two unsigned ints (u32). `vec2<u32>` in shaders.
387    Uint32x2(Vec<[u32; 2]>),
388    /// Three unsigned ints (u32). `vec3<u32>` in shaders.
389    Uint32x3(Vec<[u32; 3]>),
390    /// Four unsigned ints (u32). `vec4<u32>` in shaders.
391    Uint32x4(Vec<[u32; 4]>),
392    /// One signed int (i32). `i32` in shaders.
393    Sint32(Vec<i32>),
394    /// Two signed ints (i32). `vec2<i32>` in shaders.
395    Sint32x2(Vec<[i32; 2]>),
396    /// Three signed ints (i32). `vec3<i32>` in shaders.
397    Sint32x3(Vec<[i32; 3]>),
398    /// Four signed ints (i32). `vec4<i32>` in shaders.
399    Sint32x4(Vec<[i32; 4]>),
400    /// One double-precision float (f64). `f32` in shaders. Requires [`wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT`].
401    Float64(Vec<f64>),
402    /// Two double-precision floats (f64). `vec2<f32>` in shaders. Requires [`wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT`].
403    Float64x2(Vec<[f64; 2]>),
404    /// Three double-precision floats (f64). `vec3<f32>` in shaders. Requires [`wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT`].
405    Float64x3(Vec<[f64; 3]>),
406    /// Four double-precision floats (f64). `vec4<f32>` in shaders. Requires [`wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT`].
407    Float64x4(Vec<[f64; 4]>),
408    /// 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.
409    Unorm10_10_10_2(Vec<u32>),
410    /// Four unsigned 8-bit integers (u8) in BGRA. [0, 255] converted to float [0, 1] `vec4<f32>` RGBA in shaders.
411    Unorm8x4Bgra(Vec<[u8; 4]>),
412}
413
414impl VertexAttributeValues {
415    /// Creates a new [`VertexAttributeValues`] with the storage for given [`VertexFormat`].
416    pub(crate) fn new(format: VertexFormat) -> Self {
417        match format {
418            VertexFormat::Uint8x2 => VertexAttributeValues::Uint8x2(Vec::new()),
419            VertexFormat::Uint8x4 => VertexAttributeValues::Uint8x4(Vec::new()),
420            VertexFormat::Sint8x2 => VertexAttributeValues::Sint8x2(Vec::new()),
421            VertexFormat::Sint8x4 => VertexAttributeValues::Sint8x4(Vec::new()),
422            VertexFormat::Unorm8x2 => VertexAttributeValues::Unorm8x2(Vec::new()),
423            VertexFormat::Unorm8x4 => VertexAttributeValues::Unorm8x4(Vec::new()),
424            VertexFormat::Snorm8x2 => VertexAttributeValues::Snorm8x2(Vec::new()),
425            VertexFormat::Snorm8x4 => VertexAttributeValues::Snorm8x4(Vec::new()),
426            VertexFormat::Uint16x2 => VertexAttributeValues::Uint16x2(Vec::new()),
427            VertexFormat::Uint16x4 => VertexAttributeValues::Uint16x4(Vec::new()),
428            VertexFormat::Sint16x2 => VertexAttributeValues::Sint16x2(Vec::new()),
429            VertexFormat::Sint16x4 => VertexAttributeValues::Sint16x4(Vec::new()),
430            VertexFormat::Unorm16x2 => VertexAttributeValues::Unorm16x2(Vec::new()),
431            VertexFormat::Unorm16x4 => VertexAttributeValues::Unorm16x4(Vec::new()),
432            VertexFormat::Snorm16x2 => VertexAttributeValues::Snorm16x2(Vec::new()),
433            VertexFormat::Snorm16x4 => VertexAttributeValues::Snorm16x4(Vec::new()),
434            VertexFormat::Float32 => VertexAttributeValues::Float32(Vec::new()),
435            VertexFormat::Float32x2 => VertexAttributeValues::Float32x2(Vec::new()),
436            VertexFormat::Float32x3 => VertexAttributeValues::Float32x3(Vec::new()),
437            VertexFormat::Float32x4 => VertexAttributeValues::Float32x4(Vec::new()),
438            VertexFormat::Uint32 => VertexAttributeValues::Uint32(Vec::new()),
439            VertexFormat::Uint32x2 => VertexAttributeValues::Uint32x2(Vec::new()),
440            VertexFormat::Uint32x3 => VertexAttributeValues::Uint32x3(Vec::new()),
441            VertexFormat::Uint32x4 => VertexAttributeValues::Uint32x4(Vec::new()),
442            VertexFormat::Sint32 => VertexAttributeValues::Sint32(Vec::new()),
443            VertexFormat::Sint32x2 => VertexAttributeValues::Sint32x2(Vec::new()),
444            VertexFormat::Sint32x3 => VertexAttributeValues::Sint32x3(Vec::new()),
445            VertexFormat::Sint32x4 => VertexAttributeValues::Sint32x4(Vec::new()),
446            VertexFormat::Uint8 => VertexAttributeValues::Uint8(Vec::new()),
447            VertexFormat::Sint8 => VertexAttributeValues::Sint8(Vec::new()),
448            VertexFormat::Snorm8 => VertexAttributeValues::Snorm8(Vec::new()),
449            VertexFormat::Unorm8 => VertexAttributeValues::Unorm8(Vec::new()),
450            VertexFormat::Uint16 => VertexAttributeValues::Uint16(Vec::new()),
451            VertexFormat::Sint16 => VertexAttributeValues::Sint16(Vec::new()),
452            VertexFormat::Snorm16 => VertexAttributeValues::Snorm16(Vec::new()),
453            VertexFormat::Unorm16 => VertexAttributeValues::Unorm16(Vec::new()),
454            VertexFormat::Float16 => VertexAttributeValues::Float16(Vec::new()),
455            VertexFormat::Float16x2 => VertexAttributeValues::Float16x2(Vec::new()),
456            VertexFormat::Float16x4 => VertexAttributeValues::Float16x4(Vec::new()),
457            VertexFormat::Float64 => VertexAttributeValues::Float64(Vec::new()),
458            VertexFormat::Float64x2 => VertexAttributeValues::Float64x2(Vec::new()),
459            VertexFormat::Float64x3 => VertexAttributeValues::Float64x3(Vec::new()),
460            VertexFormat::Float64x4 => VertexAttributeValues::Float64x4(Vec::new()),
461            VertexFormat::Unorm8x4Bgra => VertexAttributeValues::Unorm8x4Bgra(Vec::new()),
462            VertexFormat::Unorm10_10_10_2 => VertexAttributeValues::Unorm10_10_10_2(Vec::new()),
463        }
464    }
465
466    /// Returns the number of vertices in this [`VertexAttributeValues`]. For a single
467    /// mesh, all of the [`VertexAttributeValues`] must have the same length.
468    #[expect(
469        clippy::match_same_arms,
470        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."
471    )]
472    pub fn len(&self) -> usize {
473        match self {
474            VertexAttributeValues::Float32(values) => values.len(),
475            VertexAttributeValues::Sint32(values) => values.len(),
476            VertexAttributeValues::Uint32(values) => values.len(),
477            VertexAttributeValues::Float32x2(values) => values.len(),
478            VertexAttributeValues::Sint32x2(values) => values.len(),
479            VertexAttributeValues::Uint32x2(values) => values.len(),
480            VertexAttributeValues::Float32x3(values) => values.len(),
481            VertexAttributeValues::Sint32x3(values) => values.len(),
482            VertexAttributeValues::Uint32x3(values) => values.len(),
483            VertexAttributeValues::Float32x4(values) => values.len(),
484            VertexAttributeValues::Sint32x4(values) => values.len(),
485            VertexAttributeValues::Uint32x4(values) => values.len(),
486            VertexAttributeValues::Sint16x2(values) => values.len(),
487            VertexAttributeValues::Snorm16x2(values) => values.len(),
488            VertexAttributeValues::Uint16x2(values) => values.len(),
489            VertexAttributeValues::Unorm16x2(values) => values.len(),
490            VertexAttributeValues::Sint16x4(values) => values.len(),
491            VertexAttributeValues::Snorm16x4(values) => values.len(),
492            VertexAttributeValues::Uint16x4(values) => values.len(),
493            VertexAttributeValues::Unorm16x4(values) => values.len(),
494            VertexAttributeValues::Sint8x2(values) => values.len(),
495            VertexAttributeValues::Snorm8x2(values) => values.len(),
496            VertexAttributeValues::Uint8x2(values) => values.len(),
497            VertexAttributeValues::Unorm8x2(values) => values.len(),
498            VertexAttributeValues::Sint8x4(values) => values.len(),
499            VertexAttributeValues::Snorm8x4(values) => values.len(),
500            VertexAttributeValues::Uint8x4(values) => values.len(),
501            VertexAttributeValues::Unorm8x4(values) => values.len(),
502            VertexAttributeValues::Uint8(values) => values.len(),
503            VertexAttributeValues::Sint8(values) => values.len(),
504            VertexAttributeValues::Unorm8(values) => values.len(),
505            VertexAttributeValues::Snorm8(values) => values.len(),
506            VertexAttributeValues::Uint16(values) => values.len(),
507            VertexAttributeValues::Sint16(values) => values.len(),
508            VertexAttributeValues::Unorm16(values) => values.len(),
509            VertexAttributeValues::Snorm16(values) => values.len(),
510            VertexAttributeValues::Float16(values) => values.len(),
511            VertexAttributeValues::Float16x2(values) => values.len(),
512            VertexAttributeValues::Float16x4(values) => values.len(),
513            VertexAttributeValues::Float64(values) => values.len(),
514            VertexAttributeValues::Float64x2(values) => values.len(),
515            VertexAttributeValues::Float64x3(values) => values.len(),
516            VertexAttributeValues::Float64x4(values) => values.len(),
517            VertexAttributeValues::Unorm10_10_10_2(values) => values.len(),
518            VertexAttributeValues::Unorm8x4Bgra(values) => values.len(),
519        }
520    }
521
522    /// Returns `true` if there are no vertices in this [`VertexAttributeValues`].
523    pub fn is_empty(&self) -> bool {
524        self.len() == 0
525    }
526
527    /// Returns the values as float triples if possible.
528    pub fn as_float3(&self) -> Option<&[[f32; 3]]> {
529        match self {
530            VertexAttributeValues::Float32x3(values) => Some(values),
531            _ => None,
532        }
533    }
534
535    // TODO: add vertex format as parameter here and perform type conversions
536    /// Flattens the [`VertexAttributeValues`] into a sequence of bytes. This is
537    /// useful for serialization and sending to the GPU.
538    #[expect(
539        clippy::match_same_arms,
540        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."
541    )]
542    pub fn get_bytes(&self) -> &[u8] {
543        match self {
544            VertexAttributeValues::Float32(values) => cast_slice(values),
545            VertexAttributeValues::Sint32(values) => cast_slice(values),
546            VertexAttributeValues::Uint32(values) => cast_slice(values),
547            VertexAttributeValues::Float32x2(values) => cast_slice(values),
548            VertexAttributeValues::Sint32x2(values) => cast_slice(values),
549            VertexAttributeValues::Uint32x2(values) => cast_slice(values),
550            VertexAttributeValues::Float32x3(values) => cast_slice(values),
551            VertexAttributeValues::Sint32x3(values) => cast_slice(values),
552            VertexAttributeValues::Uint32x3(values) => cast_slice(values),
553            VertexAttributeValues::Float32x4(values) => cast_slice(values),
554            VertexAttributeValues::Sint32x4(values) => cast_slice(values),
555            VertexAttributeValues::Uint32x4(values) => cast_slice(values),
556            VertexAttributeValues::Sint16x2(values) => cast_slice(values),
557            VertexAttributeValues::Snorm16x2(values) => cast_slice(values),
558            VertexAttributeValues::Uint16x2(values) => cast_slice(values),
559            VertexAttributeValues::Unorm16x2(values) => cast_slice(values),
560            VertexAttributeValues::Sint16x4(values) => cast_slice(values),
561            VertexAttributeValues::Snorm16x4(values) => cast_slice(values),
562            VertexAttributeValues::Uint16x4(values) => cast_slice(values),
563            VertexAttributeValues::Unorm16x4(values) => cast_slice(values),
564            VertexAttributeValues::Sint8x2(values) => cast_slice(values),
565            VertexAttributeValues::Snorm8x2(values) => cast_slice(values),
566            VertexAttributeValues::Uint8x2(values) => cast_slice(values),
567            VertexAttributeValues::Unorm8x2(values) => cast_slice(values),
568            VertexAttributeValues::Sint8x4(values) => cast_slice(values),
569            VertexAttributeValues::Snorm8x4(values) => cast_slice(values),
570            VertexAttributeValues::Uint8x4(values) => cast_slice(values),
571            VertexAttributeValues::Unorm8x4(values) => cast_slice(values),
572            VertexAttributeValues::Uint8(values) => cast_slice(values),
573            VertexAttributeValues::Sint8(values) => cast_slice(values),
574            VertexAttributeValues::Unorm8(values) => cast_slice(values),
575            VertexAttributeValues::Snorm8(values) => cast_slice(values),
576            VertexAttributeValues::Uint16(values) => cast_slice(values),
577            VertexAttributeValues::Sint16(values) => cast_slice(values),
578            VertexAttributeValues::Unorm16(values) => cast_slice(values),
579            VertexAttributeValues::Snorm16(values) => cast_slice(values),
580            VertexAttributeValues::Float16(values) => cast_slice(values),
581            VertexAttributeValues::Float16x2(values) => cast_slice(values),
582            VertexAttributeValues::Float16x4(values) => cast_slice(values),
583            VertexAttributeValues::Float64(values) => cast_slice(values),
584            VertexAttributeValues::Float64x2(values) => cast_slice(values),
585            VertexAttributeValues::Float64x3(values) => cast_slice(values),
586            VertexAttributeValues::Float64x4(values) => cast_slice(values),
587            VertexAttributeValues::Unorm10_10_10_2(values) => cast_slice(values),
588            VertexAttributeValues::Unorm8x4Bgra(values) => cast_slice(values),
589        }
590    }
591
592    /// Create a new `VertexAttributeValues` with Float32 values quantized to the format of `quantization`.
593    /// Return None if the values are not Float32, Float32x2 or Float32x4.
594    pub(crate) fn create_quantized_values(
595        &self,
596        quantization: AttributeQuantization,
597    ) -> Option<VertexAttributeValues> {
598        match self {
599            VertexAttributeValues::Float32(values) => {
600                Some(quantization.quantize_f32_values::<1>(bytemuck::must_cast_slice(values)))
601            }
602            VertexAttributeValues::Float32x2(values) => {
603                Some(quantization.quantize_f32_values::<2>(values))
604            }
605            VertexAttributeValues::Float32x4(values) => {
606                Some(quantization.quantize_f32_values::<4>(values))
607            }
608            _ => None,
609        }
610    }
611
612    /// Create a new `VertexAttributeValues` with Float32x3 normals converted to Snorm16x2 using octahedral encoding. Return None if the values are not Float32x3.
613    pub(crate) fn create_octahedral_encode_normals(&self) -> Option<VertexAttributeValues> {
614        match &self {
615            VertexAttributeValues::Float32x3(uncompressed_values) => {
616                let mut values = Vec::<[i16; 2]>::with_capacity(uncompressed_values.len());
617                for value in uncompressed_values {
618                    let encoded = octahedral_encode_signed(Vec3::from_array(*value).normalize());
619                    values.push(arr_f32_to_snorm16(encoded.to_array()));
620                }
621                Some(VertexAttributeValues::Snorm16x2(values))
622            }
623            _ => None,
624        }
625    }
626
627    /// Create a new `VertexAttributeValues` with Float32x4 tangents converted to Snorm16x2 using octahedral encoding. Return None if the values are not Float32x4.
628    pub(crate) fn create_octahedral_encode_tangents(&self) -> Option<VertexAttributeValues> {
629        match &self {
630            VertexAttributeValues::Float32x4(uncompressed_values) => {
631                let mut values = Vec::<[i16; 2]>::with_capacity(uncompressed_values.len());
632                for value in uncompressed_values {
633                    let encoded = octahedral_encode_tangent(
634                        Vec3::from_array([value[0], value[1], value[2]]).normalize(),
635                        value[3],
636                    );
637                    values.push(arr_f32_to_snorm16(encoded.to_array()));
638                }
639                Some(VertexAttributeValues::Snorm16x2(values))
640            }
641            _ => None,
642        }
643    }
644
645    /// Returns the compressed positions, or `None` if `self` is not [`Self::Float32x3`].
646    pub(crate) fn create_compressed_positions(
647        &self,
648        aabb: Aabb3d,
649    ) -> Option<VertexAttributeValues> {
650        // Create Snorm16x4 position
651        let VertexAttributeValues::Float32x3(uncompressed_values) = self else {
652            return None;
653        };
654        let mut values = Vec::<[i16; 4]>::with_capacity(uncompressed_values.len());
655        let scale = 1.0 / aabb.half_size();
656        let scale = Vec3A::select(scale.is_nan_mask(), Vec3A::ZERO, scale);
657        for val in uncompressed_values {
658            let mut val = Vec3A::from_array(*val);
659            val = (val - aabb.center()) * scale;
660            let val = arr_f32_to_snorm16(val.extend(0.0).to_array());
661            values.push(val);
662        }
663        Some(VertexAttributeValues::Snorm16x4(values))
664    }
665
666    /// Create compressed UVs. Returns `None` if `self` isn't [`VertexAttributeValues::Float32x2`].
667    pub(crate) fn create_compressed_uvs(&self, range: Aabb2d) -> Option<VertexAttributeValues> {
668        // Create Unorm16x2 UVs
669        let VertexAttributeValues::Float32x2(uncompressed_values) = self else {
670            return None;
671        };
672        let mut values = Vec::<[u16; 2]>::with_capacity(uncompressed_values.len());
673        let scale = 1.0 / (range.max - range.min);
674        let scale = Vec2::select(scale.is_nan_mask(), Vec2::ZERO, scale);
675        for val in uncompressed_values {
676            let mut val = Vec2::from_array(*val);
677            val = (val - range.min) * scale;
678            values.push(arr_f32_to_unorm16(val.to_array()));
679        }
680        Some(VertexAttributeValues::Unorm16x2(values))
681    }
682
683    #[expect(
684        clippy::match_same_arms,
685        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."
686    )]
687    pub(crate) fn get_bytes_at(&self, i: usize) -> &[u8] {
688        match self {
689            VertexAttributeValues::Float32(values) => bytes_of(&values[i]),
690            VertexAttributeValues::Sint32(values) => bytes_of(&values[i]),
691            VertexAttributeValues::Uint32(values) => bytes_of(&values[i]),
692            VertexAttributeValues::Float32x2(values) => bytes_of(&values[i]),
693            VertexAttributeValues::Sint32x2(values) => bytes_of(&values[i]),
694            VertexAttributeValues::Uint32x2(values) => bytes_of(&values[i]),
695            VertexAttributeValues::Float32x3(values) => bytes_of(&values[i]),
696            VertexAttributeValues::Sint32x3(values) => bytes_of(&values[i]),
697            VertexAttributeValues::Uint32x3(values) => bytes_of(&values[i]),
698            VertexAttributeValues::Float32x4(values) => bytes_of(&values[i]),
699            VertexAttributeValues::Sint32x4(values) => bytes_of(&values[i]),
700            VertexAttributeValues::Uint32x4(values) => bytes_of(&values[i]),
701            VertexAttributeValues::Sint16x2(values) => bytes_of(&values[i]),
702            VertexAttributeValues::Snorm16x2(values) => bytes_of(&values[i]),
703            VertexAttributeValues::Uint16x2(values) => bytes_of(&values[i]),
704            VertexAttributeValues::Unorm16x2(values) => bytes_of(&values[i]),
705            VertexAttributeValues::Sint16x4(values) => bytes_of(&values[i]),
706            VertexAttributeValues::Snorm16x4(values) => bytes_of(&values[i]),
707            VertexAttributeValues::Uint16x4(values) => bytes_of(&values[i]),
708            VertexAttributeValues::Unorm16x4(values) => bytes_of(&values[i]),
709            VertexAttributeValues::Sint8x2(values) => bytes_of(&values[i]),
710            VertexAttributeValues::Snorm8x2(values) => bytes_of(&values[i]),
711            VertexAttributeValues::Uint8x2(values) => bytes_of(&values[i]),
712            VertexAttributeValues::Unorm8x2(values) => bytes_of(&values[i]),
713            VertexAttributeValues::Sint8x4(values) => bytes_of(&values[i]),
714            VertexAttributeValues::Snorm8x4(values) => bytes_of(&values[i]),
715            VertexAttributeValues::Uint8x4(values) => bytes_of(&values[i]),
716            VertexAttributeValues::Unorm8x4(values) => bytes_of(&values[i]),
717            VertexAttributeValues::Uint8(values) => bytes_of(&values[i]),
718            VertexAttributeValues::Sint8(values) => bytes_of(&values[i]),
719            VertexAttributeValues::Unorm8(values) => bytes_of(&values[i]),
720            VertexAttributeValues::Snorm8(values) => bytes_of(&values[i]),
721            VertexAttributeValues::Uint16(values) => bytes_of(&values[i]),
722            VertexAttributeValues::Sint16(values) => bytes_of(&values[i]),
723            VertexAttributeValues::Unorm16(values) => bytes_of(&values[i]),
724            VertexAttributeValues::Snorm16(values) => bytes_of(&values[i]),
725            VertexAttributeValues::Float16(values) => bytes_of(&values[i]),
726            VertexAttributeValues::Float16x2(values) => bytes_of(&values[i]),
727            VertexAttributeValues::Float16x4(values) => bytes_of(&values[i]),
728            VertexAttributeValues::Float64(values) => bytes_of(&values[i]),
729            VertexAttributeValues::Float64x2(values) => bytes_of(&values[i]),
730            VertexAttributeValues::Float64x3(values) => bytes_of(&values[i]),
731            VertexAttributeValues::Float64x4(values) => bytes_of(&values[i]),
732            VertexAttributeValues::Unorm10_10_10_2(values) => bytes_of(&values[i]),
733            VertexAttributeValues::Unorm8x4Bgra(values) => bytes_of(&values[i]),
734        }
735    }
736
737    #[expect(
738        clippy::match_same_arms,
739        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."
740    )]
741    pub(crate) fn push_from(&mut self, source: &VertexAttributeValues, i: usize) {
742        match (self, source) {
743            (VertexAttributeValues::Float32(this), VertexAttributeValues::Float32(source)) => {
744                this.push(source[i]);
745            }
746            (VertexAttributeValues::Float32(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
747            (VertexAttributeValues::Sint32(this), VertexAttributeValues::Sint32(source)) => {
748                this.push(source[i]);
749            }
750            (VertexAttributeValues::Sint32(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
751            (VertexAttributeValues::Uint32(this), VertexAttributeValues::Uint32(source)) => {
752                this.push(source[i]);
753            }
754            (VertexAttributeValues::Uint32(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
755            (VertexAttributeValues::Float32x2(this), VertexAttributeValues::Float32x2(source)) => {
756                this.push(source[i]);
757            }
758            (VertexAttributeValues::Float32x2(_), _) => {
759                {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values")
760            }
761            (VertexAttributeValues::Sint32x2(this), VertexAttributeValues::Sint32x2(source)) => {
762                this.push(source[i]);
763            }
764            (VertexAttributeValues::Sint32x2(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
765            (VertexAttributeValues::Uint32x2(this), VertexAttributeValues::Uint32x2(source)) => {
766                this.push(source[i]);
767            }
768            (VertexAttributeValues::Uint32x2(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
769            (VertexAttributeValues::Float32x3(this), VertexAttributeValues::Float32x3(source)) => {
770                this.push(source[i]);
771            }
772            (VertexAttributeValues::Float32x3(_), _) => {
773                {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values")
774            }
775            (VertexAttributeValues::Sint32x3(this), VertexAttributeValues::Sint32x3(source)) => {
776                this.push(source[i]);
777            }
778            (VertexAttributeValues::Sint32x3(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
779            (VertexAttributeValues::Uint32x3(this), VertexAttributeValues::Uint32x3(source)) => {
780                this.push(source[i]);
781            }
782            (VertexAttributeValues::Uint32x3(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
783            (VertexAttributeValues::Float32x4(this), VertexAttributeValues::Float32x4(source)) => {
784                this.push(source[i]);
785            }
786            (VertexAttributeValues::Float32x4(_), _) => {
787                {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values")
788            }
789            (VertexAttributeValues::Sint32x4(this), VertexAttributeValues::Sint32x4(source)) => {
790                this.push(source[i]);
791            }
792            (VertexAttributeValues::Sint32x4(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
793            (VertexAttributeValues::Uint32x4(this), VertexAttributeValues::Uint32x4(source)) => {
794                this.push(source[i]);
795            }
796            (VertexAttributeValues::Uint32x4(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
797            (VertexAttributeValues::Sint16x2(this), VertexAttributeValues::Sint16x2(source)) => {
798                this.push(source[i]);
799            }
800            (VertexAttributeValues::Sint16x2(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
801            (VertexAttributeValues::Snorm16x2(this), VertexAttributeValues::Snorm16x2(source)) => {
802                this.push(source[i]);
803            }
804            (VertexAttributeValues::Snorm16x2(_), _) => {
805                {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values")
806            }
807            (VertexAttributeValues::Uint16x2(this), VertexAttributeValues::Uint16x2(source)) => {
808                this.push(source[i]);
809            }
810            (VertexAttributeValues::Uint16x2(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
811            (VertexAttributeValues::Unorm16x2(this), VertexAttributeValues::Unorm16x2(source)) => {
812                this.push(source[i]);
813            }
814            (VertexAttributeValues::Unorm16x2(_), _) => {
815                {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values")
816            }
817            (VertexAttributeValues::Sint16x4(this), VertexAttributeValues::Sint16x4(source)) => {
818                this.push(source[i]);
819            }
820            (VertexAttributeValues::Sint16x4(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
821            (VertexAttributeValues::Snorm16x4(this), VertexAttributeValues::Snorm16x4(source)) => {
822                this.push(source[i]);
823            }
824            (VertexAttributeValues::Snorm16x4(_), _) => {
825                {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values")
826            }
827            (VertexAttributeValues::Uint16x4(this), VertexAttributeValues::Uint16x4(source)) => {
828                this.push(source[i]);
829            }
830            (VertexAttributeValues::Uint16x4(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
831            (VertexAttributeValues::Unorm16x4(this), VertexAttributeValues::Unorm16x4(source)) => {
832                this.push(source[i]);
833            }
834            (VertexAttributeValues::Unorm16x4(_), _) => {
835                {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values")
836            }
837            (VertexAttributeValues::Sint8x2(this), VertexAttributeValues::Sint8x2(source)) => {
838                this.push(source[i]);
839            }
840            (VertexAttributeValues::Sint8x2(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
841            (VertexAttributeValues::Snorm8x2(this), VertexAttributeValues::Snorm8x2(source)) => {
842                this.push(source[i]);
843            }
844            (VertexAttributeValues::Snorm8x2(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
845            (VertexAttributeValues::Uint8x2(this), VertexAttributeValues::Uint8x2(source)) => {
846                this.push(source[i]);
847            }
848            (VertexAttributeValues::Uint8x2(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
849            (VertexAttributeValues::Unorm8x2(this), VertexAttributeValues::Unorm8x2(source)) => {
850                this.push(source[i]);
851            }
852            (VertexAttributeValues::Unorm8x2(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
853            (VertexAttributeValues::Sint8x4(this), VertexAttributeValues::Sint8x4(source)) => {
854                this.push(source[i]);
855            }
856            (VertexAttributeValues::Sint8x4(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
857            (VertexAttributeValues::Snorm8x4(this), VertexAttributeValues::Snorm8x4(source)) => {
858                this.push(source[i]);
859            }
860            (VertexAttributeValues::Snorm8x4(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
861            (VertexAttributeValues::Uint8x4(this), VertexAttributeValues::Uint8x4(source)) => {
862                this.push(source[i]);
863            }
864            (VertexAttributeValues::Uint8x4(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
865            (VertexAttributeValues::Unorm8x4(this), VertexAttributeValues::Unorm8x4(source)) => {
866                this.push(source[i]);
867            }
868            (VertexAttributeValues::Unorm8x4(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
869            (VertexAttributeValues::Uint8(this), VertexAttributeValues::Uint8(source)) => {
870                this.push(source[i]);
871            }
872            (VertexAttributeValues::Uint8(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
873            (VertexAttributeValues::Sint8(this), VertexAttributeValues::Sint8(source)) => {
874                this.push(source[i]);
875            }
876            (VertexAttributeValues::Sint8(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
877            (VertexAttributeValues::Unorm8(this), VertexAttributeValues::Unorm8(source)) => {
878                this.push(source[i]);
879            }
880            (VertexAttributeValues::Unorm8(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
881            (VertexAttributeValues::Snorm8(this), VertexAttributeValues::Snorm8(source)) => {
882                this.push(source[i]);
883            }
884            (VertexAttributeValues::Snorm8(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
885            (VertexAttributeValues::Uint16(this), VertexAttributeValues::Uint16(source)) => {
886                this.push(source[i]);
887            }
888            (VertexAttributeValues::Uint16(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
889            (VertexAttributeValues::Sint16(this), VertexAttributeValues::Sint16(source)) => {
890                this.push(source[i]);
891            }
892            (VertexAttributeValues::Sint16(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
893            (VertexAttributeValues::Unorm16(this), VertexAttributeValues::Unorm16(source)) => {
894                this.push(source[i]);
895            }
896            (VertexAttributeValues::Unorm16(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
897            (VertexAttributeValues::Snorm16(this), VertexAttributeValues::Snorm16(source)) => {
898                this.push(source[i]);
899            }
900            (VertexAttributeValues::Snorm16(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
901            (VertexAttributeValues::Float16(this), VertexAttributeValues::Float16(source)) => {
902                this.push(source[i]);
903            }
904            (VertexAttributeValues::Float16(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
905            (VertexAttributeValues::Float16x2(this), VertexAttributeValues::Float16x2(source)) => {
906                this.push(source[i]);
907            }
908            (VertexAttributeValues::Float16x2(_), _) => {
909                {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values")
910            }
911            (VertexAttributeValues::Float16x4(this), VertexAttributeValues::Float16x4(source)) => {
912                this.push(source[i]);
913            }
914            (VertexAttributeValues::Float16x4(_), _) => {
915                {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values")
916            }
917            (VertexAttributeValues::Float64(this), VertexAttributeValues::Float64(source)) => {
918                this.push(source[i]);
919            }
920            (VertexAttributeValues::Float64(_), _) => {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values"),
921            (VertexAttributeValues::Float64x2(this), VertexAttributeValues::Float64x2(source)) => {
922                this.push(source[i]);
923            }
924            (VertexAttributeValues::Float64x2(_), _) => {
925                {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values")
926            }
927            (VertexAttributeValues::Float64x3(this), VertexAttributeValues::Float64x3(source)) => {
928                this.push(source[i]);
929            }
930            (VertexAttributeValues::Float64x3(_), _) => {
931                {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values")
932            }
933            (VertexAttributeValues::Float64x4(this), VertexAttributeValues::Float64x4(source)) => {
934                this.push(source[i]);
935            }
936            (VertexAttributeValues::Float64x4(_), _) => {
937                {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values")
938            }
939            (
940                VertexAttributeValues::Unorm10_10_10_2(this),
941                VertexAttributeValues::Unorm10_10_10_2(source),
942            ) => {
943                this.push(source[i]);
944            }
945            (VertexAttributeValues::Unorm10_10_10_2(_), _) => {
946                {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values")
947            }
948            (
949                VertexAttributeValues::Unorm8x4Bgra(this),
950                VertexAttributeValues::Unorm8x4Bgra(source),
951            ) => {
952                this.push(source[i]);
953            }
954            (VertexAttributeValues::Unorm8x4Bgra(_), _) => {
955                {
    ::core::panicking::panic_fmt(format_args!("Mismatched vertex attribute values"));
}panic!("Mismatched vertex attribute values")
956            }
957        }
958    }
959
960    #[expect(
961        clippy::match_same_arms,
962        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."
963    )]
964    pub(crate) fn shrink_to_fit(&mut self) {
965        match self {
966            VertexAttributeValues::Float32(v) => v.shrink_to_fit(),
967            VertexAttributeValues::Sint32(v) => v.shrink_to_fit(),
968            VertexAttributeValues::Uint32(v) => v.shrink_to_fit(),
969            VertexAttributeValues::Float32x2(v) => v.shrink_to_fit(),
970            VertexAttributeValues::Sint32x2(v) => v.shrink_to_fit(),
971            VertexAttributeValues::Uint32x2(v) => v.shrink_to_fit(),
972            VertexAttributeValues::Float32x3(v) => v.shrink_to_fit(),
973            VertexAttributeValues::Sint32x3(v) => v.shrink_to_fit(),
974            VertexAttributeValues::Uint32x3(v) => v.shrink_to_fit(),
975            VertexAttributeValues::Float32x4(v) => v.shrink_to_fit(),
976            VertexAttributeValues::Sint32x4(v) => v.shrink_to_fit(),
977            VertexAttributeValues::Uint32x4(v) => v.shrink_to_fit(),
978            VertexAttributeValues::Sint16x2(v) => v.shrink_to_fit(),
979            VertexAttributeValues::Snorm16x2(v) => v.shrink_to_fit(),
980            VertexAttributeValues::Uint16x2(v) => v.shrink_to_fit(),
981            VertexAttributeValues::Unorm16x2(v) => v.shrink_to_fit(),
982            VertexAttributeValues::Sint16x4(v) => v.shrink_to_fit(),
983            VertexAttributeValues::Snorm16x4(v) => v.shrink_to_fit(),
984            VertexAttributeValues::Uint16x4(v) => v.shrink_to_fit(),
985            VertexAttributeValues::Unorm16x4(v) => v.shrink_to_fit(),
986            VertexAttributeValues::Sint8x2(v) => v.shrink_to_fit(),
987            VertexAttributeValues::Snorm8x2(v) => v.shrink_to_fit(),
988            VertexAttributeValues::Uint8x2(v) => v.shrink_to_fit(),
989            VertexAttributeValues::Unorm8x2(v) => v.shrink_to_fit(),
990            VertexAttributeValues::Sint8x4(v) => v.shrink_to_fit(),
991            VertexAttributeValues::Snorm8x4(v) => v.shrink_to_fit(),
992            VertexAttributeValues::Uint8x4(v) => v.shrink_to_fit(),
993            VertexAttributeValues::Unorm8x4(v) => v.shrink_to_fit(),
994            VertexAttributeValues::Uint8(v) => v.shrink_to_fit(),
995            VertexAttributeValues::Sint8(v) => v.shrink_to_fit(),
996            VertexAttributeValues::Unorm8(v) => v.shrink_to_fit(),
997            VertexAttributeValues::Snorm8(v) => v.shrink_to_fit(),
998            VertexAttributeValues::Uint16(v) => v.shrink_to_fit(),
999            VertexAttributeValues::Sint16(v) => v.shrink_to_fit(),
1000            VertexAttributeValues::Unorm16(v) => v.shrink_to_fit(),
1001            VertexAttributeValues::Snorm16(v) => v.shrink_to_fit(),
1002            VertexAttributeValues::Float16(v) => v.shrink_to_fit(),
1003            VertexAttributeValues::Float16x2(v) => v.shrink_to_fit(),
1004            VertexAttributeValues::Float16x4(v) => v.shrink_to_fit(),
1005            VertexAttributeValues::Float64(v) => v.shrink_to_fit(),
1006            VertexAttributeValues::Float64x2(v) => v.shrink_to_fit(),
1007            VertexAttributeValues::Float64x3(v) => v.shrink_to_fit(),
1008            VertexAttributeValues::Float64x4(v) => v.shrink_to_fit(),
1009            VertexAttributeValues::Unorm10_10_10_2(v) => v.shrink_to_fit(),
1010            VertexAttributeValues::Unorm8x4Bgra(v) => v.shrink_to_fit(),
1011        }
1012    }
1013}
1014
1015impl From<&VertexAttributeValues> for VertexFormat {
1016    fn from(values: &VertexAttributeValues) -> Self {
1017        match values {
1018            VertexAttributeValues::Float32(_) => VertexFormat::Float32,
1019            VertexAttributeValues::Sint32(_) => VertexFormat::Sint32,
1020            VertexAttributeValues::Uint32(_) => VertexFormat::Uint32,
1021            VertexAttributeValues::Float32x2(_) => VertexFormat::Float32x2,
1022            VertexAttributeValues::Sint32x2(_) => VertexFormat::Sint32x2,
1023            VertexAttributeValues::Uint32x2(_) => VertexFormat::Uint32x2,
1024            VertexAttributeValues::Float32x3(_) => VertexFormat::Float32x3,
1025            VertexAttributeValues::Sint32x3(_) => VertexFormat::Sint32x3,
1026            VertexAttributeValues::Uint32x3(_) => VertexFormat::Uint32x3,
1027            VertexAttributeValues::Float32x4(_) => VertexFormat::Float32x4,
1028            VertexAttributeValues::Sint32x4(_) => VertexFormat::Sint32x4,
1029            VertexAttributeValues::Uint32x4(_) => VertexFormat::Uint32x4,
1030            VertexAttributeValues::Sint16x2(_) => VertexFormat::Sint16x2,
1031            VertexAttributeValues::Snorm16x2(_) => VertexFormat::Snorm16x2,
1032            VertexAttributeValues::Uint16x2(_) => VertexFormat::Uint16x2,
1033            VertexAttributeValues::Unorm16x2(_) => VertexFormat::Unorm16x2,
1034            VertexAttributeValues::Sint16x4(_) => VertexFormat::Sint16x4,
1035            VertexAttributeValues::Snorm16x4(_) => VertexFormat::Snorm16x4,
1036            VertexAttributeValues::Uint16x4(_) => VertexFormat::Uint16x4,
1037            VertexAttributeValues::Unorm16x4(_) => VertexFormat::Unorm16x4,
1038            VertexAttributeValues::Sint8x2(_) => VertexFormat::Sint8x2,
1039            VertexAttributeValues::Snorm8x2(_) => VertexFormat::Snorm8x2,
1040            VertexAttributeValues::Uint8x2(_) => VertexFormat::Uint8x2,
1041            VertexAttributeValues::Unorm8x2(_) => VertexFormat::Unorm8x2,
1042            VertexAttributeValues::Sint8x4(_) => VertexFormat::Sint8x4,
1043            VertexAttributeValues::Snorm8x4(_) => VertexFormat::Snorm8x4,
1044            VertexAttributeValues::Uint8x4(_) => VertexFormat::Uint8x4,
1045            VertexAttributeValues::Unorm8x4(_) => VertexFormat::Unorm8x4,
1046            VertexAttributeValues::Uint8(_) => VertexFormat::Uint8,
1047            VertexAttributeValues::Sint8(_) => VertexFormat::Sint8,
1048            VertexAttributeValues::Unorm8(_) => VertexFormat::Unorm8,
1049            VertexAttributeValues::Snorm8(_) => VertexFormat::Snorm8,
1050            VertexAttributeValues::Uint16(_) => VertexFormat::Uint16,
1051            VertexAttributeValues::Sint16(_) => VertexFormat::Sint16,
1052            VertexAttributeValues::Unorm16(_) => VertexFormat::Unorm16,
1053            VertexAttributeValues::Snorm16(_) => VertexFormat::Snorm16,
1054            VertexAttributeValues::Float16(_) => VertexFormat::Float16,
1055            VertexAttributeValues::Float16x2(_) => VertexFormat::Float16x2,
1056            VertexAttributeValues::Float16x4(_) => VertexFormat::Float16x4,
1057            VertexAttributeValues::Float64(_) => VertexFormat::Float64,
1058            VertexAttributeValues::Float64x2(_) => VertexFormat::Float64x2,
1059            VertexAttributeValues::Float64x3(_) => VertexFormat::Float64x3,
1060            VertexAttributeValues::Float64x4(_) => VertexFormat::Float64x4,
1061            VertexAttributeValues::Unorm10_10_10_2(_) => VertexFormat::Unorm10_10_10_2,
1062            VertexAttributeValues::Unorm8x4Bgra(_) => VertexFormat::Unorm8x4Bgra,
1063        }
1064    }
1065}
1066
1067/// Describes how the vertex buffer is interpreted.
1068#[derive(#[automatically_derived]
impl ::core::default::Default for VertexBufferLayout {
    #[inline]
    fn default() -> Self {
        Self {
            array_stride: ::core::default::Default::default(),
            step_mode: ::core::default::Default::default(),
            attributes: ::core::default::Default::default(),
        }
    }
}Default, #[automatically_derived]
impl ::core::clone::Clone for VertexBufferLayout {
    #[inline]
    fn clone(&self) -> Self {
        Self {
            array_stride: ::core::clone::Clone::clone(&self.array_stride),
            step_mode: ::core::clone::Clone::clone(&self.step_mode),
            attributes: ::core::clone::Clone::clone(&self.attributes),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for VertexBufferLayout {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "VertexBufferLayout", "array_stride", &self.array_stride,
            "step_mode", &self.step_mode, "attributes", &&self.attributes)
    }
}Debug, #[automatically_derived]
impl ::core::hash::Hash for VertexBufferLayout {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.array_stride, state);
        ::core::hash::Hash::hash(&self.step_mode, state);
        ::core::hash::Hash::hash(&self.attributes, state)
    }
}Hash, #[automatically_derived]
impl ::core::cmp::Eq for VertexBufferLayout {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<BufferAddress>;
        let _: ::core::cmp::AssertParamIsEq<VertexStepMode>;
        let _: ::core::cmp::AssertParamIsEq<Vec<VertexAttribute>>;
    }
}Eq, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for VertexBufferLayout { }
#[automatically_derived]
impl ::core::cmp::PartialEq for VertexBufferLayout {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        self.array_stride == other.array_stride &&
                self.step_mode == other.step_mode &&
            self.attributes == other.attributes
    }
}PartialEq)]
1069pub struct VertexBufferLayout {
1070    /// The stride, in bytes, between elements of this buffer.
1071    pub array_stride: BufferAddress,
1072    /// How often this vertex buffer is "stepped" forward.
1073    pub step_mode: VertexStepMode,
1074    /// The list of attributes which comprise a single vertex.
1075    pub attributes: Vec<VertexAttribute>,
1076}
1077
1078impl VertexBufferLayout {
1079    /// Creates a new densely packed [`VertexBufferLayout`] from an iterator of vertex formats.
1080    /// Iteration order determines the `shader_location` and `offset` of the [`VertexAttributes`](VertexAttribute).
1081    /// The first iterated item will have a `shader_location` and `offset` of zero.
1082    /// The `array_stride` is the sum of the size of the iterated [`VertexFormats`](VertexFormat) (in bytes).
1083    pub fn from_vertex_formats<T: IntoIterator<Item = VertexFormat>>(
1084        step_mode: VertexStepMode,
1085        vertex_formats: T,
1086    ) -> Self {
1087        let mut offset = 0;
1088        let mut attributes = Vec::new();
1089        for (shader_location, format) in vertex_formats.into_iter().enumerate() {
1090            attributes.push(VertexAttribute {
1091                format,
1092                offset,
1093                shader_location: shader_location as u32,
1094            });
1095            offset += format.size();
1096        }
1097
1098        VertexBufferLayout {
1099            array_stride: offset,
1100            step_mode,
1101            attributes,
1102        }
1103    }
1104
1105    /// Returns a [`VertexBufferLayout`] with the shader location of every attribute offset by
1106    /// `location`.
1107    pub fn offset_locations_by(mut self, location: u32) -> Self {
1108        self.attributes.iter_mut().for_each(|attr| {
1109            attr.shader_location += location;
1110        });
1111        self
1112    }
1113}
1114
1115/// Describes the layout of the mesh vertices in GPU memory.
1116///
1117/// At most one copy of a mesh vertex buffer layout ever exists in GPU memory at
1118/// once. Therefore, comparing these for equality requires only a single pointer
1119/// comparison, and this type's [`PartialEq`] and [`Hash`] implementations take
1120/// advantage of this. To that end, this type doesn't implement
1121/// [`bevy_derive::Deref`] or [`bevy_derive::DerefMut`] in order to reduce the
1122/// possibility of accidental deep comparisons, which would be needlessly
1123/// expensive.
1124#[derive(#[automatically_derived]
impl ::core::clone::Clone for MeshVertexBufferLayoutRef {
    #[inline]
    fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&self.0)) }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for MeshVertexBufferLayoutRef {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f,
            "MeshVertexBufferLayoutRef", &&self.0)
    }
}Debug)]
1125pub struct MeshVertexBufferLayoutRef(pub Arc<MeshVertexBufferLayout>);
1126
1127/// Stores the single copy of each mesh vertex buffer layout.
1128#[derive(#[automatically_derived]
impl ::core::clone::Clone for MeshVertexBufferLayouts {
    #[inline]
    fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&self.0)) }
}Clone, #[automatically_derived]
impl ::core::default::Default for MeshVertexBufferLayouts {
    #[inline]
    fn default() -> Self { Self(::core::default::Default::default()) }
}Default, impl bevy_ecs::component::Component for MeshVertexBufferLayouts where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    const STORAGE_TYPE: bevy_ecs::component::StorageType =
        bevy_ecs::component::StorageType::SparseSet;
    type Mutability = bevy_ecs::component::Mutable;
    fn register_required_components(_requiree:
            bevy_ecs::component::ComponentId,
        required_components:
            &mut bevy_ecs::component::RequiredComponentsRegistrator) {
        let resource_component_id =
            if let ::core::option::Option::Some(id) =
                    required_components.components_registrator().component_id::<MeshVertexBufferLayouts>()
                {
                id
            } else {
                required_components.components_registrator().register_component::<MeshVertexBufferLayouts>()
            };
        required_components.register_required::<bevy_ecs::resource::IsResource>(move
                ||
                bevy_ecs::resource::IsResource::new(resource_component_id));
    }
    fn clone_behavior() -> bevy_ecs::component::ComponentCloneBehavior {
        use bevy_ecs::component::{
            DefaultCloneBehaviorBase, DefaultCloneBehaviorViaClone,
        };
        (&&&bevy_ecs::component::DefaultCloneBehaviorSpecialization::<Self>::default()).default_clone_behavior()
    }
    fn relationship_accessor()
        ->
            ::core::option::Option<bevy_ecs::relationship::ComponentRelationshipAccessor<Self>> {
        ::core::option::Option::None
    }
}
impl bevy_ecs::resource::Resource for MeshVertexBufferLayouts where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {}Resource)]
1129pub struct MeshVertexBufferLayouts(HashSet<Arc<MeshVertexBufferLayout>>);
1130
1131impl MeshVertexBufferLayouts {
1132    /// Inserts a new mesh vertex buffer layout in the store and returns a
1133    /// reference to it, reusing the existing reference if this mesh vertex
1134    /// buffer layout was already in the store.
1135    pub fn insert(&mut self, layout: MeshVertexBufferLayout) -> MeshVertexBufferLayoutRef {
1136        // Because the special `PartialEq` and `Hash` implementations that
1137        // compare by pointer are on `MeshVertexBufferLayoutRef`, not on
1138        // `Arc<MeshVertexBufferLayout>`, this compares the mesh vertex buffer
1139        // structurally, not by pointer.
1140        MeshVertexBufferLayoutRef(
1141            self.0
1142                .get_or_insert_with(&layout, |layout| Arc::new(layout.clone()))
1143                .clone(),
1144        )
1145    }
1146}
1147
1148impl PartialEq for MeshVertexBufferLayoutRef {
1149    fn eq(&self, other: &Self) -> bool {
1150        Arc::ptr_eq(&self.0, &other.0)
1151    }
1152}
1153
1154impl Eq for MeshVertexBufferLayoutRef {}
1155
1156impl Hash for MeshVertexBufferLayoutRef {
1157    fn hash<H: Hasher>(&self, state: &mut H) {
1158        // Hash the address of the underlying data, so two layouts that share the same
1159        // `MeshVertexBufferLayout` will have the same hash.
1160        (Arc::as_ptr(&self.0) as usize).hash(state);
1161    }
1162}
1163
1164pub(crate) fn arr_f32_to_unorm8<const N: usize>(value: [f32; N]) -> [u8; N] {
1165    value.map(|v| (v.clamp(0.0, 1.0) * u8::MAX as f32).round() as u8)
1166}
1167
1168pub(crate) fn arr_f32_to_snorm8<const N: usize>(value: [f32; N]) -> [i8; N] {
1169    value.map(|v| (v.clamp(-1.0, 1.0) * i8::MAX as f32).round() as i8)
1170}
1171
1172pub(crate) fn arr_f32_to_unorm16<const N: usize>(value: [f32; N]) -> [u16; N] {
1173    value.map(|v| (v.clamp(0.0, 1.0) * u16::MAX as f32).round() as u16)
1174}
1175
1176pub(crate) fn arr_f32_to_snorm16<const N: usize>(value: [f32; N]) -> [i16; N] {
1177    value.map(|v| (v.clamp(-1.0, 1.0) * i16::MAX as f32).round() as i16)
1178}
1179
1180pub(crate) fn arr_f32_to_float16<const N: usize>(value: [f32; N]) -> [half::f16; N] {
1181    value.map(half::f16::from_f32)
1182}
1183
1184/// Encode normals or unit direction vectors as octahedral coordinates with range [-1, 1]. Use [`octahedral_decode_signed`] to decode.
1185pub fn octahedral_encode_signed(v: Vec3) -> Vec2 {
1186    let n = v / (v.x.abs() + v.y.abs() + v.z.abs());
1187    let octahedral_wrap = (1.0 - n.yx().abs())
1188        * Vec2::select(
1189            n.xy().cmpge(vec2(0.0, 0.0)),
1190            vec2(1.0, 1.0),
1191            vec2(-1.0, -1.0),
1192        );
1193    if n.z >= 0.0 {
1194        n.xy()
1195    } else {
1196        octahedral_wrap
1197    }
1198}
1199
1200/// Encode tangent vectors as octahedral coordinates with range [-1, 1]. The sign is encoded in y component. Use [`octahedral_decode_tangent`] to decode.
1201pub fn octahedral_encode_tangent(v: Vec3, sign: f32) -> Vec2 {
1202    // Bias to ensure that encoding as snorm16 preserves the sign.
1203    let bits = 16.;
1204    let bias = 1. / (bevy_math::ops::powf(2.0, bits - 1.) - 1.);
1205
1206    let mut n_xy = octahedral_encode_signed(v);
1207    // Map y to always be positive.
1208    n_xy.y = n_xy.y * 0.5 + 0.5;
1209    n_xy.y = n_xy.y.max(bias);
1210    // Encode the sign.
1211    n_xy.y *= sign.signum();
1212    n_xy
1213}
1214
1215/// Decode octahedral coordinates to normals or unit direction vectors. Input is [-1, 1].
1216pub fn octahedral_decode_signed(v: Vec2) -> Vec3 {
1217    let mut n = Vec3::new(v.x, v.y, 1.0 - v.x.abs() - v.y.abs());
1218    let t = (-n.z).clamp(0.0, 1.0);
1219    let w = Vec2::select(n.xy().cmpge(vec2(0.0, 0.0)), vec2(-t, -t), vec2(t, t));
1220    n = Vec3::new(n.x + w.x, n.y + w.y, n.z);
1221    n.normalize()
1222}
1223
1224/// Decode tangent vectors from octahedral coordinates and return the sign. Input is [-1, 1]. The y component should have been mapped to always be positive and then encoded the sign.
1225pub fn octahedral_decode_tangent(v: Vec2) -> (Vec3, f32) {
1226    let sign = v.y.signum();
1227    let mut f = v;
1228    f.y = f.y.abs();
1229    f.y = f.y * 2.0 - 1.0;
1230    (octahedral_decode_signed(f), sign)
1231}
1232
1233#[cfg(test)]
1234mod tests {
1235    use bevy_math::{vec2, vec3, Vec4Swizzles};
1236
1237    use crate::{
1238        octahedral_decode_signed, octahedral_decode_tangent,
1239        vertex::{octahedral_encode_signed, octahedral_encode_tangent},
1240    };
1241
1242    #[test]
1243    fn octahedral_encode_decode() {
1244        let vectors = [
1245            vec3(1.0, 2.0, 3.0).normalize().extend(1.0),
1246            vec3(1.0, 0.0, 0.0).extend(-1.0),
1247            vec3(0.0, 1.0, 0.0).extend(-1.0),
1248            vec3(0.0, 0.0, -1.0).extend(1.0),
1249            vec3(0.0, 0.0, -1.0).extend(-1.0),
1250        ];
1251        let expected_encoded_normals = [
1252            vec2(0.16666667, 0.33333334),
1253            vec2(1.0, 0.0),
1254            vec2(0.0, 1.0),
1255            vec2(1.0, 1.0),
1256            vec2(1.0, 1.0),
1257        ];
1258        let expected_encoded_tangents = [
1259            vec2(0.16666667, 0.6666667),
1260            vec2(1.0, -0.5),
1261            vec2(0.0, -1.0),
1262            vec2(1.0, 1.0),
1263            vec2(1.0, -1.0),
1264        ];
1265        for (i, &v) in vectors.iter().enumerate() {
1266            let encoded_normal = octahedral_encode_signed(v.xyz());
1267            let decoded_normal = octahedral_decode_signed(encoded_normal);
1268            assert!(encoded_normal.distance(expected_encoded_normals[i]) < 1e-8);
1269            assert!(decoded_normal.distance(vectors[i].xyz()) < 1e-7);
1270
1271            let encoded_tangent = octahedral_encode_tangent(v.xyz(), v.w);
1272            let (decoded_tangent, decoded_sign) = octahedral_decode_tangent(encoded_tangent);
1273            assert!(encoded_tangent.distance(expected_encoded_tangents[i]) < 1e-8);
1274            assert_eq!(v.w, decoded_sign);
1275            assert!(decoded_tangent.distance(v.xyz()) < 1e-7);
1276        }
1277    }
1278}