Skip to main content

bevy_sprite_render/tilemap_chunk/
mod.rs

1use crate::{AlphaMode2d, MeshMaterial2d};
2use bevy_app::{App, Plugin, Update};
3use bevy_asset::{Assets, Handle};
4use bevy_color::Color;
5use bevy_derive::{Deref, DerefMut};
6use bevy_ecs::{
7    component::Component,
8    entity::Entity,
9    lifecycle::HookContext,
10    query::Changed,
11    reflect::{ReflectComponent, ReflectResource},
12    resource::Resource,
13    system::{Query, ResMut},
14    template::FromTemplate,
15    world::DeferredWorld,
16};
17use bevy_image::Image;
18use bevy_math::{primitives::Rectangle, UVec2};
19use bevy_mesh::{Mesh, Mesh2d};
20use bevy_platform::collections::HashMap;
21use bevy_reflect::{prelude::*, Reflect};
22use bevy_transform::components::Transform;
23use bevy_utils::default;
24use tracing::warn;
25
26mod tilemap_chunk_material;
27
28pub use tilemap_chunk_material::*;
29
30mod tile_orientation;
31
32pub use tile_orientation::*;
33
34/// Plugin that handles the initialization and updating of tilemap chunks.
35/// Adds systems for processing newly added tilemap chunks and updating their indices.
36pub struct TilemapChunkPlugin;
37
38impl Plugin for TilemapChunkPlugin {
39    fn build(&self, app: &mut App) {
40        app.init_resource::<TilemapChunkMeshCache>()
41            .add_systems(Update, update_tilemap_chunk_indices);
42    }
43}
44
45/// A resource storing the meshes for each tilemap chunk size.
46#[derive(impl bevy_ecs::resource::Resource for TilemapChunkMeshCache where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {}Resource, #[automatically_derived]
impl ::core::default::Default for TilemapChunkMeshCache {
    #[inline]
    fn default() -> TilemapChunkMeshCache {
        TilemapChunkMeshCache(::core::default::Default::default())
    }
}Default, impl ::core::ops::Deref for TilemapChunkMeshCache {
    type Target = HashMap<UVec2, Handle<Mesh>>;
    fn deref(&self) -> &Self::Target { &self.0 }
}Deref, impl ::core::ops::DerefMut for TilemapChunkMeshCache {
    fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
}DerefMut, const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for TilemapChunkMeshCache where
             {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration.register_type_data::<ReflectResource, Self>();
                registration.register_type_data::<ReflectDefault, Self>();
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <HashMap<UVec2, Handle<Mesh>> as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for TilemapChunkMeshCache where  {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(||
                        {
                            bevy_reflect::TypeInfo::TupleStruct(bevy_reflect::tuple_struct::TupleStructInfo::new::<Self>(&[bevy_reflect::UnnamedField::new::<HashMap<UVec2,
                                                        Handle<Mesh>>>(0usize)]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for TilemapChunkMeshCache where  {
            fn type_path() -> &'static str {
                "bevy_sprite_render::tilemap_chunk::TilemapChunkMeshCache"
            }
            fn short_type_path() -> &'static str { "TilemapChunkMeshCache" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("TilemapChunkMeshCache")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_sprite_render::tilemap_chunk".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_sprite_render::tilemap_chunk")
            }
        }
        impl bevy_reflect::Reflect for TilemapChunkMeshCache 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(<TilemapChunkMeshCache
                                        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 TilemapChunkMeshCache
            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)
                -> bevy_reflect::tuple_struct::DynamicTupleStruct {
                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));
                dynamic
            }
        }
        impl bevy_reflect::PartialReflect for TilemapChunkMeshCache 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: <HashMap<UVec2, Handle<Mesh>> as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.0)?,
                        }))
            }
        }
        impl bevy_reflect::FromReflect for TilemapChunkMeshCache 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 mut __this =
                        <Self as ::core::default::Default>::default();
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <HashMap<UVec2, Handle<Mesh>> as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::tuple_struct::TupleStruct::field(__ref_struct,
                                                    0)?))() {
                        __this.0 = __field;
                    }
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
47#[reflect(Resource, Default)]
48pub struct TilemapChunkMeshCache(HashMap<UVec2, Handle<Mesh>>);
49
50/// A component representing a chunk of a tilemap.
51/// Each chunk is a rectangular section of tiles that is rendered as a single mesh.
52#[derive(impl bevy_ecs::component::Component for TilemapChunk 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::Immutable;
    fn register_required_components(_requiree:
            bevy_ecs::component::ComponentId,
        required_components:
            &mut bevy_ecs::component::RequiredComponentsRegistrator) {}
    fn on_insert()
        -> ::core::option::Option<bevy_ecs::lifecycle::ComponentHook> {
        ::core::option::Option::Some(on_insert_tilemap_chunk)
    }
    fn clone_behavior() -> bevy_ecs::component::ComponentCloneBehavior {
        use bevy_ecs::component::{
            DefaultCloneBehaviorBase, DefaultCloneBehaviorViaClone,
        };
        (&&&bevy_ecs::component::DefaultCloneBehaviorSpecialization::<Self>::default()).default_clone_behavior()
    }
    fn relationship_accessor()
        ->
            ::core::option::Option<bevy_ecs::relationship::ComponentRelationshipAccessor<Self>> {
        ::core::option::Option::None
    }
}Component, #[automatically_derived]
impl ::core::clone::Clone for TilemapChunk {
    #[inline]
    fn clone(&self) -> TilemapChunk {
        TilemapChunk {
            chunk_size: ::core::clone::Clone::clone(&self.chunk_size),
            tile_display_size: ::core::clone::Clone::clone(&self.tile_display_size),
            tileset: ::core::clone::Clone::clone(&self.tileset),
            alpha_mode: ::core::clone::Clone::clone(&self.alpha_mode),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for TilemapChunk {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f, "TilemapChunk",
            "chunk_size", &self.chunk_size, "tile_display_size",
            &self.tile_display_size, "tileset", &self.tileset, "alpha_mode",
            &&self.alpha_mode)
    }
}Debug, #[automatically_derived]
impl ::core::default::Default for TilemapChunk {
    #[inline]
    fn default() -> TilemapChunk {
        TilemapChunk {
            chunk_size: ::core::default::Default::default(),
            tile_display_size: ::core::default::Default::default(),
            tileset: ::core::default::Default::default(),
            alpha_mode: ::core::default::Default::default(),
        }
    }
}Default, const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for TilemapChunk where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration.register_type_data::<ReflectComponent, Self>();
                registration.register_type_data::<ReflectDefault, Self>();
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <UVec2 as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <Handle<Image> as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <AlphaMode2d as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for TilemapChunk where  {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<UVec2>("chunk_size"),
                                                bevy_reflect::NamedField::new::<UVec2>("tile_display_size"),
                                                bevy_reflect::NamedField::new::<Handle<Image>>("tileset"),
                                                bevy_reflect::NamedField::new::<AlphaMode2d>("alpha_mode")]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for TilemapChunk where  {
            fn type_path() -> &'static str {
                "bevy_sprite_render::tilemap_chunk::TilemapChunk"
            }
            fn short_type_path() -> &'static str { "TilemapChunk" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("TilemapChunk")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_sprite_render::tilemap_chunk".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_sprite_render::tilemap_chunk")
            }
        }
        impl bevy_reflect::Reflect for TilemapChunk 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(<TilemapChunk
                                        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 TilemapChunk where  {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "chunk_size" =>
                        ::core::option::Option::Some(&self.chunk_size),
                    "tile_display_size" =>
                        ::core::option::Option::Some(&self.tile_display_size),
                    "tileset" => ::core::option::Option::Some(&self.tileset),
                    "alpha_mode" =>
                        ::core::option::Option::Some(&self.alpha_mode),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "chunk_size" =>
                        ::core::option::Option::Some(&mut self.chunk_size),
                    "tile_display_size" =>
                        ::core::option::Option::Some(&mut self.tile_display_size),
                    "tileset" =>
                        ::core::option::Option::Some(&mut self.tileset),
                    "alpha_mode" =>
                        ::core::option::Option::Some(&mut self.alpha_mode),
                    _ => ::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.chunk_size),
                    1usize =>
                        ::core::option::Option::Some(&self.tile_display_size),
                    2usize => ::core::option::Option::Some(&self.tileset),
                    3usize => ::core::option::Option::Some(&self.alpha_mode),
                    _ => ::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.chunk_size),
                    1usize =>
                        ::core::option::Option::Some(&mut self.tile_display_size),
                    2usize => ::core::option::Option::Some(&mut self.tileset),
                    3usize =>
                        ::core::option::Option::Some(&mut self.alpha_mode),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("chunk_size"),
                    1usize => ::core::option::Option::Some("tile_display_size"),
                    2usize => ::core::option::Option::Some("tileset"),
                    3usize => ::core::option::Option::Some("alpha_mode"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "chunk_size" => ::core::option::Option::Some(0usize),
                    "tile_display_size" => ::core::option::Option::Some(1usize),
                    "tileset" => ::core::option::Option::Some(2usize),
                    "alpha_mode" => ::core::option::Option::Some(3usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 4usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                -> bevy_reflect::structs::DynamicStruct {
                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("chunk_size",
                    bevy_reflect::PartialReflect::to_dynamic(&self.chunk_size));
                dynamic.insert_boxed("tile_display_size",
                    bevy_reflect::PartialReflect::to_dynamic(&self.tile_display_size));
                dynamic.insert_boxed("tileset",
                    bevy_reflect::PartialReflect::to_dynamic(&self.tileset));
                dynamic.insert_boxed("alpha_mode",
                    bevy_reflect::PartialReflect::to_dynamic(&self.alpha_mode));
                dynamic
            }
        }
        impl bevy_reflect::PartialReflect for TilemapChunk 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 TilemapChunk 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) =
                            (||
                                        <UVec2 as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "chunk_size")?))() {
                        __this.chunk_size = __field;
                    }
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <UVec2 as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "tile_display_size")?))() {
                        __this.tile_display_size = __field;
                    }
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <Handle<Image> as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "tileset")?))() {
                        __this.tileset = __field;
                    }
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <AlphaMode2d as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "alpha_mode")?))() {
                        __this.alpha_mode = __field;
                    }
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect, impl ::core::default::Default for TilemapChunkTemplate {
    fn default() -> Self {
        Self {
            chunk_size: ::core::default::Default::default(),
            tile_display_size: ::core::default::Default::default(),
            tileset: ::core::default::Default::default(),
            alpha_mode: ::core::default::Default::default(),
        }
    }
}FromTemplate)]
53#[reflect(Component, Clone, Debug, Default)]
54#[component(immutable, on_insert = on_insert_tilemap_chunk)]
55pub struct TilemapChunk {
56    /// The size of the chunk in tiles.
57    pub chunk_size: UVec2,
58    /// The size to use for each tile, not to be confused with the size of a tile in the tileset image.
59    /// The size of the tile in the tileset image is determined by the tileset image's dimensions.
60    pub tile_display_size: UVec2,
61    /// Handle to the tileset image containing all tile textures.
62    pub tileset: Handle<Image>,
63    /// The alpha mode to use for the tilemap chunk.
64    pub alpha_mode: AlphaMode2d,
65}
66
67impl TilemapChunk {
68    pub fn calculate_tile_transform(&self, position: UVec2) -> Transform {
69        Transform::from_xyz(
70            // tile position
71            position.x as f32
72            // times display size for a tile
73            * self.tile_display_size.x as f32
74            // plus 1/2 the tile_display_size to correct the center
75            + self.tile_display_size.x as f32 / 2.
76            // minus 1/2 the tilechunk size, in terms of the tile_display_size,
77            // to place the 0 at left of tilemapchunk
78            - self.tile_display_size.x as f32 * self.chunk_size.x as f32 / 2.,
79            // tile position
80            position.y as f32
81            // times display size for a tile
82            * self.tile_display_size.y as f32
83            // minus 1/2 the tile_display_size to correct the center
84            + self.tile_display_size.y as f32 / 2.
85            // plus 1/2 the tilechunk size, in terms of the tile_display_size,
86            // to place the 0 at bottom of tilemapchunk
87            - self.tile_display_size.y as f32 * self.chunk_size.y as f32 / 2.,
88            0.,
89        )
90    }
91}
92
93/// Data for a single tile in the tilemap chunk.
94#[derive(#[automatically_derived]
impl ::core::clone::Clone for TileData {
    #[inline]
    fn clone(&self) -> TileData {
        let _: ::core::clone::AssertParamIsClone<u16>;
        let _: ::core::clone::AssertParamIsClone<Color>;
        let _: ::core::clone::AssertParamIsClone<bool>;
        let _: ::core::clone::AssertParamIsClone<TileOrientation>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for TileData { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for TileData {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f, "TileData",
            "tileset_index", &self.tileset_index, "color", &self.color,
            "visible", &self.visible, "orientation", &&self.orientation)
    }
}Debug, const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for TileData where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration.register_type_data::<ReflectDefault, Self>();
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <u16 as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <Color as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <bool as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <TileOrientation as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for TileData where  {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<u16>("tileset_index"),
                                                bevy_reflect::NamedField::new::<Color>("color"),
                                                bevy_reflect::NamedField::new::<bool>("visible"),
                                                bevy_reflect::NamedField::new::<TileOrientation>("orientation")]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for TileData where  {
            fn type_path() -> &'static str {
                "bevy_sprite_render::tilemap_chunk::TileData"
            }
            fn short_type_path() -> &'static str { "TileData" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("TileData")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_sprite_render::tilemap_chunk".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_sprite_render::tilemap_chunk")
            }
        }
        impl bevy_reflect::Reflect for TileData 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(<TileData
                                        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 TileData where  {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "tileset_index" =>
                        ::core::option::Option::Some(&self.tileset_index),
                    "color" => ::core::option::Option::Some(&self.color),
                    "visible" => ::core::option::Option::Some(&self.visible),
                    "orientation" =>
                        ::core::option::Option::Some(&self.orientation),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "tileset_index" =>
                        ::core::option::Option::Some(&mut self.tileset_index),
                    "color" => ::core::option::Option::Some(&mut self.color),
                    "visible" =>
                        ::core::option::Option::Some(&mut self.visible),
                    "orientation" =>
                        ::core::option::Option::Some(&mut self.orientation),
                    _ => ::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.tileset_index),
                    1usize => ::core::option::Option::Some(&self.color),
                    2usize => ::core::option::Option::Some(&self.visible),
                    3usize => ::core::option::Option::Some(&self.orientation),
                    _ => ::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.tileset_index),
                    1usize => ::core::option::Option::Some(&mut self.color),
                    2usize => ::core::option::Option::Some(&mut self.visible),
                    3usize =>
                        ::core::option::Option::Some(&mut self.orientation),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("tileset_index"),
                    1usize => ::core::option::Option::Some("color"),
                    2usize => ::core::option::Option::Some("visible"),
                    3usize => ::core::option::Option::Some("orientation"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "tileset_index" => ::core::option::Option::Some(0usize),
                    "color" => ::core::option::Option::Some(1usize),
                    "visible" => ::core::option::Option::Some(2usize),
                    "orientation" => ::core::option::Option::Some(3usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 4usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                -> bevy_reflect::structs::DynamicStruct {
                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("tileset_index",
                    bevy_reflect::PartialReflect::to_dynamic(&self.tileset_index));
                dynamic.insert_boxed("color",
                    bevy_reflect::PartialReflect::to_dynamic(&self.color));
                dynamic.insert_boxed("visible",
                    bevy_reflect::PartialReflect::to_dynamic(&self.visible));
                dynamic.insert_boxed("orientation",
                    bevy_reflect::PartialReflect::to_dynamic(&self.orientation));
                dynamic
            }
        }
        impl bevy_reflect::PartialReflect for TileData 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 TileData 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) =
                            (||
                                        <u16 as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "tileset_index")?))() {
                        __this.tileset_index = __field;
                    }
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <Color as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "color")?))() {
                        __this.color = __field;
                    }
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <bool as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "visible")?))() {
                        __this.visible = __field;
                    }
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <TileOrientation as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "orientation")?))() {
                        __this.orientation = __field;
                    }
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
95#[reflect(Clone, Debug, Default)]
96pub struct TileData {
97    /// The index of the tile in the corresponding tileset array texture.
98    pub tileset_index: u16,
99    /// The color tint of the tile. White leaves the sampled texture color unchanged.
100    pub color: Color,
101    /// The visibility of the tile.
102    pub visible: bool,
103    /// The orientation of the tile.
104    pub orientation: TileOrientation,
105}
106
107impl TileData {
108    /// Creates a new `TileData` with the given tileset index and default values.
109    pub fn from_tileset_index(tileset_index: u16) -> Self {
110        Self {
111            tileset_index,
112            ..default()
113        }
114    }
115}
116
117impl Default for TileData {
118    fn default() -> Self {
119        Self {
120            tileset_index: 0,
121            color: Color::WHITE,
122            visible: true,
123            orientation: TileOrientation::Default,
124        }
125    }
126}
127
128/// Component storing the data of tiles within a chunk.
129/// Each index corresponds to a specific tile in the tileset. `None` indicates an empty tile.
130#[derive(impl bevy_ecs::component::Component for TilemapChunkTileData 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 relationship_accessor()
        ->
            ::core::option::Option<bevy_ecs::relationship::ComponentRelationshipAccessor<Self>> {
        ::core::option::Option::None
    }
}Component, #[automatically_derived]
impl ::core::clone::Clone for TilemapChunkTileData {
    #[inline]
    fn clone(&self) -> TilemapChunkTileData {
        TilemapChunkTileData(::core::clone::Clone::clone(&self.0))
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for TilemapChunkTileData {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f,
            "TilemapChunkTileData", &&self.0)
    }
}Debug, impl ::core::ops::Deref for TilemapChunkTileData {
    type Target = Vec<Option<TileData>>;
    fn deref(&self) -> &Self::Target { &self.0 }
}Deref, impl ::core::ops::DerefMut for TilemapChunkTileData {
    fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
}DerefMut, const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for TilemapChunkTileData where
            {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration.register_type_data::<ReflectComponent, Self>();
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <Vec<Option<TileData>> as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for TilemapChunkTileData where  {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(||
                        {
                            bevy_reflect::TypeInfo::TupleStruct(bevy_reflect::tuple_struct::TupleStructInfo::new::<Self>(&[bevy_reflect::UnnamedField::new::<Vec<Option<TileData>>>(0usize)]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for TilemapChunkTileData where  {
            fn type_path() -> &'static str {
                "bevy_sprite_render::tilemap_chunk::TilemapChunkTileData"
            }
            fn short_type_path() -> &'static str { "TilemapChunkTileData" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("TilemapChunkTileData")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_sprite_render::tilemap_chunk".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_sprite_render::tilemap_chunk")
            }
        }
        impl bevy_reflect::Reflect for TilemapChunkTileData 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(<TilemapChunkTileData
                                        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 TilemapChunkTileData
            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)
                -> bevy_reflect::tuple_struct::DynamicTupleStruct {
                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));
                dynamic
            }
        }
        impl bevy_reflect::PartialReflect for TilemapChunkTileData 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)
            }
            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 TilemapChunkTileData 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: <Vec<Option<TileData>> 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, #[automatically_derived]
impl ::core::default::Default for TilemapChunkTileData {
    #[inline]
    fn default() -> TilemapChunkTileData {
        TilemapChunkTileData(::core::default::Default::default())
    }
}Default)]
131#[reflect(Component, Clone, Debug)]
132pub struct TilemapChunkTileData(pub Vec<Option<TileData>>);
133
134fn on_insert_tilemap_chunk(mut world: DeferredWorld, HookContext { entity, .. }: HookContext) {
135    let Some(tilemap_chunk) = world.get::<TilemapChunk>(entity) else {
136        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event src/tilemap_chunk/mod.rs:136",
                        "bevy_sprite_render::tilemap_chunk", ::tracing::Level::WARN,
                        ::tracing_core::__macro_support::Option::Some("src/tilemap_chunk/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(136u32),
                        ::tracing_core::__macro_support::Option::Some("bevy_sprite_render::tilemap_chunk"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::WARN <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::WARN <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("TilemapChunk not found for tilemap chunk {0}",
                                                    entity) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};warn!("TilemapChunk not found for tilemap chunk {}", entity);
137        return;
138    };
139
140    let chunk_size = tilemap_chunk.chunk_size;
141    let alpha_mode = tilemap_chunk.alpha_mode;
142    let tileset = tilemap_chunk.tileset.clone();
143
144    let Some(tile_data) = world.get::<TilemapChunkTileData>(entity) else {
145        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event src/tilemap_chunk/mod.rs:145",
                        "bevy_sprite_render::tilemap_chunk", ::tracing::Level::WARN,
                        ::tracing_core::__macro_support::Option::Some("src/tilemap_chunk/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(145u32),
                        ::tracing_core::__macro_support::Option::Some("bevy_sprite_render::tilemap_chunk"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::WARN <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::WARN <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("TilemapChunkIndices not found for tilemap chunk {0}",
                                                    entity) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};warn!("TilemapChunkIndices not found for tilemap chunk {}", entity);
146        return;
147    };
148
149    let expected_tile_data_length = chunk_size.element_product() as usize;
150    if tile_data.len() != expected_tile_data_length {
151        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event src/tilemap_chunk/mod.rs:151",
                        "bevy_sprite_render::tilemap_chunk", ::tracing::Level::WARN,
                        ::tracing_core::__macro_support::Option::Some("src/tilemap_chunk/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(151u32),
                        ::tracing_core::__macro_support::Option::Some("bevy_sprite_render::tilemap_chunk"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::WARN <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::WARN <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("Invalid tile data length for tilemap chunk {0} of size {1}. Expected {2}, got {3}",
                                                    entity, chunk_size, expected_tile_data_length,
                                                    tile_data.len()) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};warn!(
152            "Invalid tile data length for tilemap chunk {} of size {}. Expected {}, got {}",
153            entity,
154            chunk_size,
155            expected_tile_data_length,
156            tile_data.len(),
157        );
158        return;
159    }
160
161    let packed_tile_data: Vec<PackedTileData> =
162        tile_data.0.iter().map(|&tile| tile.into()).collect();
163
164    let tile_data_image = make_chunk_tile_data_image(&chunk_size, &packed_tile_data);
165
166    let tilemap_chunk_mesh_cache = world.resource::<TilemapChunkMeshCache>();
167
168    let mesh_size = chunk_size * tilemap_chunk.tile_display_size;
169
170    let mesh = if let Some(mesh) = tilemap_chunk_mesh_cache.get(&mesh_size) {
171        mesh.clone()
172    } else {
173        let mut meshes = world.resource_mut::<Assets<Mesh>>();
174        meshes.add(Rectangle::from_size(mesh_size.as_vec2()))
175    };
176
177    let mut images = world.resource_mut::<Assets<Image>>();
178    let tile_data = images.add(tile_data_image);
179
180    let mut materials = world.resource_mut::<Assets<TilemapChunkMaterial>>();
181    let material = materials.add(TilemapChunkMaterial {
182        tileset,
183        tile_data,
184        alpha_mode,
185    });
186
187    world
188        .commands()
189        .entity(entity)
190        .insert((Mesh2d(mesh), MeshMaterial2d(material)));
191}
192
193pub fn update_tilemap_chunk_indices(
194    query: Query<
195        (
196            Entity,
197            &TilemapChunk,
198            &TilemapChunkTileData,
199            &MeshMaterial2d<TilemapChunkMaterial>,
200        ),
201        Changed<TilemapChunkTileData>,
202    >,
203    mut materials: ResMut<Assets<TilemapChunkMaterial>>,
204    mut images: ResMut<Assets<Image>>,
205) {
206    for (chunk_entity, TilemapChunk { chunk_size, .. }, tile_data, material) in query {
207        let expected_tile_data_length = chunk_size.element_product() as usize;
208        if tile_data.len() != expected_tile_data_length {
209            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event src/tilemap_chunk/mod.rs:209",
                        "bevy_sprite_render::tilemap_chunk", ::tracing::Level::WARN,
                        ::tracing_core::__macro_support::Option::Some("src/tilemap_chunk/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(209u32),
                        ::tracing_core::__macro_support::Option::Some("bevy_sprite_render::tilemap_chunk"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::WARN <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::WARN <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("Invalid TilemapChunkTileData length for tilemap chunk {0} of size {1}. Expected {2}, got {3}",
                                                    chunk_entity, chunk_size, tile_data.len(),
                                                    expected_tile_data_length) as
                                            &dyn ::tracing::field::Value))])
            });
    } else { ; }
};warn!(
210                "Invalid TilemapChunkTileData length for tilemap chunk {} of size {}. Expected {}, got {}",
211                chunk_entity,
212                chunk_size,
213                tile_data.len(),
214                expected_tile_data_length
215            );
216            continue;
217        }
218
219        let packed_tile_data: Vec<PackedTileData> =
220            tile_data.0.iter().map(|&tile| tile.into()).collect();
221
222        // Getting the material mutably to trigger change detection
223        let Some(material) = materials.get_mut(material.id()) else {
224            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event src/tilemap_chunk/mod.rs:224",
                        "bevy_sprite_render::tilemap_chunk", ::tracing::Level::WARN,
                        ::tracing_core::__macro_support::Option::Some("src/tilemap_chunk/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(224u32),
                        ::tracing_core::__macro_support::Option::Some("bevy_sprite_render::tilemap_chunk"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::WARN <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::WARN <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("TilemapChunkMaterial not found for tilemap chunk {0}",
                                                    chunk_entity) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};warn!(
225                "TilemapChunkMaterial not found for tilemap chunk {}",
226                chunk_entity
227            );
228            continue;
229        };
230        let Some(mut tile_data_image) = images.get_mut(&material.tile_data) else {
231            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event src/tilemap_chunk/mod.rs:231",
                        "bevy_sprite_render::tilemap_chunk", ::tracing::Level::WARN,
                        ::tracing_core::__macro_support::Option::Some("src/tilemap_chunk/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(231u32),
                        ::tracing_core::__macro_support::Option::Some("bevy_sprite_render::tilemap_chunk"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::WARN <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::WARN <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("TilemapChunkMaterial tile data image not found for tilemap chunk {0}",
                                                    chunk_entity) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};warn!(
232                "TilemapChunkMaterial tile data image not found for tilemap chunk {}",
233                chunk_entity
234            );
235            continue;
236        };
237        let Some(data) = tile_data_image.data.as_mut() else {
238            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event src/tilemap_chunk/mod.rs:238",
                        "bevy_sprite_render::tilemap_chunk", ::tracing::Level::WARN,
                        ::tracing_core::__macro_support::Option::Some("src/tilemap_chunk/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(238u32),
                        ::tracing_core::__macro_support::Option::Some("bevy_sprite_render::tilemap_chunk"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::WARN <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::WARN <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("TilemapChunkMaterial tile data image data not found for tilemap chunk {0}",
                                                    chunk_entity) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};warn!(
239                "TilemapChunkMaterial tile data image data not found for tilemap chunk {}",
240                chunk_entity
241            );
242            continue;
243        };
244        data.clear();
245        data.extend_from_slice(bytemuck::cast_slice(&packed_tile_data));
246    }
247}
248
249impl TilemapChunkTileData {
250    pub fn tile_data_from_tile_pos(
251        &self,
252        tilemap_size: UVec2,
253        position: UVec2,
254    ) -> Option<&TileData> {
255        self.0
256            .get(tilemap_size.x as usize * position.y as usize + position.x as usize)
257            .and_then(|opt| opt.as_ref())
258    }
259}