mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
Minor Chunk gen speed gains
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||

|
||||
[](https://discord.gg/wT8XjrjKkf)
|
||||
[](https://opensource.org/licenses/MIT)
|
||||

|
||||

|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@@ -94,7 +94,7 @@ pub struct ChunkEntityData {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ChunkSections {
|
||||
pub sections: Box<[SubChunk]>,
|
||||
min_y: i32,
|
||||
pub min_y: i32,
|
||||
}
|
||||
|
||||
impl ChunkSections {
|
||||
@@ -179,18 +179,19 @@ impl ChunkSections {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the replaced block state ID
|
||||
pub fn set_block_absolute_y(
|
||||
&mut self,
|
||||
relative_x: usize,
|
||||
y: i32,
|
||||
relative_z: usize,
|
||||
block_state: BlockStateId,
|
||||
) {
|
||||
) -> BlockStateId {
|
||||
let y = y - self.min_y;
|
||||
debug_assert!(y >= 0);
|
||||
let relative_y = y as usize;
|
||||
|
||||
self.set_relative_block(relative_x, relative_y, relative_z, block_state);
|
||||
self.set_relative_block(relative_x, relative_y, relative_z, block_state)
|
||||
}
|
||||
|
||||
/// Gets the given block in the chunk
|
||||
@@ -210,7 +211,7 @@ impl ChunkSections {
|
||||
.map(|section| section.block_states.get(relative_x, relative_y, relative_z))
|
||||
}
|
||||
|
||||
/// Sets the given block in the chunk, returning the old block
|
||||
/// Sets the given block in the chunk, returning the old block state ID
|
||||
#[inline]
|
||||
pub fn set_relative_block(
|
||||
&mut self,
|
||||
@@ -218,9 +219,9 @@ impl ChunkSections {
|
||||
relative_y: usize,
|
||||
relative_z: usize,
|
||||
block_state_id: BlockStateId,
|
||||
) {
|
||||
) -> BlockStateId {
|
||||
// TODO @LUK_ESC? update the heightmap
|
||||
self.set_block_no_heightmap_update(relative_x, relative_y, relative_z, block_state_id);
|
||||
self.set_block_no_heightmap_update(relative_x, relative_y, relative_z, block_state_id)
|
||||
}
|
||||
|
||||
/// Sets the given block in the chunk, returning the old block
|
||||
@@ -234,20 +235,20 @@ impl ChunkSections {
|
||||
relative_y: usize,
|
||||
relative_z: usize,
|
||||
block_state_id: BlockStateId,
|
||||
) {
|
||||
) -> BlockStateId {
|
||||
debug_assert!(relative_x < BlockPalette::SIZE);
|
||||
debug_assert!(relative_z < BlockPalette::SIZE);
|
||||
|
||||
let section_index = relative_y / BlockPalette::SIZE;
|
||||
let relative_y = relative_y % BlockPalette::SIZE;
|
||||
if let Some(section) = self.sections.get_mut(section_index) {
|
||||
section
|
||||
return section
|
||||
.block_states
|
||||
.set(relative_x, relative_y, relative_z, block_state_id);
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// Sets the given block in the chunk, returning the old block
|
||||
pub fn set_relative_biome(
|
||||
&mut self,
|
||||
relative_x: usize,
|
||||
@@ -260,9 +261,11 @@ impl ChunkSections {
|
||||
|
||||
let section_index = relative_y / BiomePalette::SIZE;
|
||||
let relative_y = relative_y % BiomePalette::SIZE;
|
||||
self.sections[section_index]
|
||||
.biomes
|
||||
.set(relative_x, relative_y, relative_z, biome_id);
|
||||
if let Some(section) = self.sections.get_mut(section_index) {
|
||||
section
|
||||
.biomes
|
||||
.set(relative_x, relative_y, relative_z, biome_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@ impl<V: Hash + Eq + Copy, const DIM: usize> HeterogeneousPaletteData<V, DIM> {
|
||||
self.cube[y][z][x]
|
||||
}
|
||||
|
||||
fn set(&mut self, x: usize, y: usize, z: usize, value: V) {
|
||||
/// Returns the Original
|
||||
fn set(&mut self, x: usize, y: usize, z: usize, value: V) -> V {
|
||||
debug_assert!(x < DIM);
|
||||
debug_assert!(y < DIM);
|
||||
debug_assert!(z < DIM);
|
||||
@@ -48,6 +49,7 @@ impl<V: Hash + Eq + Copy, const DIM: usize> HeterogeneousPaletteData<V, DIM> {
|
||||
.entry(value)
|
||||
.and_modify(|count| *count += 1)
|
||||
.or_insert(1);
|
||||
original
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,24 +193,27 @@ impl<V: Hash + Eq + Copy + Default, const DIM: usize> PalettedContainer<V, DIM>
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set(&mut self, x: usize, y: usize, z: usize, value: V) {
|
||||
pub fn set(&mut self, x: usize, y: usize, z: usize, value: V) -> V {
|
||||
debug_assert!(x < Self::SIZE);
|
||||
debug_assert!(y < Self::SIZE);
|
||||
debug_assert!(z < Self::SIZE);
|
||||
|
||||
match self {
|
||||
Self::Homogeneous(original) => {
|
||||
if value != *original {
|
||||
let mut cube = Box::new([[[*original; DIM]; DIM]; DIM]);
|
||||
let original = *original;
|
||||
if value != original {
|
||||
let mut cube = Box::new([[[original; DIM]; DIM]; DIM]);
|
||||
cube[y][z][x] = value;
|
||||
*self = Self::from_cube(cube);
|
||||
}
|
||||
original
|
||||
}
|
||||
Self::Heterogeneous(data) => {
|
||||
data.set(x, y, z, value);
|
||||
let original = data.set(x, y, z, value);
|
||||
if data.counts.len() == 1 {
|
||||
*self = Self::Homogeneous(*data.counts.keys().next().unwrap());
|
||||
}
|
||||
original
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,24 +90,34 @@ impl WorldGenerator for VanillaGenerator {
|
||||
proto_chunk.generate_features(level, block_registry);
|
||||
|
||||
for y in 0..biome_coords::from_block(generation_settings.shape.height) {
|
||||
for z in 0..BiomePalette::SIZE {
|
||||
for x in 0..BiomePalette::SIZE {
|
||||
let absolute_y =
|
||||
biome_coords::from_block(generation_settings.shape.min_y as i32) + y as i32;
|
||||
let biome =
|
||||
proto_chunk.get_biome(&Vector3::new(x as i32, absolute_y, z as i32));
|
||||
sections.set_relative_biome(x, y as usize, z, biome.id);
|
||||
let relative_y = y as usize;
|
||||
let section_index = relative_y / BiomePalette::SIZE;
|
||||
let relative_y = relative_y % BiomePalette::SIZE;
|
||||
if let Some(section) = sections.sections.get_mut(section_index) {
|
||||
for z in 0..BiomePalette::SIZE {
|
||||
for x in 0..BiomePalette::SIZE {
|
||||
let absolute_y =
|
||||
biome_coords::from_block(generation_settings.shape.min_y as i32)
|
||||
+ y as i32;
|
||||
let biome =
|
||||
proto_chunk.get_biome(&Vector3::new(x as i32, absolute_y, z as i32));
|
||||
section.biomes.set(x, relative_y, z, biome.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for y in 0..generation_settings.shape.height {
|
||||
for z in 0..BlockPalette::SIZE {
|
||||
for x in 0..BlockPalette::SIZE {
|
||||
let absolute_y = generation_settings.shape.min_y as i32 + y as i32;
|
||||
let block =
|
||||
proto_chunk.get_block_state(&Vector3::new(x as i32, absolute_y, z as i32));
|
||||
sections.set_relative_block(x, y as usize, z, block.0);
|
||||
let relative_y = (y as i32 - sections.min_y) as usize;
|
||||
let section_index = relative_y / BlockPalette::SIZE;
|
||||
let relative_y = relative_y % BlockPalette::SIZE;
|
||||
if let Some(section) = sections.sections.get_mut(section_index) {
|
||||
for z in 0..BlockPalette::SIZE {
|
||||
for x in 0..BlockPalette::SIZE {
|
||||
let absolute_y = generation_settings.shape.min_y as i32 + y as i32;
|
||||
let block = proto_chunk
|
||||
.get_block_state(&Vector3::new(x as i32, absolute_y, z as i32));
|
||||
section.block_states.set(x, relative_y, z, block.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -621,23 +621,15 @@ impl Level {
|
||||
let chunk = self.get_chunk(chunk_coordinate).await;
|
||||
let mut chunk = chunk.write().await;
|
||||
|
||||
let replaced_block_state_id = chunk
|
||||
.section
|
||||
.get_block_absolute_y(relative.x as usize, relative.y, relative.z as usize)
|
||||
.unwrap();
|
||||
|
||||
if replaced_block_state_id == block_state_id {
|
||||
return block_state_id;
|
||||
}
|
||||
|
||||
chunk.mark_dirty(true);
|
||||
|
||||
chunk.section.set_block_absolute_y(
|
||||
let replaced_block_state_id = chunk.section.set_block_absolute_y(
|
||||
relative.x as usize,
|
||||
relative.y,
|
||||
relative.z as usize,
|
||||
block_state_id,
|
||||
);
|
||||
if replaced_block_state_id != block_state_id {
|
||||
chunk.mark_dirty(true);
|
||||
}
|
||||
replaced_block_state_id
|
||||
}
|
||||
|
||||
|
||||
@@ -1836,7 +1836,6 @@ impl World {
|
||||
}
|
||||
|
||||
/// Sets a block and returns the old block id
|
||||
#[expect(clippy::too_many_lines)]
|
||||
pub async fn set_block_state(
|
||||
self: &Arc<Self>,
|
||||
position: &BlockPos,
|
||||
@@ -1850,26 +1849,17 @@ impl World {
|
||||
else {
|
||||
panic!("Timed out while waiting to acquire chunk write lock")
|
||||
};
|
||||
let Some(replaced_block_state_id) = chunk.section.get_block_absolute_y(
|
||||
relative.x as usize,
|
||||
relative.y,
|
||||
relative.z as usize,
|
||||
) else {
|
||||
return block_state_id;
|
||||
};
|
||||
|
||||
if replaced_block_state_id == block_state_id {
|
||||
return block_state_id;
|
||||
}
|
||||
|
||||
chunk.mark_dirty(true);
|
||||
|
||||
chunk.section.set_block_absolute_y(
|
||||
let replaced_block_state_id = chunk.section.set_block_absolute_y(
|
||||
relative.x as usize,
|
||||
relative.y,
|
||||
relative.z as usize,
|
||||
block_state_id,
|
||||
);
|
||||
if replaced_block_state_id == block_state_id {
|
||||
return block_state_id;
|
||||
}
|
||||
chunk.mark_dirty(true);
|
||||
|
||||
self.unsent_block_changes
|
||||
.lock()
|
||||
.await
|
||||
|
||||
Reference in New Issue
Block a user