mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 03:15:35 -04:00
count FluidFillable blocks as fluid, restructure some fluid stuff
This commit is contained in:
parent
1fdb1b6403
commit
5fc6b606bb
@ -13,8 +13,8 @@
|
||||
|
||||
package de.bixilon.minosoft.data.registries.blocks.types
|
||||
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.data.registries.fluid.Fluid
|
||||
|
||||
interface FluidFillable {
|
||||
val fluid: ResourceLocation
|
||||
val fluid: Fluid
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
package de.bixilon.minosoft.data.world.container
|
||||
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
||||
import de.bixilon.minosoft.data.registries.blocks.types.FluidBlock
|
||||
import de.bixilon.minosoft.data.registries.blocks.types.FluidFillable
|
||||
import de.bixilon.minosoft.util.KUtil.unsafeCast
|
||||
|
||||
class BlockSectionDataProvider(
|
||||
@ -16,7 +18,7 @@ class BlockSectionDataProvider(
|
||||
|
||||
fluidCount = 0
|
||||
for (blockState in data) {
|
||||
if (blockState?.block is FluidBlock) {
|
||||
if (blockState.isFluid()) {
|
||||
fluidCount++
|
||||
}
|
||||
}
|
||||
@ -24,13 +26,29 @@ class BlockSectionDataProvider(
|
||||
|
||||
override fun set(index: Int, value: BlockState?): BlockState? {
|
||||
val previous = super.set(index, value)
|
||||
val previousFluid = previous.isFluid()
|
||||
val valueFluid = value.isFluid()
|
||||
|
||||
if (previous?.block !is FluidBlock && value?.block is FluidBlock) {
|
||||
if (!previousFluid && valueFluid) {
|
||||
fluidCount++
|
||||
} else if (previous?.block is FluidBlock && value?.block !is FluidBlock) {
|
||||
} else if (previousFluid && !valueFluid) {
|
||||
fluidCount--
|
||||
}
|
||||
|
||||
return previous
|
||||
}
|
||||
|
||||
private fun BlockState?.isFluid(): Boolean {
|
||||
this ?: return false
|
||||
if (this.block is FluidBlock) {
|
||||
return true
|
||||
}
|
||||
if (properties[BlockProperties.WATERLOGGED] == true) {
|
||||
return true
|
||||
}
|
||||
if (this.block is FluidFillable) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -49,8 +49,10 @@ import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.toVec3
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.SectionMesh
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.VisibleMeshes
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
||||
import de.bixilon.minosoft.gui.rendering.world.preparer.AbstractSectionPreparer
|
||||
import de.bixilon.minosoft.gui.rendering.world.preparer.CullSectionPreparer
|
||||
import de.bixilon.minosoft.gui.rendering.world.preparer.FluidSectionPreparer
|
||||
import de.bixilon.minosoft.gui.rendering.world.preparer.SolidSectionPreparer
|
||||
import de.bixilon.minosoft.gui.rendering.world.preparer.cull.FluidCullSectionPreparer
|
||||
import de.bixilon.minosoft.gui.rendering.world.preparer.cull.SolidCullSectionPreparer
|
||||
import de.bixilon.minosoft.modding.event.events.*
|
||||
import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionStateChangeEvent
|
||||
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
|
||||
@ -84,7 +86,8 @@ class WorldRenderer(
|
||||
private val shader = renderSystem.createShader("minosoft:world".toResourceLocation())
|
||||
private val transparentShader = renderSystem.createShader("minosoft:world".toResourceLocation())
|
||||
private val world: World = connection.world
|
||||
private val sectionPreparer: AbstractSectionPreparer = CullSectionPreparer(renderWindow)
|
||||
private val solidSectionPreparer: SolidSectionPreparer = SolidCullSectionPreparer(renderWindow)
|
||||
private val fluidSectionPreparer: FluidSectionPreparer = FluidCullSectionPreparer(renderWindow)
|
||||
private val lightMap = LightMap(connection)
|
||||
|
||||
private val loadedMeshes: MutableMap<Vec2i, MutableMap<Int, SectionMesh>> = mutableMapOf() // all prepared (and up to date) meshes
|
||||
@ -106,8 +109,8 @@ class WorldRenderer(
|
||||
|
||||
// all meshes that will be rendered in the next frame (might be changed, when the frustum changes or a chunk gets loaded, ...)
|
||||
private var clearVisibleNextFrame = false
|
||||
private var visibleSolid = VisibleMeshes()
|
||||
private var visibleFluid = VisibleMeshes()
|
||||
private var visibleSolid = VisibleMeshes() // This name might be confusing. Those faces are from blocks.
|
||||
private var visibleFluid = VisibleMeshes() // Fluids disable FACE_CULLING. Blocks that have waterlogged=true also twice
|
||||
|
||||
|
||||
private var cameraPosition = Vec3.EMPTY
|
||||
@ -354,9 +357,9 @@ class WorldRenderer(
|
||||
val section = chunk[item.sectionHeight] ?: return@Runnable end()
|
||||
val neighbourChunks: Array<Chunk> = world.getChunkNeighbours(item.chunkPosition).unsafeCast()
|
||||
val neighbours = item.neighbours ?: ChunkUtil.getSectionNeighbours(neighbourChunks, chunk, item.sectionHeight)
|
||||
item.solidMesh = sectionPreparer.prepareSolid(item.chunkPosition, item.sectionHeight, chunk, section, neighbours, neighbourChunks)
|
||||
item.solidMesh = solidSectionPreparer.prepareSolid(item.chunkPosition, item.sectionHeight, chunk, section, neighbours, neighbourChunks)
|
||||
if (section.blocks.fluidCount > 0) {
|
||||
item.fluidMesh = sectionPreparer.prepareFluid(item.chunkPosition, item.sectionHeight, chunk, section, neighbours, neighbourChunks)
|
||||
item.fluidMesh = fluidSectionPreparer.prepareFluid(item.chunkPosition, item.sectionHeight, chunk, section, neighbours, neighbourChunks)
|
||||
}
|
||||
meshesToLoadLock.lock()
|
||||
locked = true
|
||||
|
@ -5,9 +5,7 @@ import de.bixilon.minosoft.data.world.ChunkSection
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
||||
import glm_.vec2.Vec2i
|
||||
|
||||
interface AbstractSectionPreparer {
|
||||
|
||||
fun prepareSolid(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk, section: ChunkSection, neighbours: Array<ChunkSection?>, neighbourChunks: Array<Chunk>): WorldMesh?
|
||||
interface FluidSectionPreparer {
|
||||
|
||||
fun prepareFluid(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk, section: ChunkSection, neighbours: Array<ChunkSection?>, neighbourChunks: Array<Chunk>): WorldMesh?
|
||||
}
|
@ -31,7 +31,7 @@ import java.util.*
|
||||
@Deprecated("TODO")
|
||||
class GreedySectionPreparer(
|
||||
val renderWindow: RenderWindow,
|
||||
) : AbstractSectionPreparer {
|
||||
) : SolidSectionPreparer {
|
||||
|
||||
private fun renderNormal(block: BlockState, directions: Directions?, position: Vec3i, section: ChunkSection, mesh: SingleWorldMesh, random: Random) {
|
||||
val neighbour = section.blocks[ChunkSection.getIndex(position.x, position.y, position.z)]
|
||||
@ -235,8 +235,4 @@ class GreedySectionPreparer(
|
||||
|
||||
TODO()
|
||||
}
|
||||
|
||||
override fun prepareFluid(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk, section: ChunkSection, neighbours: Array<ChunkSection?>, neighbourChunks: Array<Chunk>): WorldMesh? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
package de.bixilon.minosoft.gui.rendering.world.preparer
|
||||
|
||||
import de.bixilon.minosoft.data.world.Chunk
|
||||
import de.bixilon.minosoft.data.world.ChunkSection
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
||||
import glm_.vec2.Vec2i
|
||||
|
||||
interface SolidSectionPreparer {
|
||||
|
||||
fun prepareSolid(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk, section: ChunkSection, neighbours: Array<ChunkSection?>, neighbourChunks: Array<Chunk>): WorldMesh?
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package de.bixilon.minosoft.gui.rendering.world.preparer.cull
|
||||
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
||||
import de.bixilon.minosoft.data.registries.blocks.types.FluidBlock
|
||||
import de.bixilon.minosoft.data.registries.blocks.types.FluidFillable
|
||||
import de.bixilon.minosoft.data.registries.fluid.DefaultFluids
|
||||
import de.bixilon.minosoft.data.world.Chunk
|
||||
import de.bixilon.minosoft.data.world.ChunkSection
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
||||
import de.bixilon.minosoft.gui.rendering.world.preparer.FluidSectionPreparer
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.util.chunk.ChunkUtil.acquire
|
||||
import de.bixilon.minosoft.util.chunk.ChunkUtil.release
|
||||
import de.bixilon.minosoft.util.logging.Log
|
||||
import de.bixilon.minosoft.util.logging.LogLevels
|
||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
import glm_.vec2.Vec2i
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
class FluidCullSectionPreparer(
|
||||
val renderWindow: RenderWindow,
|
||||
) : FluidSectionPreparer {
|
||||
private val water = renderWindow.connection.registries.fluidRegistry[DefaultFluids.WATER]
|
||||
private val tintColorCalculator = renderWindow.tintManager
|
||||
|
||||
|
||||
override fun prepareFluid(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk, section: ChunkSection, neighbours: Array<ChunkSection?>, neighbourChunks: Array<Chunk>): WorldMesh? {
|
||||
val mesh = WorldMesh(renderWindow, chunkPosition, sectionHeight, smallMesh = true)
|
||||
|
||||
val isLowestSection = sectionHeight == chunk.lowestSection
|
||||
val isHighestSection = sectionHeight == chunk.highestSection
|
||||
val blocks = section.blocks
|
||||
val sectionLight = section.light
|
||||
section.acquire()
|
||||
neighbours.acquire()
|
||||
|
||||
var blockState: BlockState
|
||||
var position: Vec3i
|
||||
var rendered = false
|
||||
var tints: IntArray?
|
||||
|
||||
val offsetX = chunkPosition.x * ProtocolDefinition.SECTION_WIDTH_X
|
||||
val offsetY = sectionHeight * ProtocolDefinition.SECTION_HEIGHT_Y
|
||||
val offsetZ = chunkPosition.y * ProtocolDefinition.SECTION_WIDTH_Z
|
||||
|
||||
for (x in 0 until ProtocolDefinition.SECTION_WIDTH_X) {
|
||||
for (y in 0 until ProtocolDefinition.SECTION_HEIGHT_Y) {
|
||||
for (z in 0 until ProtocolDefinition.SECTION_WIDTH_Z) {
|
||||
blockState = blocks.unsafeGet(x, y, z) ?: continue
|
||||
val block = blockState.block
|
||||
val fluid = when {
|
||||
block is FluidBlock -> (blockState.block as FluidBlock).fluid
|
||||
blockState.properties[BlockProperties.WATERLOGGED] == true && water != null -> water
|
||||
block is FluidFillable -> block.fluid
|
||||
else -> continue
|
||||
}
|
||||
Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Can not render fluid: $fluid" }
|
||||
|
||||
|
||||
if (rendered) {
|
||||
mesh.addBlock(x, y, z)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
section.release()
|
||||
neighbours.release()
|
||||
|
||||
if (mesh.clearEmpty() == 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
return mesh
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package de.bixilon.minosoft.gui.rendering.world.preparer
|
||||
package de.bixilon.minosoft.gui.rendering.world.preparer.cull
|
||||
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.direction.Directions.Companion.O_DOWN
|
||||
@ -8,29 +8,24 @@ import de.bixilon.minosoft.data.direction.Directions.Companion.O_SOUTH
|
||||
import de.bixilon.minosoft.data.direction.Directions.Companion.O_UP
|
||||
import de.bixilon.minosoft.data.direction.Directions.Companion.O_WEST
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
||||
import de.bixilon.minosoft.data.registries.blocks.types.FluidBlock
|
||||
import de.bixilon.minosoft.data.registries.fluid.DefaultFluids
|
||||
import de.bixilon.minosoft.data.world.Chunk
|
||||
import de.bixilon.minosoft.data.world.ChunkSection
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.block.BakedBlockModel
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
||||
import de.bixilon.minosoft.gui.rendering.world.preparer.SolidSectionPreparer
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.util.chunk.ChunkUtil.acquire
|
||||
import de.bixilon.minosoft.util.chunk.ChunkUtil.release
|
||||
import de.bixilon.minosoft.util.logging.Log
|
||||
import de.bixilon.minosoft.util.logging.LogLevels
|
||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
import glm_.vec2.Vec2i
|
||||
import glm_.vec3.Vec3i
|
||||
import java.util.*
|
||||
|
||||
class CullSectionPreparer(
|
||||
class SolidCullSectionPreparer(
|
||||
val renderWindow: RenderWindow,
|
||||
) : AbstractSectionPreparer {
|
||||
private val water = renderWindow.connection.registries.fluidRegistry[DefaultFluids.WATER]
|
||||
) : SolidSectionPreparer {
|
||||
private val tintColorCalculator = renderWindow.tintManager
|
||||
private val ambientLight = floatArrayOf(1.0f, 1.0f, 1.0f, 1.0f)
|
||||
|
||||
@ -141,50 +136,4 @@ class CullSectionPreparer(
|
||||
|
||||
return mesh
|
||||
}
|
||||
|
||||
override fun prepareFluid(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk, section: ChunkSection, neighbours: Array<ChunkSection?>, neighbourChunks: Array<Chunk>): WorldMesh? {
|
||||
val mesh = WorldMesh(renderWindow, chunkPosition, sectionHeight, smallMesh = true)
|
||||
|
||||
val isLowestSection = sectionHeight == chunk.lowestSection
|
||||
val isHighestSection = sectionHeight == chunk.highestSection
|
||||
val blocks = section.blocks
|
||||
val sectionLight = section.light
|
||||
section.acquire()
|
||||
neighbours.acquire()
|
||||
|
||||
var blockState: BlockState
|
||||
var position: Vec3i
|
||||
var rendered = false
|
||||
var tints: IntArray?
|
||||
|
||||
val offsetX = chunkPosition.x * ProtocolDefinition.SECTION_WIDTH_X
|
||||
val offsetY = sectionHeight * ProtocolDefinition.SECTION_HEIGHT_Y
|
||||
val offsetZ = chunkPosition.y * ProtocolDefinition.SECTION_WIDTH_Z
|
||||
|
||||
for (x in 0 until ProtocolDefinition.SECTION_WIDTH_X) {
|
||||
for (y in 0 until ProtocolDefinition.SECTION_HEIGHT_Y) {
|
||||
for (z in 0 until ProtocolDefinition.SECTION_WIDTH_Z) {
|
||||
blockState = blocks.unsafeGet(x, y, z) ?: continue
|
||||
val fluid = when {
|
||||
blockState.block is FluidBlock -> (blockState.block as FluidBlock).fluid
|
||||
blockState.properties[BlockProperties.WATERLOGGED] == true && water != null -> water
|
||||
else -> continue
|
||||
}
|
||||
Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Can not render fluid: $fluid" }
|
||||
|
||||
if (rendered) {
|
||||
mesh.addBlock(x, y, z)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
section.release()
|
||||
neighbours.release()
|
||||
|
||||
if (mesh.clearEmpty() == 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
return mesh
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user