You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
48 lines
1.5 KiB
48 lines
1.5 KiB
use std::ops::Deref; |
|
|
|
use bevy::prelude::*; |
|
|
|
use crate::{ |
|
bloxel::{block::BlockTexture, prelude::*}, |
|
TerrainAtlas, TerrainMaterial, |
|
}; |
|
|
|
mod mesh_generator; |
|
|
|
pub use mesh_generator::*; |
|
|
|
/// Generates meshes for chunks that have `ChunkStorage` but no `Mesh3d` yet. |
|
pub fn generate_chunk_mesh( |
|
mut commands: Commands, |
|
mut meshes: ResMut<Assets<Mesh>>, |
|
terrain_material: Option<Res<TerrainMaterial>>, |
|
terrain_atlas: Option<Res<TerrainAtlas>>, |
|
atlas_layouts: Res<Assets<TextureAtlasLayout>>, |
|
chunks_without_meshes: Query<(Entity, &ChunkData), (With<Chunk>, Without<Mesh3d>)>, |
|
block_lookup: Query<&BlockTexture, With<Block>>, |
|
) { |
|
// This system will run before `TerrainMaterial` is available, so to avoid |
|
// the system failing, we'll make the material and atlas an `Option`. |
|
// TODO: Should be able to be replaced with `When<>` once available in Bevy. |
|
let Some(terrain_material) = terrain_material else { |
|
return; |
|
}; |
|
|
|
// Atlas and layout should exist at this point, if material does. |
|
let terrain_atlas = terrain_atlas.unwrap(); |
|
let terrain_atlas_layout = atlas_layouts.get(&terrain_atlas.layout).unwrap(); |
|
|
|
for (entity, storage) in chunks_without_meshes.iter() { |
|
let mesh = create_bloxel_mesh( |
|
storage.deref(), |
|
terrain_atlas_layout, |
|
&terrain_atlas.sources, |
|
&block_lookup, |
|
); |
|
|
|
commands.entity(entity).insert(( |
|
Mesh3d(meshes.add(mesh)), |
|
MeshMaterial3d(terrain_material.0.clone()), |
|
)); |
|
} |
|
}
|
|
|