mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 19:35:00 -04:00
rework some fluid models and rendering
This commit is contained in:
parent
67512e93e6
commit
5231b68e4a
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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<Vec3i, Any>): ChunkMesh {
|
||||
TODO()
|
||||
}
|
||||
|
||||
fun `simple water without surrounding blocks`() {
|
||||
val mesh = mesh(mapOf(Vec3i(2, 2, 2) to water))
|
||||
TODO()
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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
|
@ -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<Chunk>, neighbours: Array<ChunkSection?>, 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,
|
||||
)
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user