Skip to content
2 changes: 1 addition & 1 deletion src/client/collider/systems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ mod tests {

let block = BlockId::Dirt;
let mut resource = app.world_mut().get_resource_mut::<ChunkManager>().unwrap();
let chunks = ChunkManager::instantiate_chunks(IVec3::ZERO, IVec3::ONE);
let chunks = ChunkManager::instantiate_chunks(ChunkPosition::ZERO, IVec2::ONE);
resource.insert_chunks(chunks);
resource.update_block(IVec3 { x: 6, y: 7, z: 8 }, block);

Expand Down
6 changes: 1 addition & 5 deletions src/client/player/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,11 @@ impl LastPlayerPosition {
Self(IVec3::ZERO)
}

pub fn chunk_position(&self) -> IVec3 {
Self::chunk_pos(self.0)
}

pub fn has_same_chunk_position_as(&self, other_world_position: IVec3) -> bool {
Self::chunk_pos(self.0) == Self::chunk_pos(other_world_position)
}

fn chunk_pos(world_pos: IVec3) -> IVec3 {
fn chunk_pos(world_pos: IVec3) -> ChunkPosition {
ChunkManager::world_position_to_chunk_position(world_pos)
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/client/player/systems/terrain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ pub fn handle_block_update_events(
) {
for event in block_update_events.read() {
info!("Block update message: {:?}", event.position);
if !ChunkManager::inside_world(&event.position) {
warn!("Player attempted to set block outside of the world");
continue;
}
chunk_manager
.update_block(event.position, event.block)
.iter()
Expand Down
2 changes: 1 addition & 1 deletion src/client/terrain/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ use super::resources::MeshType;

#[derive(Component)]
pub struct ChunkMesh {
pub key: [i32; 3],
pub key: [i32; 2],
pub mesh_type: MeshType,
}
8 changes: 4 additions & 4 deletions src/client/terrain/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@ use crate::prelude::*;

#[derive(Message)]
pub struct ChunkMeshUpdateEvent {
pub chunk_position: IVec3,
pub chunk_position: ChunkPosition,
}

#[derive(Message)]
pub struct RerequestChunks {
pub center_chunk_position: IVec3,
pub center_chunk_position: ChunkPosition,
}

#[derive(Message)]
pub struct RequestChunkBatch {
pub positions: Vec<IVec3>,
pub positions: Vec<ChunkPosition>,
}

#[derive(Message)]
pub struct CleanupChunksAroundOrigin {
pub center_chunk_position: IVec3,
pub center_chunk_position: ChunkPosition,
}

#[derive(Message)]
Expand Down
24 changes: 11 additions & 13 deletions src/client/terrain/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl SpawnRegionLoaded {

#[derive(Resource, Default)]
pub struct RequestedChunks {
pub previous_chunks: HashSet<IVec3>,
pub previous_chunks: HashSet<ChunkPosition>,
}

#[derive(Eq, Hash, Clone, PartialEq)]
Expand All @@ -31,7 +31,7 @@ pub struct ChunkMeshes {

pub struct MeshTask(pub Task<ChunkMeshes>);
pub struct FutureChunkMesh {
pub position: IVec3,
pub position: ChunkPosition,
pub meshes_task: MeshTask,
}

Expand All @@ -42,12 +42,12 @@ pub struct MesherTasks {

#[derive(Resource, Default)]
pub struct ChunkEntityMap {
map: HashMap<IVec3, Vec<Entity>>,
map: HashMap<ChunkPosition, Vec<Entity>>,
}

#[derive(Resource, Default)]
pub struct SpawnRegion {
pub origin_chunk_position: IVec3,
pub origin_chunk_position: ChunkPosition,
}

impl SpawnRegion {
Expand All @@ -63,25 +63,23 @@ impl ChunkEntityMap {
self.map.len()
}

pub fn add(&mut self, chunk_position: IVec3, entity: Entity) {
pub fn add(&mut self, chunk_position: ChunkPosition, entity: Entity) {
self.map.entry(chunk_position).or_default().push(entity);
}

pub fn remove(&mut self, chunk_position: IVec3) -> Option<Vec<Entity>> {
pub fn remove(&mut self, chunk_position: ChunkPosition) -> Option<Vec<Entity>> {
self.map.remove(&chunk_position)
}

pub fn extract_outside_distance(
&mut self,
origin: &IVec3,
distance: &IVec3,
) -> Vec<(IVec3, Vec<Entity>)> {
let extracted: HashMap<IVec3, Vec<Entity>> = self
origin: &ChunkPosition,
distance: &IVec2,
) -> Vec<(ChunkPosition, Vec<Entity>)> {
let extracted: HashMap<ChunkPosition, Vec<Entity>> = self
.map
.extract_if(|k, _v| {
(k.x - origin.x).abs() > distance.x
|| (k.y - origin.y).abs() > distance.y
|| (k.z - origin.z).abs() > distance.z
(k.x - origin.x).abs() > distance[0] || (k.z - origin.z).abs() > distance[1]
})
.collect();

Expand Down
41 changes: 18 additions & 23 deletions src/client/terrain/systems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use terrain_resources::{

use crate::prelude::*;

const RENDER_DISTANCE: IVec3 = IVec3::new(4, 4, 4);
const CLEANUP_DISTANCE: IVec3 = IVec3::new(6, 6, 6);
const MIN_SPAWN_AREA_DISTANCE: IVec3 = IVec3::new(1, 1, 1);
const RENDER_DISTANCE: IVec2 = IVec2::new(4, 4);
const CLEANUP_DISTANCE: IVec2 = IVec2::new(6, 6);
const MIN_SPAWN_AREA_DISTANCE: IVec2 = IVec2::new(1, 1);

pub fn prepare_mesher_materials_system(
mut render_materials: ResMut<RenderMaterials>,
Expand Down Expand Up @@ -60,16 +60,16 @@ pub fn handle_chunk_request_chunk_batch_event_system(
return;
}

let mut new_positions: HashSet<IVec3> = HashSet::new();
let mut new_positions: HashSet<ChunkPosition> = HashSet::new();
for batch_event in batch_events.read() {
batch_event.positions.iter().for_each(|position| {
new_positions.insert(*position);
});
}

let old_positions = &all_requests.previous_chunks;
let diff: HashSet<&IVec3> = new_positions.difference(old_positions).collect();
let diff: Vec<IVec3> = diff.into_iter().copied().collect();
let diff: HashSet<&ChunkPosition> = new_positions.difference(old_positions).collect();
let diff: Vec<ChunkPosition> = diff.into_iter().copied().collect();

let batched_positions = diff.chunks(32);

Expand Down Expand Up @@ -131,8 +131,8 @@ pub fn handle_chunk_rerequests_system(

fn create_mesh_task(chunk: &Chunk, texture_manager: &terrain_util::TextureManager) -> MeshTask {
let task_pool = AsyncComputeTaskPool::get();
let chunk = *chunk;
let texture_manager = texture_manager.clone();
let chunk = chunk.clone();
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can no longer copy chunks.
Storing them on stack yields StackOverflow errors as the memory requirements are too large, hence the heap.

MeshTask(task_pool.spawn(async move {
ChunkMeshes {
cube_mesh: terrain_util::create_cube_mesh_for_chunk(&chunk, &texture_manager),
Expand Down Expand Up @@ -165,10 +165,9 @@ pub fn handle_chunk_tasks_system(
};

completed += 1;
let pos = future_chunk.position;
let pos_vec = pos.as_vec3();
let chunk_position = future_chunk.position;

if let Some(entities) = chunk_entities.remove(pos) {
if let Some(entities) = chunk_entities.remove(chunk_position) {
entities.iter().for_each(|entity| {
commands.entity(*entity).despawn();
})
Expand All @@ -178,25 +177,25 @@ pub fn handle_chunk_tasks_system(
let entity = commands
.spawn(create_chunk_bundle(
meshes.add(mesh),
pos_vec,
chunk_position,
MeshType::Transparent,
materials.transparent_material.clone().unwrap(),
))
.id();
chunk_entities.add(pos, entity);
chunk_entities.add(chunk_position, entity);
}

if let Some(mesh) = mesh_option.cube_mesh {
let entity = commands
.spawn(create_chunk_bundle(
meshes.add(mesh),
pos_vec,
chunk_position,
MeshType::Solid,
materials.chunk_material.clone().unwrap(),
))
.insert(player_components::Raycastable)
.id();
chunk_entities.add(pos, entity);
chunk_entities.add(chunk_position, entity);
}

DISCARD
Expand Down Expand Up @@ -246,7 +245,7 @@ pub fn check_if_spawn_area_is_loaded_system(

fn create_chunk_bundle(
mesh_handle: Handle<Mesh>,
chunk_position: Vec3,
chunk_position: ChunkPosition,
mesh_type: MeshType,
material_handle: Handle<StandardMaterial>,
) -> (
Expand All @@ -258,16 +257,12 @@ fn create_chunk_bundle(
(
Mesh3d(mesh_handle),
Transform::from_xyz(
chunk_position.x * CHUNK_SIZE as f32,
chunk_position.y * CHUNK_SIZE as f32,
chunk_position.z * CHUNK_SIZE as f32,
chunk_position.x as f32 * CHUNK_SIZE as f32,
0.0,
chunk_position.z as f32 * CHUNK_SIZE as f32,
),
terrain_components::ChunkMesh {
key: [
chunk_position.x as i32,
chunk_position.y as i32,
chunk_position.z as i32,
],
key: [chunk_position.x, chunk_position.z],
mesh_type,
},
MeshMaterial3d(material_handle),
Expand Down
2 changes: 1 addition & 1 deletion src/client/terrain/util/cross_mesher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fn create_cross_geometry_for_chunk(
let mut index_offset = 0;

for x in 0..CHUNK_SIZE {
for y in 0..CHUNK_SIZE {
for y in 0..CHUNK_HEIGHT {
for z in 0..CHUNK_SIZE {
let block_id = chunk.get(x as i32, y as i32, z as i32);
let pos = Vec3::new(x as f32, y as f32, z as f32);
Expand Down
17 changes: 13 additions & 4 deletions src/client/terrain/util/cube_mesher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pub fn create_cube_mesh_for_chunk(chunk: &Chunk, texture_manager: &TextureManage
};

for x in 1..CHUNK_SIZE + 1 {
for y in 1..CHUNK_SIZE + 1 {
for y in 0..CHUNK_HEIGHT {
for z in 1..CHUNK_SIZE + 1 {
let block_id = chunk.get_unpadded(x, y, z);

Expand All @@ -89,8 +89,17 @@ pub fn create_cube_mesh_for_chunk(chunk: &Chunk, texture_manager: &TextureManage

let mut mask = 0b000000;

update_mask(chunk, &mut mask, 0b000001, x, y + 1, z);
update_mask(chunk, &mut mask, 0b000010, x, y - 1, z);
if y >= 1 {
update_mask(chunk, &mut mask, 0b000010, x, y - 1, z);
} else {
// Don't render faces at bottom of world
}

if y < CHUNK_HEIGHT - 1 {
update_mask(chunk, &mut mask, 0b000001, x, y + 1, z);
} else {
mask |= 0b000001
}

update_mask(chunk, &mut mask, 0b000100, x + 1, y, z);
update_mask(chunk, &mut mask, 0b001000, x - 1, y, z);
Expand All @@ -100,7 +109,7 @@ pub fn create_cube_mesh_for_chunk(chunk: &Chunk, texture_manager: &TextureManage

let cube_data = create_cube_geometry_data(
(x - 1) as f32,
(y - 1) as f32,
(y) as f32,
(z - 1) as f32,
mask,
block_id,
Expand Down
4 changes: 2 additions & 2 deletions src/server/terrain/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub struct WorldConfig {
pub world_extension: String,
pub world_save_interval_seconds: i64,
pub world_backup_interval_seconds: i64,
pub spawn_area_distance: IVec3,
pub spawn_area_distance: IVec2,
}

impl Default for WorldConfig {
Expand All @@ -20,7 +20,7 @@ impl Default for WorldConfig {
world_extension: String::from(".rsmcw"),
world_save_interval_seconds: 30,
world_backup_interval_seconds: 180,
spawn_area_distance: IVec3::new(4, 3, 4),
spawn_area_distance: IVec2::new(4, 4),
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/server/terrain/persistence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ fn build_world_save_from_resources(
chunk_manager: &ChunkManager,
generator: &Generator,
) -> WorldSave {
let chunks = chunk_manager.all_chunks().into_iter().copied().collect();
let chunks = chunk_manager.all_chunks().into_iter().cloned().collect();
let generator = generator.clone();

WorldSave {
Expand Down Expand Up @@ -147,7 +147,7 @@ mod tests {
generator.params.density.squash_factor = 6.7;

let mut chunk_manager = ChunkManager::new();
let mut chunks = ChunkManager::instantiate_chunks(IVec3::ZERO, IVec3::ONE);
let mut chunks = ChunkManager::instantiate_chunks(ChunkPosition::ZERO, IVec2::ONE);

assert!(!chunks.is_empty());

Expand All @@ -168,15 +168,15 @@ mod tests {
#[test]
fn test_world_continuation() {
let generator = Generator::with_seed(0);
let mut possible_new_chunk = Chunk::new(IVec3::new(20, 0, 20));
let mut possible_new_chunk = Chunk::new(ChunkPosition::new(20, 20));
generator.generate_chunk(&mut possible_new_chunk);

save_world("my_world", &ChunkManager::new(), &generator).unwrap();

let world = read_world_save_by_name("my_world").unwrap();
let generator = world.generator;

let mut actual_new_chunk = Chunk::new(IVec3::new(20, 0, 20));
let mut actual_new_chunk = Chunk::new(ChunkPosition::new(20, 20));
generator.generate_chunk(&mut actual_new_chunk);

assert_eq!(possible_new_chunk.data, actual_new_chunk.data);
Expand Down
10 changes: 7 additions & 3 deletions src/server/terrain/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ use terrain_events::BlockUpdateEvent;

#[derive(Resource, Default)]
pub struct ClientChunkRequests {
queues: HashMap<ClientId, VecDeque<IVec3>>,
queues: HashMap<ClientId, VecDeque<ChunkPosition>>,
}

impl ClientChunkRequests {
pub fn enqueue_bulk(&mut self, client_id: ClientId, chunk_positions: &mut VecDeque<IVec3>) {
pub fn enqueue_bulk(
&mut self,
client_id: ClientId,
chunk_positions: &mut VecDeque<ChunkPosition>,
) {
self.queues
.entry(client_id)
.or_default()
Expand All @@ -26,7 +30,7 @@ impl ClientChunkRequests {

pub fn retain<F>(&mut self, f: F)
where
F: FnMut(&ClientId, &mut VecDeque<IVec3>) -> bool,
F: FnMut(&ClientId, &mut VecDeque<ChunkPosition>) -> bool,
{
self.queues.retain(f)
}
Expand Down
Loading