Minor Chunk gen speed gains
This commit is contained in:
parent
f80650c36c
commit
eaf5959f2b
@ -5,7 +5,7 @@
|
|||||||

|

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

|

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