From fbf95e4f8d9bfd336674ee96bdb10617ae05a1af Mon Sep 17 00:00:00 2001 From: Moritz Zwerger Date: Fri, 28 Jul 2023 00:33:56 +0200 Subject: [PATCH] move chunk neighbour tracing to chunk neighbours --- .../minosoft/data/world/WorldTestUtil.kt | 4 +- .../minosoft/camera/target/TargetHandler.kt | 2 +- .../minosoft/data/registries/fluid/Fluid.kt | 2 +- .../de/bixilon/minosoft/data/world/World.kt | 2 +- .../minosoft/data/world/chunk/chunk/Chunk.kt | 71 +------------------ .../world/chunk/neighbours/ChunkNeighbours.kt | 66 +++++++++++++++++ .../data/world/iterator/WorldIterator.kt | 2 +- .../particle/types/render/RenderParticle.kt | 2 +- .../gui/rendering/sky/box/SkyboxRenderer.kt | 2 +- .../minosoft/physics/EntityPositionInfo.kt | 2 +- .../packets/s2c/play/ExplosionS2CP.kt | 2 +- 11 files changed, 77 insertions(+), 80 deletions(-) diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/data/world/WorldTestUtil.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/WorldTestUtil.kt index 46520f0ef..ea71d7826 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/data/world/WorldTestUtil.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/WorldTestUtil.kt @@ -73,7 +73,7 @@ object WorldTestUtil { if (chunk == null) { chunk = this.chunks[chunkPosition] ?: continue } else if (chunk.chunkPosition != chunkPosition) { - chunk = chunk.traceChunk(chunkPosition - chunk.chunkPosition) ?: continue + chunk = chunk.neighbours.trace(chunkPosition - chunk.chunkPosition) ?: continue } for (y in start.y..end.y) { val section = chunk.getOrPut(y.sectionHeight) ?: continue @@ -96,7 +96,7 @@ object WorldTestUtil { for (z in (start.z shr 4)..(end.z shr 4)) { val chunkPosition = Vec2i(x, z) chunk = if (chunk != null) { - chunk.traceChunk(chunkPosition - chunk.chunkPosition) ?: continue + chunk.neighbours.trace(chunkPosition - chunk.chunkPosition) ?: continue } else { this.chunks[chunkPosition] ?: continue } diff --git a/src/main/java/de/bixilon/minosoft/camera/target/TargetHandler.kt b/src/main/java/de/bixilon/minosoft/camera/target/TargetHandler.kt index 5bf68eb30..3e85646df 100644 --- a/src/main/java/de/bixilon/minosoft/camera/target/TargetHandler.kt +++ b/src/main/java/de/bixilon/minosoft/camera/target/TargetHandler.kt @@ -124,7 +124,7 @@ class TargetHandler( if (chunk == null) { chunk = camera.connection.world.chunks[chunkPosition] ?: break } else if (chunk.chunkPosition != chunkPosition) { - chunk = chunk.traceChunk(chunkPosition - chunk.chunkPosition) ?: break + chunk = chunk.neighbours.trace(chunkPosition - chunk.chunkPosition) ?: break } val state = chunk[blockPosition.inChunkPosition] ?: continue if (state.block is FluidBlock) { diff --git a/src/main/java/de/bixilon/minosoft/data/registries/fluid/Fluid.kt b/src/main/java/de/bixilon/minosoft/data/registries/fluid/Fluid.kt index 197a93b38..04403e8e5 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/fluid/Fluid.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/fluid/Fluid.kt @@ -54,7 +54,7 @@ abstract class Fluid(override val identifier: ResourceLocation) : RegistryItem() val offset = blockPosition.inChunkPosition for (direction in Directions.SIDES) { - val neighbour = chunk.traceBlock(offset + direction) ?: continue + val neighbour = chunk.neighbours.traceBlock(offset + direction) ?: continue if (!this.matches(neighbour)) { continue } diff --git a/src/main/java/de/bixilon/minosoft/data/world/World.kt b/src/main/java/de/bixilon/minosoft/data/world/World.kt index b1d7fe616..d2930237c 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/World.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/World.kt @@ -187,7 +187,7 @@ class World( chunkDelta.x = (origin.x - position.x) shr 4 chunkDelta.y = (origin.z - position.z) shr 4 - val state = chunk.traceBlock(position.x and 0x0F, position.y, position.z and 0x0F, chunkDelta) ?: return + val state = chunk.neighbours.traceBlock(position.x and 0x0F, position.y, position.z and 0x0F, chunkDelta) ?: return if (state.block !is RandomDisplayTickable) return if (!state.block.hasRandomTicks(connection, state, position)) return diff --git a/src/main/java/de/bixilon/minosoft/data/world/chunk/chunk/Chunk.kt b/src/main/java/de/bixilon/minosoft/data/world/chunk/chunk/Chunk.kt index ed2c01de4..1841788c9 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/chunk/chunk/Chunk.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/chunk/chunk/Chunk.kt @@ -15,7 +15,6 @@ package de.bixilon.minosoft.data.world.chunk.chunk import de.bixilon.kotlinglm.vec2.Vec2i import de.bixilon.kotlinglm.vec3.Vec3i import de.bixilon.kutil.concurrent.lock.thread.ThreadLock -import de.bixilon.kutil.exception.Broken import de.bixilon.kutil.math.simple.IntMath.clamp import de.bixilon.kutil.reflection.ReflectionUtil.forceSet import de.bixilon.minosoft.data.direction.Directions @@ -31,15 +30,12 @@ import de.bixilon.minosoft.data.world.chunk.neighbours.ChunkNeighbours import de.bixilon.minosoft.data.world.chunk.update.block.ChunkLocalBlockUpdate import de.bixilon.minosoft.data.world.chunk.update.block.SingleBlockUpdate import de.bixilon.minosoft.data.world.positions.ChunkPosition -import de.bixilon.minosoft.data.world.positions.ChunkPositionUtil.chunkPosition import de.bixilon.minosoft.data.world.positions.InChunkPosition import de.bixilon.minosoft.data.world.positions.SectionHeight import de.bixilon.minosoft.gui.rendering.util.VecUtil.inSectionHeight import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight -import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.inChunkPosition import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition -import de.bixilon.minosoft.util.chunk.ChunkUtil import java.util.* /** @@ -65,10 +61,6 @@ class Chunk( light.heightmap.recalculate() } - @Deprecated("neighbours.complete", ReplaceWith("neighbours.complete")) - val isFullyLoaded: Boolean - get() = neighbours.complete - operator fun get(sectionHeight: SectionHeight): ChunkSection? = sections.getOrNull(sectionHeight - minSection) operator fun get(x: Int, y: Int, z: Int): BlockState? { @@ -203,7 +195,7 @@ class Chunk( if (neighbours != null) { for (neighbour in neighbours) { val neighbourNeighbours = neighbour.neighbours.get() ?: continue - neighbour.updateNeighbours(neighbourNeighbours, sectionHeight) + neighbour.neighbours.update(neighbourNeighbours, sectionHeight) } } @@ -235,67 +227,6 @@ class Chunk( } return biomeSource.getBiome(x and 0x0F, y, z and 0x0F) } - - @Deprecated("") - private fun updateNeighbours(neighbours: Array, sectionHeight: Int) { - for (nextSectionHeight in sectionHeight - 1..sectionHeight + 1) { - if (nextSectionHeight < minSection || nextSectionHeight > maxSection) { - continue - } - - val section = this[nextSectionHeight] ?: continue - val sectionNeighbours = ChunkUtil.getDirectNeighbours(neighbours, this, nextSectionHeight) - section.neighbours = sectionNeighbours - } - } - - @Deprecated("neighbours") - fun traceBlock(offset: Vec3i, origin: Vec3i, blockPosition: Vec3i = origin + offset): BlockState? { - val chunkDelta = (origin - blockPosition).chunkPosition - - return traceBlock(blockPosition.x and 0x0F, blockPosition.y, blockPosition.z and 0x0F, chunkDelta) - } - - @Deprecated("neighbours") - fun traceBlock(offset: Vec3i): BlockState? { - return traceBlock(offset.inChunkPosition, offset.chunkPosition) - } - - @Deprecated("neighbours") - fun traceChunk(offset: Vec2i): Chunk? { - if (offset.x == 0 && offset.y == 0) { - return this - } - - if (offset.x > 0) { - offset.x-- - return neighbours[6]?.traceChunk(offset) - } - if (offset.x < 0) { - offset.x++ - return neighbours[1]?.traceChunk(offset) - } - if (offset.y > 0) { - offset.y-- - return neighbours[4]?.traceChunk(offset) - } - if (offset.y < 0) { - offset.y++ - return neighbours[3]?.traceChunk(offset) - } - - Broken("Can not get chunk from offset: $offset") - } - - @Deprecated("neighbours") - private fun traceBlock(inChunkPosition: Vec3i, chunkOffset: Vec2i): BlockState? { - return traceChunk(chunkOffset)?.get(inChunkPosition) - } - - @Deprecated("neighbours") - fun traceBlock(x: Int, y: Int, z: Int, chunkOffset: Vec2i): BlockState? { - return traceChunk(chunkOffset)?.get(x, y, z) - } } diff --git a/src/main/java/de/bixilon/minosoft/data/world/chunk/neighbours/ChunkNeighbours.kt b/src/main/java/de/bixilon/minosoft/data/world/chunk/neighbours/ChunkNeighbours.kt index 0038b5f39..0a51514a2 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/chunk/neighbours/ChunkNeighbours.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/chunk/neighbours/ChunkNeighbours.kt @@ -14,12 +14,16 @@ package de.bixilon.minosoft.data.world.chunk.neighbours import de.bixilon.kotlinglm.vec2.Vec2i +import de.bixilon.kotlinglm.vec3.Vec3i import de.bixilon.kutil.cast.CastUtil.unsafeCast import de.bixilon.kutil.exception.Broken +import de.bixilon.minosoft.data.registries.blocks.state.BlockState import de.bixilon.minosoft.data.world.biome.accessor.NoiseBiomeAccessor import de.bixilon.minosoft.data.world.chunk.ChunkSection import de.bixilon.minosoft.data.world.chunk.chunk.Chunk +import de.bixilon.minosoft.data.world.positions.ChunkPositionUtil.chunkPosition import de.bixilon.minosoft.data.world.positions.SectionHeight +import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.inChunkPosition import de.bixilon.minosoft.util.chunk.ChunkUtil class ChunkNeighbours(val chunk: Chunk) : Iterable { @@ -100,6 +104,68 @@ class ChunkNeighbours(val chunk: Chunk) : Iterable { return neighbours.iterator() } + + fun update(neighbours: Array, sectionHeight: Int) { + for (nextSectionHeight in sectionHeight - 1..sectionHeight + 1) { + if (nextSectionHeight < chunk.minSection || nextSectionHeight > chunk.maxSection) { + continue + } + + val section = chunk[nextSectionHeight] ?: continue + val sectionNeighbours = ChunkUtil.getDirectNeighbours(neighbours, chunk, nextSectionHeight) + section.neighbours = sectionNeighbours + } + } + + fun trace(offset: Vec2i): Chunk? { + if (offset.x == 0 && offset.y == 0) { + return chunk + } + + val chunk = when { + offset.x > 0 -> { + offset.x-- + this[6] + } + + offset.x < 0 -> { + offset.x++ + this[1] + } + + offset.y < 0 -> { + offset.y-- + this[4] + } + + offset.y > 0 -> { + offset.y++ + this[3] + } + + else -> Broken("Can not get chunk from offset: $offset") + } + return chunk?.neighbours?.trace(offset) + } + + fun traceBlock(offset: Vec3i, origin: Vec3i, blockPosition: Vec3i = origin + offset): BlockState? { + val chunkDelta = (origin - blockPosition).chunkPosition + + return traceBlock(blockPosition.x and 0x0F, blockPosition.y, blockPosition.z and 0x0F, chunkDelta) + } + + fun traceBlock(offset: Vec3i): BlockState? { + return traceBlock(offset.inChunkPosition, offset.chunkPosition) + } + + private fun traceBlock(inChunkPosition: Vec3i, chunkOffset: Vec2i): BlockState? { + return trace(chunkOffset)?.get(inChunkPosition) + } + + fun traceBlock(x: Int, y: Int, z: Int, chunkOffset: Vec2i): BlockState? { + return trace(chunkOffset)?.get(x, y, z) + } + companion object { const val COUNT = 8 const val NORTH = 3 diff --git a/src/main/java/de/bixilon/minosoft/data/world/iterator/WorldIterator.kt b/src/main/java/de/bixilon/minosoft/data/world/iterator/WorldIterator.kt index d484f46d7..a413ad8cc 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/iterator/WorldIterator.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/iterator/WorldIterator.kt @@ -57,7 +57,7 @@ class WorldIterator( } else if (chunk.chunkPosition != chunkPosition) { offset.x = chunkPosition.x - chunk.chunkPosition.x offset.y = chunkPosition.y - chunk.chunkPosition.y - chunk = chunk.traceChunk(offset) ?: continue + chunk = chunk.neighbours.trace(offset) ?: continue } if (this.chunk !== chunk) { this.chunk = chunk diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/RenderParticle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/RenderParticle.kt index 8009e629d..997fed166 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/RenderParticle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/RenderParticle.kt @@ -55,7 +55,7 @@ abstract class RenderParticle(connection: PlayConnection, position: Vec3d, veloc inChunk.y = position.y inChunk.z = position.z and 0x0F - val light = chunk.traceChunk(offset)?.light?.get(inChunk) ?: SectionLight.SKY_LIGHT_MASK + val light = chunk.neighbours.trace(offset)?.light?.get(inChunk) ?: SectionLight.SKY_LIGHT_MASK if (light and SectionLight.BLOCK_LIGHT_MASK > maxBlockLight) { maxBlockLight = light and SectionLight.BLOCK_LIGHT_MASK } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/box/SkyboxRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/box/SkyboxRenderer.kt index 272cc3e66..f3b028aa1 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/box/SkyboxRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/box/SkyboxRenderer.kt @@ -232,7 +232,7 @@ class SkyboxRenderer( val x = offset.x + xOffset val y = offset.y + yOffset val z = offset.z + zOffset - val neighbour = chunk.traceChunk(Vec2i(x shr 4, z shr 4)) ?: continue + val neighbour = chunk.neighbours.trace(Vec2i(x shr 4, z shr 4)) ?: continue val biome = neighbour.getBiome(x and 0x0F, y, z and 0x0F) ?: continue count++ diff --git a/src/main/java/de/bixilon/minosoft/physics/EntityPositionInfo.kt b/src/main/java/de/bixilon/minosoft/physics/EntityPositionInfo.kt index 023eca229..622e2df1e 100644 --- a/src/main/java/de/bixilon/minosoft/physics/EntityPositionInfo.kt +++ b/src/main/java/de/bixilon/minosoft/physics/EntityPositionInfo.kt @@ -63,7 +63,7 @@ class EntityPositionInfo( val chunks = physics.entity.connection.world.chunks val revision = chunks.revision - var chunk = if (previous.revision == revision) previous.chunk?.traceChunk(chunkPosition - previous.chunkPosition) else null + var chunk = if (previous.revision == revision) previous.chunk?.neighbours?.trace(chunkPosition - previous.chunkPosition) else null if (chunk == null) { chunk = chunks[chunkPosition] diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/ExplosionS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/ExplosionS2CP.kt index 9b7bf3be2..12f9e4601 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/ExplosionS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/ExplosionS2CP.kt @@ -72,7 +72,7 @@ class ExplosionS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { } else if (chunk.chunkPosition != chunkPosition) { chunkOffset.x = chunkPosition.x - chunk.chunkPosition.x chunkOffset.y = chunkPosition.y - chunk.chunkPosition.y - chunk = chunk.traceChunk(chunkOffset) ?: continue + chunk = chunk.neighbours.trace(chunkOffset) ?: continue } val inChunkPosition = total.inChunkPosition