improve fluid velocity getting performance

This commit is contained in:
Bixilon 2021-11-24 23:40:36 +01:00
parent 2e521643e6
commit d3165e6a3c
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
4 changed files with 71 additions and 48 deletions

View File

@ -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<ChunkSection?>): 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<Directions> {
const val O_DOWN = 0 // Directions.DOWN.ordinal

View File

@ -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<ChunkSection?>? = 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
}

View File

@ -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)
}

View File

@ -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