Skip to content

Commit

Permalink
Generate 1 chunk at a time
Browse files Browse the repository at this point in the history
  • Loading branch information
Cyliann committed Dec 15, 2022
1 parent 887f07d commit fe940d5
Show file tree
Hide file tree
Showing 9 changed files with 279 additions and 203 deletions.
61 changes: 55 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ bevy = {version = "0.8"}
bevy-inspector-egui = "0.12.1"
bevy_atmosphere = "0.4.0"
bevy_flycam = "*"
bracket-noise = "0.8.7"
itertools = "0.10.3"
ndarray = "0.15.6"
noise = "0.7.0"
Expand Down
2 changes: 1 addition & 1 deletion src/block_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub const BLOCKTYPES: [BlockType; 6] = [
BlockType {
name: "grass",
is_solid: true,
texture_id: Some([3, 3, 1, 0, 3, 3]),
texture_id: Some([3, 3, 0, 1, 3, 3]),
},
BlockType {
name: "dirt",
Expand Down
9 changes: 5 additions & 4 deletions src/chunk.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::voxel_data::{self, CHUNK_SIZE, WORLD_SIZE_IN_CHUNKS};
use crate::voxel_data::{CHUNK_SIZE, WORLD_SIZE_IN_CHUNKS};
use crate::voxel_map;
use crate::mesh;
use crate::world::{ChunkCoord, ChunkMap};
use bevy::prelude::*;

Expand All @@ -16,10 +17,10 @@ impl Chunk {
asset_server: &Res<AssetServer>,
voxel_map: &mut ResMut<voxel_map::VoxelMap>,
chunk_map: &mut ResMut<ChunkMap>,
is_chunk_empty: bool,
is_chunk_full: bool,
) -> Self {
if !is_chunk_empty {
let mesh_handle = meshes.add(voxel_data::create_mesh(chunk_pos, voxel_map));
if !is_chunk_full {
let mesh_handle = meshes.add(mesh::create_mesh(chunk_pos, voxel_map));
let texture_handle: Handle<Image> = asset_server.load("texture_atlas.png");

let material_handle = materials.add(StandardMaterial {
Expand Down
6 changes: 4 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ mod chunk;
mod voxel_data;
mod voxel_map;
mod world;
mod mesh;

fn main() {
App::new()
Expand All @@ -32,6 +33,8 @@ fn main() {
})
.insert_resource(voxel_map::VoxelMap::new())
.insert_resource(world::ChunkMap::new())
.insert_resource(world::ChunkToGenerateQueue(Vec::new()))
.insert_resource(world::ChunkToSpawnQueue(Vec::new()))
.insert_resource(world::ActiveChunks::new())
.insert_resource(world::PlayerLastChunk::new())
.insert_resource(world::GeneratedChunks {
Expand All @@ -49,13 +52,12 @@ fn main() {
.add_plugin(AtmospherePlugin) // Atmosphere setup
.add_plugin(LogDiagnosticsPlugin::default()) // Diagnostics setup
.add_plugin(FrameTimeDiagnosticsPlugin::default())
// Events
.add_event::<world::SpawnChunkEvent>()
// Systems
.add_startup_system(world::spawn_world)
.add_startup_system(spawn_light)
.add_startup_system(spawn_camera)
.add_system(world::check_render_distance)
.add_system(world::generate_chunk)
.add_system(world::spawn_chunk)
.run();
}
Expand Down
102 changes: 102 additions & 0 deletions src/mesh.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
use crate::voxel_map;
use crate::world::{ChunkCoord, WORLD_HEIGHT, WORLD_SIZE};
use bevy::log::info_span;
use bevy::prelude::{Mesh, ResMut, Vec2, Vec3};
use bevy::render::mesh::{self, PrimitiveTopology};
use itertools::iproduct;
use crate::voxel_data::{CHUNK_SIZE, FACE_CHECKS, INDICES, NORMALS, VERTICES};

use super::block_types;
use super::world;

pub fn create_mesh(chunk_pos: &ChunkCoord, voxel_map: &mut ResMut<voxel_map::VoxelMap>) -> Mesh {
let _span = info_span!("Create mesh").entered();
let mut positions = Vec::new();
let mut indices = Vec::new();
let mut normals = Vec::new();
let mut uvs = Vec::new();
let mut index: u32 = 0;
let shifted_global_x = chunk_pos.x * CHUNK_SIZE as i32 + (WORLD_SIZE / 2) as i32;
let shifted_global_y = chunk_pos.y * CHUNK_SIZE as i32;
let shifted_global_z = chunk_pos.z * CHUNK_SIZE as i32 + (WORLD_SIZE / 2) as i32;

for (x, y, z) in iproduct!((0..CHUNK_SIZE), (0..CHUNK_SIZE), (0..CHUNK_SIZE)) {
if check_voxel(
shifted_global_x + x as i32,
shifted_global_y + y as i32,
shifted_global_z + z as i32,
voxel_map,
) {
let block_type = &block_types::BLOCKTYPES[voxel_map.voxels[[
(x as i32 + shifted_global_x) as usize,
(y as i32 + shifted_global_y) as usize,
(z as i32 + shifted_global_z) as usize,
]] as usize];

for i in 0..6 {
let face_check = FACE_CHECKS[i];

if !check_voxel(
shifted_global_x + face_check.x as i32 + x as i32,
shifted_global_y + face_check.y as i32 + y as i32,
shifted_global_z + face_check.z as i32 + z as i32,
voxel_map,
) {

for position in VERTICES[i].iter() {
positions
.push((*position + Vec3::new(x as f32, y as f32, z as f32)).to_array());
normals.push(NORMALS[i].to_array());
}
for triangle_index in INDICES.iter() {
indices.push(*triangle_index + index);
}
for uv in add_texture(block_type.texture_id.unwrap()[i]) {
uvs.push(uv.to_array());
}
index += 4;
}
}
}
}

let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, positions);
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, normals);
mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, uvs);
mesh.set_indices(Some(mesh::Indices::U32(indices)));
mesh
}

pub fn check_voxel(x: i32, y: i32, z: i32, voxel_map: &mut ResMut<voxel_map::VoxelMap>) -> bool {
if x > WORLD_SIZE as i32 - 1
|| x < 0
|| y > WORLD_HEIGHT as i32 - 1
|| y < 0
|| z > WORLD_SIZE as i32 - 1
|| z < 0
{
return false;
}

block_types::BLOCKTYPES[voxel_map.voxels[[x as usize, y as usize, z as usize]] as usize]
.is_solid
}

fn add_texture(texture_id: u32) -> [Vec2; 4] {
let mut y = (texture_id / world::TEXTURE_ATLAS_SIZE_IN_BLOCKS as u32) as f32;
let mut x = (texture_id % world::TEXTURE_ATLAS_SIZE_IN_BLOCKS as u32) as f32;

x *= world::NORMALIZED_BLOCK_TEXTURE_SIZE;
y *= world::NORMALIZED_BLOCK_TEXTURE_SIZE;

[
Vec2::new(x, y + world::NORMALIZED_BLOCK_TEXTURE_SIZE),
Vec2::new(x, y),
Vec2::new(x + world::NORMALIZED_BLOCK_TEXTURE_SIZE, y),
Vec2::new(
x + world::NORMALIZED_BLOCK_TEXTURE_SIZE,
y + world::NORMALIZED_BLOCK_TEXTURE_SIZE,
),
]
}
Loading

0 comments on commit fe940d5

Please sign in to comment.