bevylder 0.1.0

Voxels brought to bevy
Documentation
use bevy::{
    ecs::system::{
        lifetimeless::{Read, SQuery, SRes},
        SystemParamItem,
    },
    pbr::{SetMeshBindGroup, SetMeshViewBindGroup},
    prelude::*,
    render::{
        mesh::GpuBufferInfo,
        render_asset::RenderAssets,
        render_phase::{
            EntityRenderCommand, RenderCommandResult, SetItemPipeline, TrackedRenderPass,
        },
    },
};

use super::voxel_mesh::VoxelMesh;

use super::voxel;

pub(crate) type DrawVoxels = (
    SetItemPipeline,
    SetMeshViewBindGroup<0>,
    SetMeshBindGroup<1>,
    SetVoxelBindGroup<2>,
    DrawVoxel,
);

pub(crate) struct SetVoxelBindGroup<const I: usize>;

impl<const I: usize> EntityRenderCommand for SetVoxelBindGroup<I> {
    type Param = (
        SQuery<Read<voxel::Voxel>>,
        SRes<RenderAssets<voxel::VoxelData>>,
    );

    fn render<'w>(
        _view: Entity,
        item: Entity,
        (voxels, voxel_data): SystemParamItem<'w, '_, Self::Param>,
        pass: &mut TrackedRenderPass<'w>,
    ) -> RenderCommandResult {
        let voxel = voxels.get_inner(item).unwrap();
        let voxel_meta = voxel_data.into_inner().get(&voxel.data).unwrap();

        pass.set_bind_group(I, &voxel_meta.bind_group, &[]);

        RenderCommandResult::Success
    }
}

pub struct DrawVoxel;

impl EntityRenderCommand for DrawVoxel {
    type Param = (SRes<RenderAssets<Mesh>>, SRes<VoxelMesh>);
    #[inline]
    fn render<'w>(
        _view: Entity,
        _item: Entity,
        (meshes, voxel_mesh): SystemParamItem<'w, '_, Self::Param>,
        pass: &mut TrackedRenderPass<'w>,
    ) -> RenderCommandResult {
        if let Some(gpu_mesh) = meshes.into_inner().get(&voxel_mesh.mesh) {
            pass.set_vertex_buffer(0, gpu_mesh.vertex_buffer.slice(..));
            match &gpu_mesh.buffer_info {
                GpuBufferInfo::Indexed {
                    buffer,
                    index_format,
                    count,
                } => {
                    pass.set_index_buffer(buffer.slice(..), 0, *index_format);
                    pass.draw_indexed(0..*count, 0, 0..1);
                }
                GpuBufferInfo::NonIndexed { vertex_count } => {
                    pass.draw(0..*vertex_count, 0..1);
                }
            }
            RenderCommandResult::Success
        } else {
            RenderCommandResult::Failure
        }
    }
}