Skip to main content

bevy_mesh/
skinning.rs

1use crate::{Mesh, MeshVertexAttribute, VertexAttributeValues, VertexFormat};
2use bevy_asset::{AsAssetId, Asset, AssetId, Handle};
3use bevy_ecs::{
4    component::Component, entity::Entity, prelude::ReflectComponent, system::Query,
5    template::FromTemplate,
6};
7use bevy_math::{Affine3A, Mat4, Vec3, Vec3A};
8use bevy_reflect::prelude::*;
9use bevy_shape::{Aabb3d, BoundingVolume};
10use bevy_transform::components::GlobalTransform;
11use core::ops::Deref;
12use thiserror::Error;
13
14#[derive(impl bevy_ecs::component::Component for SkinnedMesh where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    const STORAGE_TYPE: bevy_ecs::component::StorageType =
        bevy_ecs::component::StorageType::Table;
    type Mutability = bevy_ecs::component::Mutable;
    fn register_required_components(_requiree:
            bevy_ecs::component::ComponentId,
        required_components:
            &mut bevy_ecs::component::RequiredComponentsRegistrator) {}
    fn clone_behavior() -> bevy_ecs::component::ComponentCloneBehavior {
        use bevy_ecs::component::{
            DefaultCloneBehaviorBase, DefaultCloneBehaviorViaClone,
        };
        (&&&bevy_ecs::component::DefaultCloneBehaviorSpecialization::<Self>::default()).default_clone_behavior()
    }
    fn map_entities<M: bevy_ecs::entity::EntityMapper>(this: &mut Self,
        mapper: &mut M) {
        use bevy_ecs::entity::MapEntities;
        this.joints.map_entities(mapper);
    }
    fn relationship_accessor()
        ->
            ::core::option::Option<bevy_ecs::relationship::ComponentRelationshipAccessor<Self>> {
        ::core::option::Option::None
    }
}Component, #[automatically_derived]impl ::core::fmt::Debug for SkinnedMesh {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "SkinnedMesh",
            "inverse_bindposes", &self.inverse_bindposes, "joints",
            &&self.joints)
    }
}Debug, #[automatically_derived]impl ::core::default::Default for SkinnedMesh {
    #[inline]
    fn default() -> Self {
        SkinnedMesh {
            inverse_bindposes: ::core::default::Default::default(),
            joints: ::core::default::Default::default(),
        }
    }
}Default, #[automatically_derived]impl ::core::clone::Clone for SkinnedMesh {
    #[inline]
    fn clone(&self) -> Self {
        SkinnedMesh {
            inverse_bindposes: ::core::clone::Clone::clone(&self.inverse_bindposes),
            joints: ::core::clone::Clone::clone(&self.joints),
        }
    }
}Clone, const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for SkinnedMesh where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert(<bevy_reflect::ReflectFromPtr as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.insert(<bevy_reflect::ReflectFromReflect as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.register_type_data_with::<ReflectComponent, Self,
                    _>(());
                registration.register_type_data_with::<ReflectDefault, Self,
                    _>(());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <Handle<SkinnedMeshInverseBindposes> as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <Vec<Entity> as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for SkinnedMesh where  {
            #[inline(never)]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(#[inline(never)] ||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<Handle<SkinnedMeshInverseBindposes>>("inverse_bindposes"),
                                                bevy_reflect::NamedField::new::<Vec<Entity>>("joints")]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for SkinnedMesh where  {
            fn type_path() -> &'static str {
                "bevy_mesh::skinning::SkinnedMesh"
            }
            fn short_type_path() -> &'static str { "SkinnedMesh" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("SkinnedMesh")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_mesh::skinning".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_mesh::skinning")
            }
        }
        impl bevy_reflect::Reflect for SkinnedMesh where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        #[allow(non_upper_case_globals)]
        const _: () =
            {
                static __INVENTORY: ::inventory::Node =
                    ::inventory::Node {
                        value: &{
                                bevy_reflect::__macro_exports::auto_register::AutomaticReflectRegistrations(<SkinnedMesh
                                        as
                                        bevy_reflect::__macro_exports::auto_register::RegisterForReflection>::__register)
                            },
                        next: ::inventory::__private::UnsafeCell::new(::inventory::__private::Option::None),
                    };
                #[link_section = ".text.startup"]
                unsafe extern "C" fn __ctor() {
                    unsafe {
                        ::inventory::ErasedNode::submit(__INVENTORY.value,
                            &__INVENTORY)
                    }
                }
                #[used]
                #[link_section = ".init_array"]
                static __CTOR: unsafe extern "C" fn() = __ctor;
            };
        impl bevy_reflect::structs::Struct for SkinnedMesh where  {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "inverse_bindposes" =>
                        ::core::option::Option::Some(&self.inverse_bindposes),
                    "joints" => ::core::option::Option::Some(&self.joints),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "inverse_bindposes" =>
                        ::core::option::Option::Some(&mut self.inverse_bindposes),
                    "joints" => ::core::option::Option::Some(&mut self.joints),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize =>
                        ::core::option::Option::Some(&self.inverse_bindposes),
                    1usize => ::core::option::Option::Some(&self.joints),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize =>
                        ::core::option::Option::Some(&mut self.inverse_bindposes),
                    1usize => ::core::option::Option::Some(&mut self.joints),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("inverse_bindposes"),
                    1usize => ::core::option::Option::Some("joints"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "inverse_bindposes" => ::core::option::Option::Some(0usize),
                    "joints" => ::core::option::Option::Some(1usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 2usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                ->
                    ::core::result::Result<bevy_reflect::structs::DynamicStruct,
                    bevy_reflect::ReflectCloneError> {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("inverse_bindposes",
                    bevy_reflect::PartialReflect::to_dynamic(&self.inverse_bindposes)?);
                dynamic.insert_boxed("joints",
                    bevy_reflect::PartialReflect::to_dynamic(&self.joints)?);
                ::core::result::Result::Ok(dynamic)
            }
        }
        impl bevy_reflect::PartialReflect for SkinnedMesh where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            fn debug(&self, f: &mut ::core::fmt::Formatter<'_>)
                -> ::core::fmt::Result {
                ::core::fmt::Debug::fmt(self, f)
            }
            #[inline]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(::core::clone::Clone::clone(self)))
            }
        }
        impl bevy_reflect::FromReflect for SkinnedMesh where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let mut __this =
                        <Self as ::core::default::Default>::default();
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <Handle<SkinnedMeshInverseBindposes> as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "inverse_bindposes")?))() {
                        __this.inverse_bindposes = __field;
                    }
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <Vec<Entity> as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "joints")?))() {
                        __this.joints = __field;
                    }
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect, impl bevy_ecs::template::FromTemplate for SkinnedMesh {
    type Template = SkinnedMeshTemplate;
}
impl ::core::marker::Unpin for SkinnedMesh where
    for<'a> [()]: bevy_ecs::template::SpecializeFromTemplate {}
#[allow(missing_docs)]
pub struct SkinnedMeshTemplate {
    pub inverse_bindposes: <Handle<SkinnedMeshInverseBindposes> as
    bevy_ecs::template::FromTemplate>::Template,
    pub joints: <Vec<Entity> as bevy_ecs::template::FromTemplate>::Template,
}
impl bevy_ecs::template::Template for SkinnedMeshTemplate {
    type Output = SkinnedMesh;
    fn build_template(&self,
        context: &mut bevy_ecs::template::TemplateContext)
        -> bevy_ecs::error::Result<Self::Output> {
        bevy_ecs::error::Result::Ok(SkinnedMesh {
                inverse_bindposes: self.inverse_bindposes.build_template(context)?,
                joints: self.joints.build_template(context)?,
            })
    }
    fn clone_template(&self) -> Self {
        Self {
            inverse_bindposes: bevy_ecs::template::Template::clone_template(&self.inverse_bindposes),
            joints: bevy_ecs::template::Template::clone_template(&self.joints),
        }
    }
}
impl ::core::default::Default for SkinnedMeshTemplate {
    fn default() -> Self {
        Self {
            inverse_bindposes: ::core::default::Default::default(),
            joints: ::core::default::Default::default(),
        }
    }
}FromTemplate)]
15#[reflect(Component, Default, Debug, Clone)]
16pub struct SkinnedMesh {
17    pub inverse_bindposes: Handle<SkinnedMeshInverseBindposes>,
18    #[entities]
19    pub joints: Vec<Entity>,
20}
21
22impl AsAssetId for SkinnedMesh {
23    type Asset = SkinnedMeshInverseBindposes;
24
25    // We implement this so that `AssetChanged` will work to pick up any changes
26    // to `SkinnedMeshInverseBindposes`.
27    fn as_asset_id(&self) -> AssetId<Self::Asset> {
28        self.inverse_bindposes.id()
29    }
30}
31
32#[derive(impl bevy_asset::Asset for SkinnedMeshInverseBindposes {}
impl bevy_asset::VisitAssetDependencies for SkinnedMeshInverseBindposes {
    fn visit_dependencies(&self,
        visit: &mut impl ::core::ops::FnMut(bevy_asset::UntypedAssetId)) {}
}Asset, const _: () =
    {
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for SkinnedMeshInverseBindposes where  {
            fn type_path() -> &'static str {
                "bevy_mesh::skinning::SkinnedMeshInverseBindposes"
            }
            fn short_type_path() -> &'static str {
                "SkinnedMeshInverseBindposes"
            }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("SkinnedMeshInverseBindposes")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_mesh::skinning".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_mesh::skinning")
            }
        }
    };TypePath, #[automatically_derived]impl ::core::fmt::Debug for
    SkinnedMeshInverseBindposes {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f,
            "SkinnedMeshInverseBindposes", &&self.0)
    }
}Debug)]
33pub struct SkinnedMeshInverseBindposes(Box<[Mat4]>);
34
35impl From<Vec<Mat4>> for SkinnedMeshInverseBindposes {
36    fn from(value: Vec<Mat4>) -> Self {
37        Self(value.into_boxed_slice())
38    }
39}
40
41impl Deref for SkinnedMeshInverseBindposes {
42    type Target = [Mat4];
43    fn deref(&self) -> &Self::Target {
44        &self.0
45    }
46}
47
48// The AABB of a joint. This is optimized for `transform_aabb` - center/size is
49// slightly faster than the min/max used by `bevy_math::Aabb3d`, and the vectors
50// don't benefit from alignment because they're broadcast loaded.
51#[derive(#[automatically_derived]impl ::core::marker::Copy for JointAabb { }Copy, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for JointAabb {
}
#[automatically_derived]impl ::core::clone::Clone for JointAabb {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<Vec3>;
        *self
    }
}Clone, #[automatically_derived]impl ::core::fmt::Debug for JointAabb {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "JointAabb",
            "center", &self.center, "half_size", &&self.half_size)
    }
}Debug, #[automatically_derived]impl ::core::marker::StructuralPartialEq for JointAabb
    {
}
#[automatically_derived]impl ::core::cmp::PartialEq for JointAabb {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        self.center == other.center && self.half_size == other.half_size
    }
}PartialEq, const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for JointAabb where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert(<bevy_reflect::ReflectFromPtr as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.insert(<bevy_reflect::ReflectFromReflect as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <Vec3 as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for JointAabb where  {
            #[inline(never)]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(#[inline(never)] ||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<Vec3>("center"),
                                                bevy_reflect::NamedField::new::<Vec3>("half_size")]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for JointAabb where  {
            fn type_path() -> &'static str {
                "bevy_mesh::skinning::JointAabb"
            }
            fn short_type_path() -> &'static str { "JointAabb" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("JointAabb")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_mesh::skinning".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_mesh::skinning")
            }
        }
        impl bevy_reflect::Reflect for JointAabb where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        #[allow(non_upper_case_globals)]
        const _: () =
            {
                static __INVENTORY: ::inventory::Node =
                    ::inventory::Node {
                        value: &{
                                bevy_reflect::__macro_exports::auto_register::AutomaticReflectRegistrations(<JointAabb
                                        as
                                        bevy_reflect::__macro_exports::auto_register::RegisterForReflection>::__register)
                            },
                        next: ::inventory::__private::UnsafeCell::new(::inventory::__private::Option::None),
                    };
                #[link_section = ".text.startup"]
                unsafe extern "C" fn __ctor() {
                    unsafe {
                        ::inventory::ErasedNode::submit(__INVENTORY.value,
                            &__INVENTORY)
                    }
                }
                #[used]
                #[link_section = ".init_array"]
                static __CTOR: unsafe extern "C" fn() = __ctor;
            };
        impl bevy_reflect::structs::Struct for JointAabb where  {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "center" => ::core::option::Option::Some(&self.center),
                    "half_size" =>
                        ::core::option::Option::Some(&self.half_size),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "center" => ::core::option::Option::Some(&mut self.center),
                    "half_size" =>
                        ::core::option::Option::Some(&mut self.half_size),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.center),
                    1usize => ::core::option::Option::Some(&self.half_size),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.center),
                    1usize => ::core::option::Option::Some(&mut self.half_size),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("center"),
                    1usize => ::core::option::Option::Some("half_size"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "center" => ::core::option::Option::Some(0usize),
                    "half_size" => ::core::option::Option::Some(1usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 2usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                ->
                    ::core::result::Result<bevy_reflect::structs::DynamicStruct,
                    bevy_reflect::ReflectCloneError> {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("center",
                    bevy_reflect::PartialReflect::to_dynamic(&self.center)?);
                dynamic.insert_boxed("half_size",
                    bevy_reflect::PartialReflect::to_dynamic(&self.half_size)?);
                ::core::result::Result::Ok(dynamic)
            }
        }
        impl bevy_reflect::PartialReflect for JointAabb where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {
                            center: <Vec3 as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.center)?,
                            half_size: <Vec3 as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.half_size)?,
                        }))
            }
        }
        impl bevy_reflect::FromReflect for JointAabb where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            center: <Vec3 as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "center")?)?,
                            half_size: <Vec3 as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "half_size")?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
52pub struct JointAabb {
53    pub center: Vec3,
54    pub half_size: Vec3,
55}
56
57impl JointAabb {
58    fn min(&self) -> Vec3 {
59        self.center - self.half_size
60    }
61
62    fn max(&self) -> Vec3 {
63        self.center + self.half_size
64    }
65}
66
67impl From<JointAabb> for Aabb3d {
68    fn from(value: JointAabb) -> Self {
69        Self {
70            min: value.min().into(),
71            max: value.max().into(),
72        }
73    }
74}
75
76impl From<Aabb3d> for JointAabb {
77    fn from(value: Aabb3d) -> Self {
78        Self {
79            center: value.center().into(),
80            half_size: value.half_size().into(),
81        }
82    }
83}
84
85/// Data that can be used to calculate the AABB of a skinned mesh.
86#[derive(#[automatically_derived]impl ::core::clone::Clone for SkinnedMeshBounds {
    #[inline]
    fn clone(&self) -> Self {
        SkinnedMeshBounds {
            aabbs: ::core::clone::Clone::clone(&self.aabbs),
            aabb_index_to_joint_index: ::core::clone::Clone::clone(&self.aabb_index_to_joint_index),
        }
    }
}Clone, #[automatically_derived]impl ::core::default::Default for SkinnedMeshBounds {
    #[inline]
    fn default() -> Self {
        SkinnedMeshBounds {
            aabbs: ::core::default::Default::default(),
            aabb_index_to_joint_index: ::core::default::Default::default(),
        }
    }
}Default, #[automatically_derived]impl ::core::fmt::Debug for SkinnedMeshBounds {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "SkinnedMeshBounds", "aabbs", &self.aabbs,
            "aabb_index_to_joint_index", &&self.aabb_index_to_joint_index)
    }
}Debug, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
    SkinnedMeshBounds {
}
#[automatically_derived]impl ::core::cmp::PartialEq for SkinnedMeshBounds {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        self.aabbs == other.aabbs &&
            self.aabb_index_to_joint_index == other.aabb_index_to_joint_index
    }
}PartialEq, const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for SkinnedMeshBounds where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert(<bevy_reflect::ReflectFromPtr as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.insert(<bevy_reflect::ReflectFromReflect as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <Vec<JointAabb> as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <Vec<JointIndex> as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for SkinnedMeshBounds where  {
            #[inline(never)]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(#[inline(never)] ||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<Vec<JointAabb>>("aabbs"),
                                                bevy_reflect::NamedField::new::<Vec<JointIndex>>("aabb_index_to_joint_index")]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for SkinnedMeshBounds where  {
            fn type_path() -> &'static str {
                "bevy_mesh::skinning::SkinnedMeshBounds"
            }
            fn short_type_path() -> &'static str { "SkinnedMeshBounds" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("SkinnedMeshBounds")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_mesh::skinning".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_mesh::skinning")
            }
        }
        impl bevy_reflect::Reflect for SkinnedMeshBounds where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        #[allow(non_upper_case_globals)]
        const _: () =
            {
                static __INVENTORY: ::inventory::Node =
                    ::inventory::Node {
                        value: &{
                                bevy_reflect::__macro_exports::auto_register::AutomaticReflectRegistrations(<SkinnedMeshBounds
                                        as
                                        bevy_reflect::__macro_exports::auto_register::RegisterForReflection>::__register)
                            },
                        next: ::inventory::__private::UnsafeCell::new(::inventory::__private::Option::None),
                    };
                #[link_section = ".text.startup"]
                unsafe extern "C" fn __ctor() {
                    unsafe {
                        ::inventory::ErasedNode::submit(__INVENTORY.value,
                            &__INVENTORY)
                    }
                }
                #[used]
                #[link_section = ".init_array"]
                static __CTOR: unsafe extern "C" fn() = __ctor;
            };
        impl bevy_reflect::structs::Struct for SkinnedMeshBounds where  {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "aabbs" => ::core::option::Option::Some(&self.aabbs),
                    "aabb_index_to_joint_index" =>
                        ::core::option::Option::Some(&self.aabb_index_to_joint_index),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "aabbs" => ::core::option::Option::Some(&mut self.aabbs),
                    "aabb_index_to_joint_index" =>
                        ::core::option::Option::Some(&mut self.aabb_index_to_joint_index),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.aabbs),
                    1usize =>
                        ::core::option::Option::Some(&self.aabb_index_to_joint_index),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.aabbs),
                    1usize =>
                        ::core::option::Option::Some(&mut self.aabb_index_to_joint_index),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("aabbs"),
                    1usize =>
                        ::core::option::Option::Some("aabb_index_to_joint_index"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "aabbs" => ::core::option::Option::Some(0usize),
                    "aabb_index_to_joint_index" =>
                        ::core::option::Option::Some(1usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 2usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                ->
                    ::core::result::Result<bevy_reflect::structs::DynamicStruct,
                    bevy_reflect::ReflectCloneError> {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("aabbs",
                    bevy_reflect::PartialReflect::to_dynamic(&self.aabbs)?);
                dynamic.insert_boxed("aabb_index_to_joint_index",
                    bevy_reflect::PartialReflect::to_dynamic(&self.aabb_index_to_joint_index)?);
                ::core::result::Result::Ok(dynamic)
            }
        }
        impl bevy_reflect::PartialReflect for SkinnedMeshBounds where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            #[inline]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(::core::clone::Clone::clone(self)))
            }
        }
        impl bevy_reflect::FromReflect for SkinnedMeshBounds where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            aabbs: <Vec<JointAabb> as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "aabbs")?)?,
                            aabb_index_to_joint_index: <Vec<JointIndex> as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "aabb_index_to_joint_index")?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
87#[reflect(Clone)]
88pub struct SkinnedMeshBounds {
89    // Model-space AABBs that enclose the vertices skinned to a joint. Some
90    // joints may not be skinned to any vertices, so not every joint has an
91    // AABB.
92    //
93    // `aabb_index_to_joint_index` maps from an `aabbs` index to a joint index,
94    // which corresponds to `Mesh::ATTRIBUTE_JOINT_INDEX` and `SkinnedMesh::joints`.
95    //
96    // These arrays could be a single `Vec<(JointAabb, JointIndex)>`, but that
97    // would waste two bytes due to alignment.
98    //
99    // TODO: If https://github.com/bevyengine/bevy/issues/11570 is fixed, `Vec<_>`
100    // can be changed to `Box<[_]>`.
101    pub aabbs: Vec<JointAabb>,
102    pub aabb_index_to_joint_index: Vec<JointIndex>,
103}
104
105#[derive(#[automatically_derived]impl ::core::marker::Copy for SkinnedMeshBoundsError {
}Copy, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for SkinnedMeshBoundsError {
}
#[automatically_derived]impl ::core::clone::Clone for SkinnedMeshBoundsError {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<MeshAttributeError>;
        *self
    }
}Clone, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
    SkinnedMeshBoundsError {
}
#[automatically_derived]impl ::core::cmp::PartialEq for SkinnedMeshBoundsError
    {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
                ::core::intrinsics::discriminant_value(other) &&
            match (self, other) {
                (Self::MeshAttributeError(__self_0),
                    Self::MeshAttributeError(__arg1_0)) => __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]impl ::core::fmt::Debug for SkinnedMeshBoundsError {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::NoSkinnedJoints =>
                ::core::fmt::Formatter::write_str(f, "NoSkinnedJoints"),
            Self::MeshAttributeError(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "MeshAttributeError", &__self_0),
        }
    }
}Debug, #[allow(unused_qualifications)]
#[automatically_derived]
impl ::thiserror::__private21::Error for SkinnedMeshBoundsError {
    fn source(&self)
        ->
            ::core::option::Option<&(dyn ::thiserror::__private21::Error +
            'static)> {
        use ::thiserror::__private21::AsDynError as _;

        #[allow(deprecated)]
        match self {
            SkinnedMeshBoundsError::NoSkinnedJoints { .. } =>
                ::core::option::Option::None,
            SkinnedMeshBoundsError::MeshAttributeError { 0: transparent } =>
                ::thiserror::__private21::Error::source(transparent.as_dyn_error()),
        }
    }
}
#[allow(unused_qualifications)]
#[automatically_derived]
impl ::core::fmt::Display for SkinnedMeshBoundsError {
    fn fmt(&self, __formatter: &mut ::core::fmt::Formatter)
        -> ::core::fmt::Result {

        #[allow(unused_variables, deprecated, clippy ::
        used_underscore_binding)]
        match self {
            SkinnedMeshBoundsError::NoSkinnedJoints {} =>
                __formatter.write_str("The mesh does not contain any joints that are skinned to vertices"),
            SkinnedMeshBoundsError::MeshAttributeError(_0) =>
                ::core::fmt::Display::fmt(_0, __formatter),
        }
    }
}
SkinnedMeshBoundsError
#[allow(clippy :: redundant_field_names)]
fn from(source: MeshAttributeError) -> Self {
    SkinnedMeshBoundsError::MeshAttributeError { 0: source }
}Error)]
106pub enum SkinnedMeshBoundsError {
107    #[error("The mesh does not contain any joints that are skinned to vertices")]
108    NoSkinnedJoints,
109    #[error(transparent)]
110    MeshAttributeError(#[from] MeshAttributeError),
111}
112
113impl SkinnedMeshBounds {
114    /// Create a `SkinnedMeshBounds` from a [`Mesh`].
115    ///
116    /// The mesh is expected to have position, joint index and joint weight
117    /// attributes. If any are missing then a [`MeshAttributeError`] is returned.
118    pub fn from_mesh(mesh: &Mesh) -> Result<SkinnedMeshBounds, SkinnedMeshBoundsError> {
119        let vertex_positions = expect_attribute_float32x3(mesh, Mesh::ATTRIBUTE_POSITION)?;
120        let vertex_influences = InfluenceIterator::new(mesh)?;
121
122        // Find the maximum joint index.
123        let Some(max_joint_index) = vertex_influences
124            .clone()
125            .map(|i| i.joint_index.0 as usize)
126            .reduce(Ord::max)
127        else {
128            return Ok(SkinnedMeshBounds::default());
129        };
130
131        // Create an AABB accumulator for each joint.
132        let mut accumulators: Box<[AabbAccumulator]> =
133            ::alloc::vec::from_elem(AabbAccumulator::new(), max_joint_index + 1)vec![AabbAccumulator::new(); max_joint_index + 1].into();
134
135        // Iterate over all vertex influences and add the vertex position to
136        // the influencing joint's AABB.
137        for influence in vertex_influences {
138            if let Some(&vertex_position) = vertex_positions.get(influence.vertex_index) {
139                accumulators[influence.joint_index.0 as usize]
140                    .add_point(Vec3A::from_array(vertex_position));
141            }
142        }
143
144        // Filter out joints with no AABB.
145        let joint_indices_and_aabbs = accumulators
146            .iter()
147            .enumerate()
148            .filter_map(|(joint_index, &accumulator)| {
149                accumulator.finish().map(|aabb| (joint_index, aabb))
150            })
151            .collect::<Vec<_>>();
152
153        if joint_indices_and_aabbs.is_empty() {
154            return Err(SkinnedMeshBoundsError::NoSkinnedJoints);
155        }
156
157        let aabbs = joint_indices_and_aabbs
158            .iter()
159            .map(|&(_, aabb)| JointAabb::from(aabb))
160            .collect::<Vec<_>>();
161
162        let aabb_index_to_joint_index = joint_indices_and_aabbs
163            .iter()
164            .map(|&(joint_index, _)| JointIndex(joint_index as u16))
165            .collect::<Vec<_>>();
166
167        {
    match (&aabbs.len(), &aabb_index_to_joint_index.len()) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    }
};assert_eq!(aabbs.len(), aabb_index_to_joint_index.len());
168
169        Ok(SkinnedMeshBounds {
170            aabbs,
171            aabb_index_to_joint_index,
172        })
173    }
174
175    pub fn iter(&self) -> impl Iterator<Item = (&JointIndex, &JointAabb)> {
176        self.aabb_index_to_joint_index.iter().zip(self.aabbs.iter())
177    }
178}
179
180#[derive(#[automatically_derived]impl ::core::marker::Copy for
    EntityAabbFromSkinnedMeshBoundsError {
}Copy, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for EntityAabbFromSkinnedMeshBoundsError {
}
#[automatically_derived]impl ::core::clone::Clone for
    EntityAabbFromSkinnedMeshBoundsError {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<JointIndex>;
        *self
    }
}Clone, #[automatically_derived]impl ::core::fmt::Debug for
    EntityAabbFromSkinnedMeshBoundsError {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::OutOfRangeJointIndex(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "OutOfRangeJointIndex", &__self_0),
            Self::MissingJointEntity =>
                ::core::fmt::Formatter::write_str(f, "MissingJointEntity"),
            Self::MissingSkinnedMeshBounds =>
                ::core::fmt::Formatter::write_str(f,
                    "MissingSkinnedMeshBounds"),
        }
    }
}Debug)]
181pub enum EntityAabbFromSkinnedMeshBoundsError {
182    OutOfRangeJointIndex(JointIndex),
183    MissingJointEntity,
184    MissingSkinnedMeshBounds,
185}
186
187/// Given the components of a skinned mesh entity, return an `Aabb3d` that
188/// encloses the skinned vertices of the mesh.
189pub fn entity_aabb_from_skinned_mesh_bounds(
190    joint_entities: &Query<&GlobalTransform>,
191    mesh: &Mesh,
192    skinned_mesh: &SkinnedMesh,
193    skinned_mesh_inverse_bindposes: &SkinnedMeshInverseBindposes,
194    world_from_entity: Option<&GlobalTransform>,
195) -> Result<Aabb3d, EntityAabbFromSkinnedMeshBoundsError> {
196    let Some(skinned_mesh_bounds) = mesh.skinned_mesh_bounds() else {
197        return Err(EntityAabbFromSkinnedMeshBoundsError::MissingSkinnedMeshBounds);
198    };
199
200    let mut accumulator = AabbAccumulator::new();
201
202    // For each model-space joint AABB, transform it to world-space and add it
203    // to the accumulator.
204    for (&joint_index, &modelspace_joint_aabb) in skinned_mesh_bounds.iter() {
205        let Some(joint_from_model) = skinned_mesh_inverse_bindposes
206            .get(joint_index.0 as usize)
207            .map(|&m| Affine3A::from_mat4(m))
208        else {
209            return Err(EntityAabbFromSkinnedMeshBoundsError::OutOfRangeJointIndex(
210                joint_index,
211            ));
212        };
213
214        let Some(&joint_entity) = skinned_mesh.joints.get(joint_index.0 as usize) else {
215            return Err(EntityAabbFromSkinnedMeshBoundsError::OutOfRangeJointIndex(
216                joint_index,
217            ));
218        };
219
220        let Ok(&world_from_joint) = joint_entities.get(joint_entity) else {
221            return Err(EntityAabbFromSkinnedMeshBoundsError::MissingJointEntity);
222        };
223
224        let world_from_model = world_from_joint.affine() * joint_from_model;
225        let worldspace_joint_aabb = transform_aabb(modelspace_joint_aabb, world_from_model);
226
227        accumulator.add_aabb(worldspace_joint_aabb);
228    }
229
230    let Some(worldspace_entity_aabb) = accumulator.finish() else {
231        return Err(EntityAabbFromSkinnedMeshBoundsError::MissingJointEntity);
232    };
233
234    // If the entity has a transform, move the AABB from world-space to entity-space.
235    if let Some(world_from_entity) = world_from_entity {
236        let entityspace_entity_aabb = transform_aabb(
237            worldspace_entity_aabb.into(),
238            world_from_entity.affine().inverse(),
239        );
240
241        Ok(entityspace_entity_aabb)
242    } else {
243        Ok(worldspace_entity_aabb)
244    }
245}
246
247// Return the smallest `Aabb3d` that encloses the transformed `JointAabb`.
248//
249// Algorithm from "Transforming Axis-Aligned Bounding Boxes", James Arvo, Graphics Gems (1990).
250#[inline]
251fn transform_aabb(input: JointAabb, transform: Affine3A) -> Aabb3d {
252    let mx = transform.matrix3.x_axis;
253    let my = transform.matrix3.y_axis;
254    let mz = transform.matrix3.z_axis;
255    let mt = transform.translation;
256
257    let cx = Vec3A::splat(input.center.x);
258    let cy = Vec3A::splat(input.center.y);
259    let cz = Vec3A::splat(input.center.z);
260
261    let sx = Vec3A::splat(input.half_size.x);
262    let sy = Vec3A::splat(input.half_size.y);
263    let sz = Vec3A::splat(input.half_size.z);
264
265    // Transform the center.
266    let tc = (mx * cx) + (my * cy) + (mz * cz) + mt;
267
268    // Calculate a size that encloses the transformed size.
269    let ts = (mx.abs() * sx) + (my.abs() * sy) + (mz.abs() * sz);
270
271    let min = tc - ts;
272    let max = tc + ts;
273
274    Aabb3d { min, max }
275}
276
277// Helper for efficiently accumulating an enclosing AABB from a set of points or
278// other AABBs. Intended for cases where the size of the set is not known in
279// advance and might be zero.
280//
281// ```
282// let a = AabbAccumulator::new();
283//
284// a.add_point(point); // Add a `Vec3A`.
285// a.add_aabb(aabb); // Add an `Aabb3d`.
286//
287// // Returns `Some(Aabb3d)` if at least one thing was added.
288// let result = a.finish();
289// ```
290//
291// For alternatives, see [`Aabb3d::from_point_clound`](`bevy_shape::bounded3d::Aabb3d::from_point_cloud`)
292// and [`BoundingVolume::merge`](`bevy_shape::BoundingVolume::merge`).
293#[derive(#[automatically_derived]impl ::core::marker::Copy for AabbAccumulator { }Copy, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for AabbAccumulator {
}
#[automatically_derived]impl ::core::clone::Clone for AabbAccumulator {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<Vec3A>;
        *self
    }
}Clone)]
294struct AabbAccumulator {
295    min: Vec3A,
296    max: Vec3A,
297}
298
299impl AabbAccumulator {
300    fn new() -> Self {
301        // Initialize in such a way that adds can be branchless but `finish` can
302        // still detect if nothing was added. The initial state has `min > max`,
303        // but the first add will make `min <= max`.
304        Self {
305            min: Vec3A::MAX,
306            max: Vec3A::MIN,
307        }
308    }
309
310    fn add_aabb(&mut self, aabb: Aabb3d) {
311        self.min = self.min.min(aabb.min);
312        self.max = self.max.max(aabb.max);
313    }
314
315    fn add_point(&mut self, position: Vec3A) {
316        self.min = self.min.min(position);
317        self.max = self.max.max(position);
318    }
319
320    /// Returns the enclosing AABB if at least one thing was added, otherwise `None`.
321    fn finish(self) -> Option<Aabb3d> {
322        if self.min.cmpgt(self.max).any() {
323            None
324        } else {
325            Some(Aabb3d {
326                min: self.min,
327                max: self.max,
328            })
329        }
330    }
331}
332
333// An index that corresponds to `Mesh::ATTRIBUTE_JOINT_INDEX` and `SkinnedMesh::joints`.
334#[derive(#[automatically_derived]impl ::core::marker::Copy for JointIndex { }Copy, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for JointIndex {
}
#[automatically_derived]impl ::core::clone::Clone for JointIndex {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<u16>;
        *self
    }
}Clone, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
    JointIndex {
}
#[automatically_derived]impl ::core::cmp::PartialEq for JointIndex {
    #[inline]
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]impl ::core::fmt::Debug for JointIndex {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "JointIndex",
            &&self.0)
    }
}Debug, const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for JointIndex where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert(<bevy_reflect::ReflectFromPtr as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.insert(<bevy_reflect::ReflectFromReflect as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <u16 as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for JointIndex where  {
            #[inline(never)]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(#[inline(never)] ||
                        {
                            bevy_reflect::TypeInfo::TupleStruct(bevy_reflect::tuple_struct::TupleStructInfo::new::<Self>(&[bevy_reflect::UnnamedField::new::<u16>(0usize)]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for JointIndex where  {
            fn type_path() -> &'static str {
                "bevy_mesh::skinning::JointIndex"
            }
            fn short_type_path() -> &'static str { "JointIndex" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("JointIndex")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_mesh::skinning".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_mesh::skinning")
            }
        }
        impl bevy_reflect::Reflect for JointIndex where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        #[allow(non_upper_case_globals)]
        const _: () =
            {
                static __INVENTORY: ::inventory::Node =
                    ::inventory::Node {
                        value: &{
                                bevy_reflect::__macro_exports::auto_register::AutomaticReflectRegistrations(<JointIndex
                                        as
                                        bevy_reflect::__macro_exports::auto_register::RegisterForReflection>::__register)
                            },
                        next: ::inventory::__private::UnsafeCell::new(::inventory::__private::Option::None),
                    };
                #[link_section = ".text.startup"]
                unsafe extern "C" fn __ctor() {
                    unsafe {
                        ::inventory::ErasedNode::submit(__INVENTORY.value,
                            &__INVENTORY)
                    }
                }
                #[used]
                #[link_section = ".init_array"]
                static __CTOR: unsafe extern "C" fn() = __ctor;
            };
        impl bevy_reflect::tuple_struct::TupleStruct for JointIndex where  {
            fn field(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.0),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.0),
                    _ => ::core::option::Option::None,
                }
            }
            #[inline]
            fn field_len(&self) -> usize { 1usize }
            #[inline]
            fn iter_fields(&self)
                -> bevy_reflect::tuple_struct::TupleStructFieldIter {
                bevy_reflect::tuple_struct::TupleStructFieldIter::new(self)
            }
            fn to_dynamic_tuple_struct(&self)
                ->
                    ::core::result::Result<bevy_reflect::tuple_struct::DynamicTupleStruct,
                    bevy_reflect::ReflectCloneError> {
                let mut dynamic:
                        bevy_reflect::tuple_struct::DynamicTupleStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed(bevy_reflect::PartialReflect::to_dynamic(&self.0)?);
                ::core::result::Result::Ok(dynamic)
            }
        }
        impl bevy_reflect::PartialReflect for JointIndex where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::TupleStruct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (i, value) in
                        ::core::iter::Iterator::enumerate(bevy_reflect::tuple_struct::TupleStruct::iter_fields(struct_value))
                        {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::tuple_struct::TupleStruct::field_mut(self, i)
                            {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::TupleStruct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::TupleStruct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::TupleStruct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::TupleStruct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::TupleStruct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::tuple_struct::tuple_struct_partial_eq)(self,
                    value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::tuple_struct::tuple_struct_partial_cmp)(self,
                    value)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {
                            0: <u16 as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.0)?,
                        }))
            }
        }
        impl bevy_reflect::FromReflect for JointIndex where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::TupleStruct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            0: <u16 as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::tuple_struct::TupleStruct::field(__ref_struct,
                                            0)?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
335pub struct JointIndex(pub u16);
336
337/// A single vertex influence. Used by [`InfluenceIterator`].
338#[derive(#[automatically_derived]impl ::core::marker::Copy for Influence { }Copy, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for Influence {
}
#[automatically_derived]impl ::core::clone::Clone for Influence {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<usize>;
        let _: ::core::clone::AssertParamIsClone<JointIndex>;
        let _: ::core::clone::AssertParamIsClone<f32>;
        *self
    }
}Clone, #[automatically_derived]impl ::core::marker::StructuralPartialEq for Influence
    {
}
#[automatically_derived]impl ::core::cmp::PartialEq for Influence {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        self.joint_weight == other.joint_weight &&
                self.vertex_index == other.vertex_index &&
            self.joint_index == other.joint_index
    }
}PartialEq, #[automatically_derived]impl ::core::fmt::Debug for Influence {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "Influence",
            "vertex_index", &self.vertex_index, "joint_index",
            &self.joint_index, "joint_weight", &&self.joint_weight)
    }
}Debug)]
339pub struct Influence {
340    pub vertex_index: usize,
341    pub joint_index: JointIndex,
342    pub joint_weight: f32,
343}
344
345/// Iterator over all vertex influences with non-zero weight.
346#[derive(#[automatically_derived]impl<'a> ::core::clone::Clone for
    InfluenceIterator<'a> {
    #[inline]
    fn clone(&self) -> Self {
        InfluenceIterator {
            vertex_count: ::core::clone::Clone::clone(&self.vertex_count),
            joint_indices: ::core::clone::Clone::clone(&self.joint_indices),
            joint_weights: ::core::clone::Clone::clone(&self.joint_weights),
            vertex_index: ::core::clone::Clone::clone(&self.vertex_index),
            influence_index: ::core::clone::Clone::clone(&self.influence_index),
        }
    }
}Clone, #[automatically_derived]impl<'a> ::core::fmt::Debug for InfluenceIterator<'a>
    {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field5_finish(f,
            "InfluenceIterator", "vertex_count", &self.vertex_count,
            "joint_indices", &self.joint_indices, "joint_weights",
            &self.joint_weights, "vertex_index", &self.vertex_index,
            "influence_index", &&self.influence_index)
    }
}Debug)]
347pub struct InfluenceIterator<'a> {
348    vertex_count: usize,
349    joint_indices: &'a [[u16; 4]],
350    joint_weights: &'a [[f32; 4]],
351    vertex_index: usize,
352    influence_index: usize,
353}
354
355impl<'a> InfluenceIterator<'a> {
356    pub fn new(mesh: &'a Mesh) -> Result<Self, MeshAttributeError> {
357        let joint_indices = expect_attribute_uint16x4(mesh, Mesh::ATTRIBUTE_JOINT_INDEX)?;
358        let joint_weights = expect_attribute_float32x4(mesh, Mesh::ATTRIBUTE_JOINT_WEIGHT)?;
359
360        Ok(InfluenceIterator {
361            vertex_count: joint_indices.len().min(joint_weights.len()),
362            joint_indices,
363            joint_weights,
364            vertex_index: 0,
365            influence_index: 0,
366        })
367    }
368
369    // `Mesh` only supports four influences, so we can make this const for
370    // simplicity. If `Mesh` gains support for variable influences then this
371    // will become a variable.
372    const MAX_INFLUENCES: usize = 4;
373}
374
375impl Iterator for InfluenceIterator<'_> {
376    type Item = Influence;
377
378    fn next(&mut self) -> Option<Influence> {
379        loop {
380            if !(self.influence_index <= Self::MAX_INFLUENCES) {
    ::core::panicking::panic("assertion failed: self.influence_index <= Self::MAX_INFLUENCES")
};assert!(self.influence_index <= Self::MAX_INFLUENCES);
381            if !(self.vertex_index <= self.vertex_count) {
    ::core::panicking::panic("assertion failed: self.vertex_index <= self.vertex_count")
};assert!(self.vertex_index <= self.vertex_count);
382
383            if self.influence_index >= Self::MAX_INFLUENCES {
384                self.influence_index = 0;
385                self.vertex_index += 1;
386            }
387
388            if self.vertex_index >= self.vertex_count {
389                return None;
390            }
391
392            let joint_index = self.joint_indices[self.vertex_index][self.influence_index];
393            let joint_weight = self.joint_weights[self.vertex_index][self.influence_index];
394
395            self.influence_index += 1;
396
397            if joint_weight > 0.0 {
398                return Some(Influence {
399                    vertex_index: self.vertex_index,
400                    joint_index: JointIndex(joint_index),
401                    joint_weight,
402                });
403            }
404        }
405    }
406}
407
408/// Generic error for when a mesh was expected to have a certain attribute with
409/// a certain format.
410#[derive(#[automatically_derived]impl ::core::marker::Copy for MeshAttributeError { }Copy, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for MeshAttributeError {
}
#[automatically_derived]impl ::core::clone::Clone for MeshAttributeError {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<&'static str>;
        let _: ::core::clone::AssertParamIsClone<&'static str>;
        let _: ::core::clone::AssertParamIsClone<VertexFormat>;
        *self
    }
}Clone, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
    MeshAttributeError {
}
#[automatically_derived]impl ::core::cmp::PartialEq for MeshAttributeError {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
                ::core::intrinsics::discriminant_value(other) &&
            match (self, other) {
                (Self::MissingAttribute(__self_0),
                    Self::MissingAttribute(__arg1_0)) => __self_0 == __arg1_0,
                (Self::UnexpectedFormat(__self_0, __self_1),
                    Self::UnexpectedFormat(__arg1_0, __arg1_1)) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]impl ::core::fmt::Debug for MeshAttributeError {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::MissingAttribute(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "MissingAttribute", &__self_0),
            Self::UnexpectedFormat(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f,
                    "UnexpectedFormat", __self_0, &__self_1),
        }
    }
}Debug, #[allow(unused_qualifications)]
#[automatically_derived]
impl ::thiserror::__private21::Error for MeshAttributeError { }
#[allow(unused_qualifications)]
#[automatically_derived]
impl ::core::fmt::Display for MeshAttributeError {
    fn fmt(&self, __formatter: &mut ::core::fmt::Formatter)
        -> ::core::fmt::Result {
        use ::thiserror::__private21::AsDisplay as _;

        #[allow(unused_variables, deprecated, clippy ::
        used_underscore_binding)]
        match self {
            MeshAttributeError::MissingAttribute(_0) =>
                match (_0.as_display(),) {
                    (__display0,) =>
                        __formatter.write_fmt(format_args!("Missing attribute \"{0}\"",
                                __display0)),
                },
            MeshAttributeError::UnexpectedFormat(_0, _1) =>
                match (_0.as_display(), _1) {
                    (__display0, __field1) =>
                        __formatter.write_fmt(format_args!("Attribute \"{0}\" has unexpected format {1:?}",
                                __display0, __field1)),
                },
        }
    }
}Error)]
411pub enum MeshAttributeError {
412    #[error("Missing attribute \"{0}\"")]
413    MissingAttribute(&'static str),
414    #[error("Attribute \"{0}\" has unexpected format {1:?}")]
415    UnexpectedFormat(&'static str, VertexFormat),
416}
417
418// Implements a function that returns a mesh attribute's data or `MeshAttributeError`.
419//
420// ```
421// impl_expect_attribute!(expect_attribute_float32x3, Float32x3, [f32; 3]);
422//
423// let positions: Vec<[f32; 3]> = expect_attribute_float32x3(mesh, Mesh::ATTRIBUTE_POSITION)?;
424// ```
425macro_rules! impl_expect_attribute {
426    ($name:ident, $value_type:ident, $output_type:ty) => {
427        fn $name<'a>(
428            mesh: &'a Mesh,
429            attribute: MeshVertexAttribute,
430        ) -> Result<&'a Vec<$output_type>, MeshAttributeError> {
431            match mesh.attribute(attribute) {
432                Some(VertexAttributeValues::$value_type(v)) => Ok(v),
433                Some(v) => {
434                    return Err(MeshAttributeError::UnexpectedFormat(
435                        attribute.name,
436                        v.into(),
437                    ))
438                }
439                None => return Err(MeshAttributeError::MissingAttribute(attribute.name)),
440            }
441        }
442    };
443}
444
445fn expect_attribute_float32x3<'a>(mesh: &'a Mesh,
    attribute: MeshVertexAttribute)
    -> Result<&'a Vec<[f32; 3]>, MeshAttributeError> {
    match mesh.attribute(attribute) {
        Some(VertexAttributeValues::Float32x3(v)) => Ok(v),
        Some(v) => {
            return Err(MeshAttributeError::UnexpectedFormat(attribute.name,
                        v.into()))
        }
        None =>
            return Err(MeshAttributeError::MissingAttribute(attribute.name)),
    }
}impl_expect_attribute!(expect_attribute_float32x3, Float32x3, [f32; 3]);
446fn expect_attribute_float32x4<'a>(mesh: &'a Mesh,
    attribute: MeshVertexAttribute)
    -> Result<&'a Vec<[f32; 4]>, MeshAttributeError> {
    match mesh.attribute(attribute) {
        Some(VertexAttributeValues::Float32x4(v)) => Ok(v),
        Some(v) => {
            return Err(MeshAttributeError::UnexpectedFormat(attribute.name,
                        v.into()))
        }
        None =>
            return Err(MeshAttributeError::MissingAttribute(attribute.name)),
    }
}impl_expect_attribute!(expect_attribute_float32x4, Float32x4, [f32; 4]);
447fn expect_attribute_uint16x4<'a>(mesh: &'a Mesh,
    attribute: MeshVertexAttribute)
    -> Result<&'a Vec<[u16; 4]>, MeshAttributeError> {
    match mesh.attribute(attribute) {
        Some(VertexAttributeValues::Uint16x4(v)) => Ok(v),
        Some(v) => {
            return Err(MeshAttributeError::UnexpectedFormat(attribute.name,
                        v.into()))
        }
        None =>
            return Err(MeshAttributeError::MissingAttribute(attribute.name)),
    }
}impl_expect_attribute!(expect_attribute_uint16x4, Uint16x4, [u16; 4]);
448
449#[cfg(test)]
450mod tests {
451    use super::*;
452    use approx::assert_abs_diff_eq;
453    use bevy_asset::RenderAssetUsages;
454    use bevy_math::{vec3, vec3a};
455    use bevy_shape::BoundingVolume;
456
457    #[test]
458    fn aabb_accumulator() {
459        assert_eq!(AabbAccumulator::new().finish(), None);
460
461        let nice_aabbs = &[
462            Aabb3d {
463                min: vec3a(1.0, 2.0, 3.0),
464                max: vec3a(5.0, 4.0, 3.0),
465            },
466            Aabb3d {
467                min: vec3a(-99.0, 2.0, 3.0),
468                max: vec3a(5.0, 4.0, 3.0),
469            },
470            Aabb3d {
471                min: vec3a(1.0, 2.0, 3.0),
472                max: vec3a(5.0, 99.0, 3.0),
473            },
474        ];
475
476        let naughty_aabbs = &[
477            Aabb3d {
478                min: Vec3A::MIN,
479                max: Vec3A::MAX,
480            },
481            Aabb3d {
482                min: Vec3A::MIN,
483                max: Vec3A::MIN,
484            },
485            Aabb3d {
486                min: Vec3A::MAX,
487                max: Vec3A::MAX,
488            },
489        ];
490
491        for aabbs in [nice_aabbs, naughty_aabbs] {
492            for &aabb in aabbs {
493                let point = aabb.min;
494
495                let mut one_aabb = AabbAccumulator::new();
496                let mut one_point = AabbAccumulator::new();
497
498                one_aabb.add_aabb(aabb);
499                one_point.add_point(point);
500
501                assert_eq!(one_aabb.finish(), Some(aabb));
502                assert_eq!(
503                    one_point.finish(),
504                    Some(Aabb3d {
505                        min: point,
506                        max: point
507                    })
508                );
509            }
510
511            {
512                let mut multiple_aabbs = AabbAccumulator::new();
513                let mut multiple_points = AabbAccumulator::new();
514
515                for &aabb in aabbs {
516                    multiple_aabbs.add_aabb(aabb);
517                    multiple_points.add_point(aabb.min);
518                    multiple_points.add_point(aabb.max);
519                }
520
521                let expected = aabbs.iter().cloned().reduce(|l, r| l.merge(&r));
522
523                assert_eq!(multiple_aabbs.finish(), expected);
524                assert_eq!(multiple_points.finish(), expected);
525            }
526        }
527    }
528
529    #[test]
530    fn influence_iterator() {
531        let mesh = Mesh::new(
532            wgpu_types::PrimitiveTopology::TriangleList,
533            RenderAssetUsages::default(),
534        );
535
536        assert_eq!(
537            InfluenceIterator::new(&mesh).err(),
538            Some(MeshAttributeError::MissingAttribute(
539                Mesh::ATTRIBUTE_JOINT_INDEX.name
540            ))
541        );
542
543        let mesh = mesh.with_inserted_attribute(
544            Mesh::ATTRIBUTE_JOINT_INDEX,
545            VertexAttributeValues::Uint16x4(vec![
546                [1, 0, 0, 0],
547                [0, 2, 0, 0],
548                [0, 0, 3, 0],
549                [0, 0, 0, 4],
550                [1, 2, 0, 0],
551                [3, 4, 5, 0],
552                [6, 7, 8, 9],
553            ]),
554        );
555
556        assert_eq!(
557            InfluenceIterator::new(&mesh).err(),
558            Some(MeshAttributeError::MissingAttribute(
559                Mesh::ATTRIBUTE_JOINT_WEIGHT.name
560            ))
561        );
562
563        let mesh = mesh.with_inserted_attribute(
564            Mesh::ATTRIBUTE_JOINT_WEIGHT,
565            VertexAttributeValues::Float32x4(vec![
566                [1.0, 0.0, 0.0, 0.0],
567                [0.0, 1.0, 0.0, 0.0],
568                [0.0, 0.0, 1.0, 0.0],
569                [0.0, 0.0, 0.0, 1.0],
570                [0.1, 0.9, 0.0, 0.0],
571                [0.1, 0.2, 0.7, 0.0],
572                [0.1, 0.2, 0.4, 0.3],
573            ]),
574        );
575
576        let expected = &[
577            Influence {
578                vertex_index: 0,
579                joint_index: JointIndex(1),
580                joint_weight: 1.0,
581            },
582            Influence {
583                vertex_index: 1,
584                joint_index: JointIndex(2),
585                joint_weight: 1.0,
586            },
587            Influence {
588                vertex_index: 2,
589                joint_index: JointIndex(3),
590                joint_weight: 1.0,
591            },
592            Influence {
593                vertex_index: 3,
594                joint_index: JointIndex(4),
595                joint_weight: 1.0,
596            },
597            Influence {
598                vertex_index: 4,
599                joint_index: JointIndex(1),
600                joint_weight: 0.1,
601            },
602            Influence {
603                vertex_index: 4,
604                joint_index: JointIndex(2),
605                joint_weight: 0.9,
606            },
607            Influence {
608                vertex_index: 5,
609                joint_index: JointIndex(3),
610                joint_weight: 0.1,
611            },
612            Influence {
613                vertex_index: 5,
614                joint_index: JointIndex(4),
615                joint_weight: 0.2,
616            },
617            Influence {
618                vertex_index: 5,
619                joint_index: JointIndex(5),
620                joint_weight: 0.7,
621            },
622            Influence {
623                vertex_index: 6,
624                joint_index: JointIndex(6),
625                joint_weight: 0.1,
626            },
627            Influence {
628                vertex_index: 6,
629                joint_index: JointIndex(7),
630                joint_weight: 0.2,
631            },
632            Influence {
633                vertex_index: 6,
634                joint_index: JointIndex(8),
635                joint_weight: 0.4,
636            },
637            Influence {
638                vertex_index: 6,
639                joint_index: JointIndex(9),
640                joint_weight: 0.3,
641            },
642        ];
643
644        assert_eq!(
645            InfluenceIterator::new(&mesh).unwrap().collect::<Vec<_>>(),
646            expected
647        );
648    }
649
650    fn aabb_assert_eq(a: Aabb3d, b: Aabb3d) {
651        assert_abs_diff_eq!(a.min.x, b.min.x);
652        assert_abs_diff_eq!(a.min.y, b.min.y);
653        assert_abs_diff_eq!(a.min.z, b.min.z);
654        assert_abs_diff_eq!(a.max.x, b.max.x);
655        assert_abs_diff_eq!(a.max.y, b.max.y);
656        assert_abs_diff_eq!(a.max.z, b.max.z);
657    }
658
659    // Like `transform_aabb`, but uses the naive method of transforming each corner.
660    fn naive_transform_aabb(input: JointAabb, transform: Affine3A) -> Aabb3d {
661        let minmax = [input.min(), input.max()];
662
663        let mut accumulator = AabbAccumulator::new();
664
665        for i in 0..8 {
666            let corner = vec3(
667                minmax[i & 1].x,
668                minmax[(i >> 1) & 1].y,
669                minmax[(i >> 2) & 1].z,
670            );
671
672            accumulator.add_point(transform.transform_point3(corner).into());
673        }
674
675        accumulator.finish().unwrap()
676    }
677
678    #[test]
679    fn transform_aabb() {
680        let aabbs = [
681            JointAabb {
682                center: Vec3::ZERO,
683                half_size: Vec3::ZERO,
684            },
685            JointAabb {
686                center: Vec3::ZERO,
687                half_size: vec3(2.0, 3.0, 4.0),
688            },
689            JointAabb {
690                center: vec3(2.0, 3.0, 4.0),
691                half_size: Vec3::ZERO,
692            },
693            JointAabb {
694                center: vec3(20.0, -30.0, 40.0),
695                half_size: vec3(5.0, 6.0, 7.0),
696            },
697        ];
698
699        // Various transforms, including awkward ones like skews and
700        // negative/zero scales.
701        let transforms = [
702            Affine3A::IDENTITY,
703            Affine3A::from_cols(Vec3A::X, Vec3A::Z, Vec3A::Y, vec3a(1.0, 2.0, 3.0)),
704            Affine3A::from_cols(Vec3A::Y, Vec3A::X, Vec3A::Z, vec3a(1.0, 2.0, 3.0)),
705            Affine3A::from_cols(Vec3A::Z, Vec3A::Y, Vec3A::X, vec3a(1.0, 2.0, 3.0)),
706            Affine3A::from_scale(Vec3::ZERO),
707            Affine3A::from_scale(vec3(2.0, 3.0, 4.0)),
708            Affine3A::from_scale(vec3(-2.0, 3.0, -4.0)),
709            Affine3A::from_cols(
710                vec3a(1.0, 2.0, -3.0),
711                vec3a(4.0, -5.0, 6.0),
712                vec3a(-7.0, 8.0, 9.0),
713                vec3a(1.0, -2.0, 3.0),
714            ),
715        ];
716
717        for aabb in aabbs {
718            for transform in transforms {
719                aabb_assert_eq(
720                    super::transform_aabb(aabb, transform),
721                    naive_transform_aabb(aabb, transform),
722                );
723            }
724        }
725    }
726}