diff --git a/build.gradle.kts b/build.gradle.kts index 79199ccb2..0c8885461 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -222,7 +222,7 @@ testing { options { val options = this as TestNGOptions options.preserveOrder = true - options.excludeGroups("chunk", "input", "font", "command", "registry", "biome", "version", "fluid", "world", "raycasting", "pixlyzer", "item", "block", "physics", "light", "packet", "container", "item_stack", "signature", "private_key", "interaction", "item_digging", "world_renderer", "rendering") + options.excludeGroups("chunk", "input", "font", "command", "registry", "biome", "version", "fluid", "world", "raycasting", "pixlyzer", "item", "block", "physics", "light", "packet", "container", "item_stack", "signature", "private_key", "interaction", "item_digging", "chunk_renderer", "rendering") } } } diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/chunk/ChunkRendererTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/chunk/ChunkRendererTest.kt index f36814fc9..d7fe0bb54 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/chunk/ChunkRendererTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/chunk/ChunkRendererTest.kt @@ -22,7 +22,7 @@ import de.bixilon.minosoft.gui.rendering.RenderTestUtil.frame import org.testng.Assert import org.testng.annotations.Test -@Test(groups = ["world_renderer"], dependsOnGroups = ["rendering", "block"]) +@Test(groups = ["chunk_renderer"], dependsOnGroups = ["rendering", "block"]) class ChunkRendererTest { private fun create(): ChunkRenderer { diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/chunk/mesher/FluidSectionMesherTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/chunk/mesher/FluidSectionMesherTest.kt new file mode 100644 index 000000000..c5c2a45ad --- /dev/null +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/chunk/mesher/FluidSectionMesherTest.kt @@ -0,0 +1,42 @@ +/* + * Minosoft + * Copyright (C) 2020-2023 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.chunk.mesher + +import de.bixilon.kotlinglm.vec3.Vec3i +import de.bixilon.kutil.cast.CastUtil.unsafeNull +import de.bixilon.minosoft.data.registries.fluid.fluids.LavaFluid +import de.bixilon.minosoft.data.registries.fluid.fluids.WaterFluid +import de.bixilon.minosoft.gui.rendering.chunk.mesh.ChunkMesh +import org.testng.annotations.Test + +@Test(groups = ["mesher"], dependsOnGroups = ["rendering", "block"], enabled = false) +class FluidSectionMesherTest { + private var water: WaterFluid = unsafeNull() + private var lava: LavaFluid = unsafeNull() + + @Test(priority = -1) + fun load() { + + } + + + private fun mesh(data: Map): ChunkMesh { + TODO() + } + + fun `simple water without surrounding blocks`() { + val mesh = mesh(mapOf(Vec3i(2, 2, 2) to water)) + TODO() + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkRenderer.kt index 438fd450f..5460a6a39 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkRenderer.kt @@ -26,6 +26,7 @@ import de.bixilon.minosoft.data.world.World import de.bixilon.minosoft.gui.rendering.RenderContext import de.bixilon.minosoft.gui.rendering.RenderingStates import de.bixilon.minosoft.gui.rendering.chunk.mesh.VisibleMeshes +import de.bixilon.minosoft.gui.rendering.chunk.mesher.ChunkMesher import de.bixilon.minosoft.gui.rendering.chunk.queue.CulledQueue import de.bixilon.minosoft.gui.rendering.chunk.queue.QueuePosition import de.bixilon.minosoft.gui.rendering.chunk.queue.loading.MeshLoadingQueue diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkMesher.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/ChunkMesher.kt similarity index 93% rename from src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkMesher.kt rename to src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/ChunkMesher.kt index f6dd16629..3036c605e 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkMesher.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/ChunkMesher.kt @@ -11,12 +11,12 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.gui.rendering.chunk +package de.bixilon.minosoft.gui.rendering.chunk.mesher import de.bixilon.kutil.concurrent.pool.runnable.InterruptableRunnable +import de.bixilon.minosoft.gui.rendering.chunk.ChunkRenderer +import de.bixilon.minosoft.gui.rendering.chunk.WorldQueueItem import de.bixilon.minosoft.gui.rendering.chunk.mesh.ChunkMesh -import de.bixilon.minosoft.gui.rendering.chunk.mesher.FluidSectionMesher -import de.bixilon.minosoft.gui.rendering.chunk.mesher.SolidSectionMesher import de.bixilon.minosoft.gui.rendering.chunk.queue.meshing.tasks.MeshPrepareTask import de.bixilon.minosoft.gui.rendering.chunk.util.ChunkRendererUtil.smallMesh import de.bixilon.minosoft.util.chunk.ChunkUtil diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/FluidSectionMesher.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/FluidSectionMesher.kt index 5e40d0580..64ecb1242 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/FluidSectionMesher.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/FluidSectionMesher.kt @@ -35,6 +35,7 @@ import de.bixilon.minosoft.gui.rendering.RenderContext import de.bixilon.minosoft.gui.rendering.chunk.mesh.ChunkMesh import de.bixilon.minosoft.gui.rendering.chunk.mesh.SingleChunkMesh import de.bixilon.minosoft.gui.rendering.models.block.state.baked.cull.FaceCulling +import de.bixilon.minosoft.gui.rendering.models.block.state.baked.cull.side.FaceProperties import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.getMesh import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus @@ -44,7 +45,6 @@ import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.chunkPosition import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.inChunkPosition import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.util.KUtil.isTrue -import java.util.* import kotlin.math.atan2 class FluidSectionMesher( @@ -53,13 +53,20 @@ class FluidSectionMesher( private val water = context.connection.registries.fluid[WaterFluid] private val tints = context.tints + private fun BlockState.getFluid(): Fluid? { + val block = block + return when { + block is FluidHolder -> block.fluid + water != null && isWaterlogged() -> water + else -> null + } + } + // ToDo: Should this be combined with the solid renderer (but we'd need to render faces twice, because of cullface) fun mesh(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk, section: ChunkSection, neighbourChunks: Array, neighbours: Array, mesh: ChunkMesh) { val blocks = section.blocks - val random = Random(0L) - var blockState: BlockState var position: Vec3i var rendered = false var tint: Int @@ -73,17 +80,11 @@ class FluidSectionMesher( for (y in blocks.minPosition.y..blocks.maxPosition.y) { for (z in blocks.minPosition.z..blocks.maxPosition.z) { for (x in blocks.minPosition.x..blocks.maxPosition.x) { - blockState = blocks[x, y, z] ?: continue - val block = blockState.block - val fluid = when { - block is FluidHolder -> block.fluid - water != null && blockState.isWaterlogged() -> water - else -> continue - } + val state = blocks[x, y, z] ?: continue + val fluid = state.getFluid() ?: continue + val model = fluid.model ?: continue - val stillTexture = model.still ?: continue - val flowingTexture = model.flowing ?: continue - val height = fluid.getHeight(blockState) + val height = fluid.getHeight(state) position = Vec3i(offsetX + x, offsetY + y, offsetZ + z) tint = tints.getFluidTint(chunk, fluid, height, position.x, position.y, position.z) ?: Colors.WHITE @@ -97,7 +98,7 @@ class FluidSectionMesher( return true } - return FaceCulling.canCull(blockState, model.properties, direction, neighbour) + return FaceCulling.canCull(state, FaceProperties(Vec2.EMPTY, Vec2(1.0f), model.transparency), direction, neighbour) } val topBlock = if (y == ProtocolDefinition.SECTION_MAX_Y) { @@ -129,7 +130,7 @@ class FluidSectionMesher( val offsetPosition = Vec3(position - cameraOffset) if (!skip[Directions.O_UP]) { - val velocity = fluid.getVelocity(blockState, position, chunk) + val velocity = fluid.getVelocity(state, position, chunk) val still = velocity.x == 0.0 && velocity.z == 0.0 val texture: Texture val minUV = Vec2.EMPTY @@ -145,9 +146,9 @@ class FluidSectionMesher( if (still) { - texture = stillTexture + texture = model.still } else { - texture = flowingTexture + texture = model.flowing maxUV.x = 0.5f val atan = atan2(velocity.x, velocity.z).toFloat() @@ -232,9 +233,9 @@ class FluidSectionMesher( TEXTURE_2, ) - val meshToUse = flowingTexture.transparency.getMesh(mesh) + val meshToUse = model.flowing.transparency.getMesh(mesh) val fluidLight = chunk.light[x, offsetY + y, z] - addFluidVertices(meshToUse, positions, texturePositions, flowingTexture, tint, fluidLight) + addFluidVertices(meshToUse, positions, texturePositions, model.flowing, tint, fluidLight) rendered = true } @@ -273,21 +274,21 @@ class FluidSectionMesher( return 1.0f } - val blockState = chunk[inChunkPosition] - if (blockState == null) { + val state = chunk[inChunkPosition] + if (state == null) { count++ continue } - if (!fluid.matches(blockState)) { + if (!fluid.matches(state)) { // TODO: this was !blockState.material.solid - if (blockState.block !is CollidableBlock || blockState.block.getCollisionShape(EmptyCollisionContext, blockPosition, blockState, null) == AbstractVoxelShape.EMPTY) { + if (state.block !is CollidableBlock || state.block.getCollisionShape(EmptyCollisionContext, blockPosition, state, null) == AbstractVoxelShape.EMPTY) { count++ } continue } - val height = fluid.getHeight(blockState) + val height = fluid.getHeight(state) if (height >= 0.8f) { totalHeight += height * 10.0f @@ -307,13 +308,5 @@ class FluidSectionMesher( private val TEXTURE_1 = Vec2(0.0f, 0.5f) private val TEXTURE_2 = Vec2(0.5f, 0.5f) - - /* - private val FLUID_FACE_PROPERTY = FaceProperties( - Vec2.EMPTY, - Vec2(1.0f, 1.0f), - TextureTransparencies.OPAQUE, - ) - */ } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/SingleBlockStateApply.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/SingleBlockStateApply.kt index 71199a64b..a7f7c9b7a 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/SingleBlockStateApply.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/SingleBlockStateApply.kt @@ -51,9 +51,8 @@ data class SingleBlockStateApply( for (index in 0 until VERTEX_DATA_COMPONENTS) { val offset = index * 3 val y = this[offset + 1] - val z = this[offset + 2] - this[offset + 1] = z + this[offset + 1] = this[offset + 2] this[offset + 2] = -y + 1.0f } } @@ -78,9 +77,8 @@ data class SingleBlockStateApply( for (index in 0 until VERTEX_DATA_COMPONENTS) { val offset = index * 3 val x = this[offset + 0] - val z = this[offset + 2] - this[offset + 0] = -z + 1.0f // translates to origin and back; same as -(z-0.5f) + 0.5f + this[offset + 0] = -this[offset + 2] + 1.0f // translates to origin and back; same as -(z-0.5f) + 0.5f this[offset + 2] = x } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/fluid/FluidModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/fluid/FluidModel.kt index 4f29703eb..db37c4944 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/fluid/FluidModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/fluid/FluidModel.kt @@ -14,15 +14,15 @@ package de.bixilon.minosoft.gui.rendering.models.fluid import de.bixilon.minosoft.gui.rendering.RenderContext -import de.bixilon.minosoft.gui.rendering.models.block.state.baked.cull.side.FaceProperties +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.tint.TintProvider interface FluidModel { val tint: TintProvider? get() = null - val still: Texture? - val flowing: Texture? - val properties: FaceProperties + val still: Texture + val flowing: Texture + val transparency: TextureTransparencies fun load(context: RenderContext) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/fluid/fluids/LavaFluidModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/fluid/fluids/LavaFluidModel.kt index a1433824e..5995d2402 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/fluid/fluids/LavaFluidModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/fluid/fluids/LavaFluidModel.kt @@ -13,20 +13,18 @@ package de.bixilon.minosoft.gui.rendering.models.fluid.fluids -import de.bixilon.kotlinglm.vec2.Vec2 +import de.bixilon.kutil.cast.CastUtil.unsafeNull import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft import de.bixilon.minosoft.gui.rendering.RenderContext -import de.bixilon.minosoft.gui.rendering.models.block.state.baked.cull.side.FaceProperties import de.bixilon.minosoft.gui.rendering.models.fluid.FluidModel import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture -import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY class LavaFluidModel : FluidModel { - override var still: Texture? = null - override var flowing: Texture? = null - override var properties = FaceProperties(Vec2.EMPTY, Vec2(1.0f), TextureTransparencies.OPAQUE) // TODO: determinate by texture + override var still: Texture = unsafeNull() + override var flowing: Texture = unsafeNull() + override val transparency = TextureTransparencies.OPAQUE// TODO: from texture override fun load(context: RenderContext) { still = context.textures.staticTextures.createTexture(STILL) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/fluid/fluids/WaterFluidModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/fluid/fluids/WaterFluidModel.kt index 113283579..6830b0f4b 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/fluid/fluids/WaterFluidModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/fluid/fluids/WaterFluidModel.kt @@ -13,24 +13,22 @@ package de.bixilon.minosoft.gui.rendering.models.fluid.fluids -import de.bixilon.kotlinglm.vec2.Vec2 +import de.bixilon.kutil.cast.CastUtil.unsafeNull import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft import de.bixilon.minosoft.gui.rendering.RenderContext -import de.bixilon.minosoft.gui.rendering.models.block.state.baked.cull.side.FaceProperties import de.bixilon.minosoft.gui.rendering.models.fluid.FluidModel import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture import de.bixilon.minosoft.gui.rendering.tint.TintProvider import de.bixilon.minosoft.gui.rendering.tint.WaterTintProvider -import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY class WaterFluidModel : FluidModel { override val tint: TintProvider = WaterTintProvider - override var still: Texture? = null - override var flowing: Texture? = null - override var properties = FaceProperties(Vec2.EMPTY, Vec2(1.0f), TextureTransparencies.TRANSLUCENT) // TODO: determinate by texture + override var still: Texture = unsafeNull() + override var flowing: Texture = unsafeNull() + override val transparency = TextureTransparencies.TRANSLUCENT// TODO: from texture override fun load(context: RenderContext) { still = context.textures.staticTextures.createTexture(STILL) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/loader/FluidModelLoader.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/loader/FluidModelLoader.kt index dc0d950df..75a76298e 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/loader/FluidModelLoader.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/loader/FluidModelLoader.kt @@ -33,9 +33,7 @@ class FluidModelLoader(private val loader: ModelLoader) { } private fun load(fluid: Fluid) { - if (fluid.model != null) { - return - } + if (fluid.model != null) return val model = fluid.createModel() ?: return fluid.model = model model.load(context)