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 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#[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#[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 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 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 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 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 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 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
187pub 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 (&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 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#[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 let tc = (mx * cx) + (my * cy) + (mz * cz) + mt;
267
268 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#[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 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 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#[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#[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#[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 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#[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
418macro_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 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 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}