diff --git a/src/main/java/de/bixilon/minosoft/data/direction/Directions.kt b/src/main/java/de/bixilon/minosoft/data/direction/Directions.kt index 2dbd2c6f0..981759881 100644 --- a/src/main/java/de/bixilon/minosoft/data/direction/Directions.kt +++ b/src/main/java/de/bixilon/minosoft/data/direction/Directions.kt @@ -13,9 +13,12 @@ package de.bixilon.minosoft.data.direction import de.bixilon.minosoft.data.Axes +import de.bixilon.minosoft.data.registries.blocks.BlockState import de.bixilon.minosoft.data.registries.blocks.properties.serializer.BlockPropertiesSerializer import de.bixilon.minosoft.data.text.ChatColors +import de.bixilon.minosoft.data.world.ChunkSection import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.get +import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.util.KUtil import de.bixilon.minosoft.util.enum.ValuesEnum import glm_.vec2.Vec2 @@ -108,6 +111,53 @@ enum class Directions( } } + fun getBlock(x: Int, y: Int, z: Int, section: ChunkSection, neighbours: Array): BlockState? { + return when (this) { + Directions.DOWN -> { + if (y == 0) { + neighbours[Directions.O_DOWN]?.blocks?.unsafeGet(x, ProtocolDefinition.SECTION_MAX_Y, z) + } else { + section.blocks.unsafeGet(x, y - 1, z) + } + } + Directions.UP -> { + if (y == ProtocolDefinition.SECTION_MAX_Y) { + neighbours[Directions.O_UP]?.blocks?.unsafeGet(x, 0, z) + } else { + section.blocks.unsafeGet(x, y + 1, z) + } + } + Directions.NORTH -> { + if (z == 0) { + neighbours[Directions.O_NORTH]?.blocks?.unsafeGet(x, y, ProtocolDefinition.SECTION_MAX_Z) + } else { + section.blocks.unsafeGet(x, y, z - 1) + } + } + Directions.SOUTH -> { + if (z == ProtocolDefinition.SECTION_MAX_Z) { + neighbours[Directions.O_SOUTH]?.blocks?.unsafeGet(x, y, 0) + } else { + section.blocks.unsafeGet(x, y, z + 1) + } + } + Directions.WEST -> { + if (x == 0) { + neighbours[Directions.O_WEST]?.blocks?.unsafeGet(ProtocolDefinition.SECTION_MAX_X, y, z) + } else { + section.blocks.unsafeGet(x - 1, y, z) + } + } + Directions.EAST -> { + if (x == ProtocolDefinition.SECTION_MAX_X) { + neighbours[Directions.O_EAST]?.blocks?.unsafeGet(0, y, z) + } else { + section.blocks.unsafeGet(x + 1, y, z) + } + } + } + } + companion object : BlockPropertiesSerializer, ValuesEnum { const val O_DOWN = 0 // Directions.DOWN.ordinal diff --git a/src/main/java/de/bixilon/minosoft/data/registries/fluid/FlowableFluid.kt b/src/main/java/de/bixilon/minosoft/data/registries/fluid/FlowableFluid.kt index ab7b0bf9b..746c33a81 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/fluid/FlowableFluid.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/fluid/FlowableFluid.kt @@ -16,6 +16,8 @@ import de.bixilon.minosoft.data.direction.Directions import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.registries.blocks.BlockState import de.bixilon.minosoft.data.registries.registries.Registries +import de.bixilon.minosoft.data.world.ChunkSection +import de.bixilon.minosoft.gui.rendering.util.VecUtil.inSectionHeight import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection @@ -30,7 +32,7 @@ abstract class FlowableFluid( abstract fun getVelocityMultiplier(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i): Double - open fun getVelocity(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i): Vec3d { + open fun getVelocity(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, section: ChunkSection? = null, neighbours: Array? = null): Vec3d { if (!this.matches(blockState)) { return Vec3d.EMPTY } @@ -39,7 +41,11 @@ abstract class FlowableFluid( val velocity = Vec3d.EMPTY for (direction in Directions.SIDES) { - val neighbourBlockState = connection.world[blockPosition + direction] ?: continue + val neighbourBlockState = if (section != null && neighbours != null) { + direction.getBlock(blockPosition.x and 0x0F, blockPosition.y.inSectionHeight, blockPosition.z and 0x0F, section, neighbours) + } else { + connection.world[blockPosition + direction] + } ?: continue if (!this.matches(neighbourBlockState)) { continue } diff --git a/src/main/java/de/bixilon/minosoft/data/world/Chunk.kt b/src/main/java/de/bixilon/minosoft/data/world/Chunk.kt index fb9c47dd3..8e29aa21d 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/Chunk.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/Chunk.kt @@ -57,6 +57,10 @@ class Chunk( operator fun get(sectionHeight: Int): ChunkSection? = sections?.getOrNull(sectionHeight - lowestSection) + fun unsafeGet(x: Int, y: Int, z: Int): BlockState? { + return this[y.sectionHeight]?.blocks?.unsafeGet(x, y.inSectionHeight, z) + } + fun get(x: Int, y: Int, z: Int): BlockState? { return this[y.sectionHeight]?.blocks?.get(x, y.inSectionHeight, z) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/preparer/cull/FluidCullSectionPreparer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/preparer/cull/FluidCullSectionPreparer.kt index 58bbbbfd4..c9596d130 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/preparer/cull/FluidCullSectionPreparer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/preparer/cull/FluidCullSectionPreparer.kt @@ -84,50 +84,7 @@ class FluidCullSectionPreparer( fun isSideCovered(direction: Directions): Boolean { val neighbourPosition = position + direction - val neighbour = when (direction) { - Directions.DOWN -> { - if (y == 0) { - neighbours[Directions.O_DOWN]?.blocks?.unsafeGet(x, ProtocolDefinition.SECTION_MAX_Y, z) - } else { - section.blocks.unsafeGet(x, y - 1, z) - } - } - Directions.UP -> { - if (y == ProtocolDefinition.SECTION_MAX_Y) { - neighbours[Directions.O_UP]?.blocks?.unsafeGet(x, 0, z) - } else { - section.blocks.unsafeGet(x, y + 1, z) - } - } - Directions.NORTH -> { - if (z == 0) { - neighbours[Directions.O_NORTH]?.blocks?.unsafeGet(x, y, ProtocolDefinition.SECTION_MAX_Z) - } else { - section.blocks.unsafeGet(x, y, z - 1) - } - } - Directions.SOUTH -> { - if (z == ProtocolDefinition.SECTION_MAX_Z) { - neighbours[Directions.O_SOUTH]?.blocks?.unsafeGet(x, y, 0) - } else { - section.blocks.unsafeGet(x, y, z + 1) - } - } - Directions.WEST -> { - if (x == 0) { - neighbours[Directions.O_WEST]?.blocks?.unsafeGet(ProtocolDefinition.SECTION_MAX_X, y, z) - } else { - section.blocks.unsafeGet(x - 1, y, z) - } - } - Directions.EAST -> { - if (x == ProtocolDefinition.SECTION_MAX_X) { - neighbours[Directions.O_EAST]?.blocks?.unsafeGet(0, y, z) - } else { - section.blocks.unsafeGet(x + 1, y, z) - } - } - } ?: return false + val neighbour = direction.getBlock(x, y, z, section, neighbours) ?: return false if (fluid.matches(neighbour)) { return true @@ -138,9 +95,15 @@ class FluidCullSectionPreparer( return size.canCull(FLUID_FACE_PROPERTY, false) } + val topBlock = if (y == ProtocolDefinition.SECTION_MAX_Y) { + neighbours[Directions.O_UP]?.blocks?.unsafeGet(x, 0, z) + } else { + section.blocks.unsafeGet(x, y + 1, z) + } + val skip = booleanArrayOf( isSideCovered(Directions.DOWN), /* ToDo */ - fluid.matches(chunk.get(x, offsetY + y + 1, z)), + fluid.matches(topBlock), isSideCovered(Directions.NORTH), isSideCovered(Directions.SOUTH), isSideCovered(Directions.WEST), @@ -159,7 +122,7 @@ class FluidCullSectionPreparer( ) if (!skip[Directions.O_UP]) { - val velocity = if (fluid is FlowableFluid) fluid.getVelocity(renderWindow.connection, blockState, position) else null + val velocity = if (fluid is FlowableFluid) fluid.getVelocity(renderWindow.connection, blockState, position, section, neighbours) else null val still = velocity == null || velocity.x == 0.0 && velocity.z == 0.0 val texture: AbstractTexture val minUV = Vec2.EMPTY