bevy_entitiles 0.9.0

A 2d tilemap library for bevy. With many useful algorithms/tools built in.
Documentation
use bevy::{
    ecs::system::{Res, Resource},
    prelude::{Query, ResMut},
    render::view::ViewVisibility,
};

use crate::{math::CameraAabb2d, tilemap::map::TilemapAabbs};

use super::{
    chunk::RenderChunkStorage,
    extract::{ExtractedTilemap, ExtractedView},
    material::TilemapMaterial,
};

#[derive(Resource)]
pub struct FrustumCulling(pub bool);

impl Default for FrustumCulling {
    fn default() -> Self {
        Self(true)
    }
}

pub fn cull_tilemaps(
    mut tilemaps: Query<(&TilemapAabbs, &mut ViewVisibility)>,
    cameras: Query<&CameraAabb2d>,
    culling: Res<FrustumCulling>,
) {
    if !culling.0 {
        return;
    }

    cameras.iter().for_each(|camera| {
        tilemaps.par_iter_mut().for_each(|(aabbs, mut visibility)| {
            if aabbs.world_aabb.is_intersected(camera.0) {
                visibility.set();
            }
        });
    });
}

pub fn cull_chunks<M: TilemapMaterial>(
    tilemaps: Query<&ExtractedTilemap<M>>,
    mut render_chunk_storage: ResMut<RenderChunkStorage<M>>,
    cameras: Query<&ExtractedView>,
    culling: Res<FrustumCulling>,
) {
    if !culling.0 {
        return;
    }

    tilemaps.iter().for_each(|tilemap| {
        let Some(chunks) = render_chunk_storage.get_chunks_mut(tilemap.id) else {
            return;
        };
        chunks.values_mut().for_each(|c| {
            c.visible = false;
        });
    });

    cameras.iter().for_each(|cam_aabb| {
        tilemaps.iter().for_each(|tilemap| {
            let Some(chunks) = render_chunk_storage.get_chunks_mut(tilemap.id) else {
                return;
            };

            chunks.values_mut().for_each(|c| {
                if c.aabb.is_intersected(cam_aabb.0) {
                    c.visible = true;
                }
            });
        });
    });
}