mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-18 03:44:54 -04:00
fluid culling
This commit is contained in:
parent
f2247e7fa3
commit
b907ae65e7
@ -16,7 +16,6 @@ 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.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
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
|
||||
@ -28,9 +27,6 @@ abstract class FlowableFluid(
|
||||
registries: Registries,
|
||||
data: Map<String, Any>,
|
||||
) : Fluid(resourceLocation, registries, data) {
|
||||
abstract val flowingTextureName: ResourceLocation
|
||||
var flowingTexture: AbstractTexture? = null
|
||||
|
||||
|
||||
abstract fun getVelocityMultiplier(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i): Double
|
||||
|
||||
|
@ -40,7 +40,9 @@ open class Fluid(
|
||||
) : RegistryItem() {
|
||||
open val tintProvider: TintProvider? = null
|
||||
open val stillTextureName: ResourceLocation? = null
|
||||
open val flowingTextureName: ResourceLocation? = null
|
||||
var stillTexture: AbstractTexture? = null
|
||||
var flowingTexture: AbstractTexture? = null
|
||||
val dripParticle: ParticleType? = null
|
||||
val bucketItem: Item? = null
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
package de.bixilon.minosoft.gui.rendering.models
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.models.properties.AbstractFaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies
|
||||
|
||||
object CullUtil {
|
||||
|
||||
fun Array<FaceProperties>.canCull(properties: FaceProperties, blockCull: Boolean): Boolean {
|
||||
fun Array<AbstractFaceProperties>.canCull(properties: AbstractFaceProperties, blockCull: Boolean): Boolean {
|
||||
// ToDo: Sometimes faces get drawn between stairs (we need to swap xy with yx in special cases)
|
||||
val sizeStartX = properties.sizeStart.x
|
||||
val sizeStartY = properties.sizeStart.y
|
||||
|
@ -15,8 +15,8 @@ package de.bixilon.minosoft.gui.rendering.models.baked
|
||||
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.block.BakedBlockModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.properties.AbstractFaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
||||
import glm_.vec3.Vec3i
|
||||
@ -24,11 +24,11 @@ import java.util.*
|
||||
|
||||
class MultipartBakedModel(
|
||||
val models: Array<BakedBlockModel>,
|
||||
val sizes: Array<Array<FaceProperties>>,
|
||||
val sizes: Array<Array<AbstractFaceProperties>>,
|
||||
val particleTexture: AbstractTexture?,
|
||||
) : BakedBlockModel {
|
||||
|
||||
override fun getTouchingFaceProperties(random: Random, direction: Directions): Array<FaceProperties> {
|
||||
override fun getTouchingFaceProperties(random: Random, direction: Directions): Array<AbstractFaceProperties> {
|
||||
return sizes[direction.ordinal]
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,8 @@ package de.bixilon.minosoft.gui.rendering.models.baked
|
||||
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.block.BakedBlockModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.properties.AbstractFaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
||||
@ -38,7 +38,7 @@ class WeightedBakedModel(
|
||||
this.totalWeight = totalWeight
|
||||
}
|
||||
|
||||
override fun getTouchingFaceProperties(random: Random, direction: Directions): Array<FaceProperties> {
|
||||
override fun getTouchingFaceProperties(random: Random, direction: Directions): Array<AbstractFaceProperties> {
|
||||
return getModel(random).getTouchingFaceProperties(random, direction)
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,8 @@ package de.bixilon.minosoft.gui.rendering.models.baked.block
|
||||
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.BakedModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.properties.AbstractFaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
||||
import glm_.vec3.Vec3i
|
||||
@ -24,7 +24,7 @@ import java.util.*
|
||||
|
||||
interface BakedBlockModel : BakedModel {
|
||||
|
||||
fun getTouchingFaceProperties(random: Random, direction: Directions): Array<FaceProperties>
|
||||
fun getTouchingFaceProperties(random: Random, direction: Directions): Array<AbstractFaceProperties>
|
||||
|
||||
fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, light: ByteArray, ambientLight: FloatArray, tints: IntArray?): Boolean
|
||||
|
||||
|
@ -16,7 +16,7 @@ package de.bixilon.minosoft.gui.rendering.models.baked.block
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.gui.rendering.models.CullUtil.canCull
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.models.properties.AbstractFaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.getWorldOffset
|
||||
@ -28,11 +28,11 @@ import java.util.*
|
||||
|
||||
class BakedBlockStateModel(
|
||||
private val faces: Array<Array<BakedFace>>,
|
||||
private val touchingFaceProperties: Array<Array<FaceProperties>>,
|
||||
private val touchingFaceProperties: Array<Array<AbstractFaceProperties>>,
|
||||
private val particleTexture: AbstractTexture?,
|
||||
) : BakedBlockModel {
|
||||
|
||||
override fun getTouchingFaceProperties(random: Random, direction: Directions): Array<FaceProperties> {
|
||||
override fun getTouchingFaceProperties(random: Random, direction: Directions): Array<AbstractFaceProperties> {
|
||||
return touchingFaceProperties[direction.ordinal]
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ class BakedBlockStateModel(
|
||||
val direction = Directions.VALUES[index]
|
||||
val neighbour = neighbours[index]
|
||||
val neighboursModel = neighbour?.blockModel
|
||||
var neighbourProperties: Array<FaceProperties>? = null
|
||||
var neighbourProperties: Array<AbstractFaceProperties>? = null
|
||||
if (neighboursModel != null) {
|
||||
random.setSeed(VecUtil.generatePositionHash(position.x + direction.vector.x, position.y + direction.vector.y, position.z + direction.vector.z))
|
||||
neighbourProperties = neighboursModel.getTouchingFaceProperties(random, direction.inverted)
|
||||
|
@ -16,7 +16,7 @@ package de.bixilon.minosoft.gui.rendering.models.baked.block
|
||||
import de.bixilon.minosoft.data.Axes
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.models.properties.AbstractFaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.getMesh
|
||||
@ -37,7 +37,7 @@ class BakedFace(
|
||||
val cullFace: Directions?,
|
||||
val texture: AbstractTexture,
|
||||
val touching: Boolean,
|
||||
) : FaceProperties {
|
||||
) : AbstractFaceProperties {
|
||||
override val transparency: TextureTransparencies
|
||||
get() = texture.transparency // ToDo
|
||||
|
||||
|
@ -11,12 +11,12 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.models
|
||||
package de.bixilon.minosoft.gui.rendering.models.properties
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies
|
||||
import glm_.vec2.Vec2
|
||||
|
||||
interface FaceProperties {
|
||||
interface AbstractFaceProperties {
|
||||
val sizeStart: Vec2
|
||||
val sizeEnd: Vec2
|
||||
val transparency: TextureTransparencies
|
@ -0,0 +1,10 @@
|
||||
package de.bixilon.minosoft.gui.rendering.models.properties
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies
|
||||
import glm_.vec2.Vec2
|
||||
|
||||
data class FaceProperties(
|
||||
override val sizeStart: Vec2,
|
||||
override val sizeEnd: Vec2,
|
||||
override val transparency: TextureTransparencies,
|
||||
) : AbstractFaceProperties
|
@ -17,10 +17,10 @@ import de.bixilon.minosoft.data.Axes
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.block.BakedBlockModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.block.BakedBlockStateModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.block.BakedFace
|
||||
import de.bixilon.minosoft.gui.rendering.models.properties.AbstractFaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.models.unbaked.GenericUnbakedModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.unbaked.UnbakedBlockModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.unbaked.UnbakedModel
|
||||
@ -86,7 +86,7 @@ data class UnbakedBlockStateModel(
|
||||
|
||||
|
||||
val faces: Array<MutableList<BakedFace>> = Array(Directions.SIZE) { mutableListOf() }
|
||||
val touchingFaceProperties: Array<MutableList<FaceProperties>> = Array(Directions.SIZE) { mutableListOf() }
|
||||
val touchingFaceProperties: Array<MutableList<AbstractFaceProperties>> = Array(Directions.SIZE) { mutableListOf() }
|
||||
|
||||
for (element in model.elements) {
|
||||
for (face in element.faces) {
|
||||
@ -169,7 +169,7 @@ data class UnbakedBlockStateModel(
|
||||
finalFaces[index] = faceArray.toTypedArray()
|
||||
}
|
||||
|
||||
val finalTouchingProperties: Array<Array<FaceProperties>?> = arrayOfNulls(faces.size)
|
||||
val finalTouchingProperties: Array<Array<AbstractFaceProperties>?> = arrayOfNulls(faces.size)
|
||||
for ((index, sizeArray) in touchingFaceProperties.withIndex()) {
|
||||
finalTouchingProperties[index] = sizeArray.toTypedArray()
|
||||
}
|
||||
|
@ -2,10 +2,10 @@ package de.bixilon.minosoft.gui.rendering.models.unbaked.block
|
||||
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.BakedModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.MultipartBakedModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.block.BakedBlockModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.properties.AbstractFaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.models.unbaked.UnbakedModel
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.EMPTY
|
||||
@ -19,7 +19,7 @@ class UnbakedMultipartModel(
|
||||
|
||||
override fun bake(renderWindow: RenderWindow): BakedModel {
|
||||
val baked: Array<BakedBlockModel?> = arrayOfNulls(this.models.size)
|
||||
val sizes: Array<MutableList<FaceProperties>> = Array(Directions.SIZE) { mutableListOf() }
|
||||
val sizes: Array<MutableList<AbstractFaceProperties>> = Array(Directions.SIZE) { mutableListOf() }
|
||||
var particleTexture: AbstractTexture? = null
|
||||
|
||||
for ((index, model) in this.models.withIndex()) {
|
||||
@ -35,7 +35,7 @@ class UnbakedMultipartModel(
|
||||
}
|
||||
baked[index] = bakedModel
|
||||
}
|
||||
val finalFaces: Array<Array<FaceProperties>?> = arrayOfNulls(Directions.SIZE)
|
||||
val finalFaces: Array<Array<AbstractFaceProperties>?> = arrayOfNulls(Directions.SIZE)
|
||||
for (index in 0 until Directions.SIZE) {
|
||||
finalFaces[index] = sizes[index].toTypedArray()
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ class WorldRenderer(
|
||||
|
||||
connection.registries.fluidRegistry.forEachItem {
|
||||
if (it is FlowableFluid) {
|
||||
it.flowingTexture = renderWindow.textureManager.staticTextures.createTexture(it.flowingTextureName.texture())
|
||||
it.flowingTexture = renderWindow.textureManager.staticTextures.createTexture(it.flowingTextureName!!.texture())
|
||||
}
|
||||
it.stillTexture = it.stillTextureName?.let { texture -> renderWindow.textureManager.staticTextures.createTexture(texture.texture()) }
|
||||
}
|
||||
|
@ -12,8 +12,12 @@ import de.bixilon.minosoft.data.world.Chunk
|
||||
import de.bixilon.minosoft.data.world.ChunkSection
|
||||
import de.bixilon.minosoft.data.world.World
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.models.CullUtil.canCull
|
||||
import de.bixilon.minosoft.gui.rendering.models.properties.FaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.getMesh
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rotate
|
||||
@ -29,6 +33,7 @@ import glm_.vec2.Vec2
|
||||
import glm_.vec2.Vec2i
|
||||
import glm_.vec3.Vec3
|
||||
import glm_.vec3.Vec3i
|
||||
import java.util.*
|
||||
import kotlin.math.atan2
|
||||
|
||||
class FluidCullSectionPreparer(
|
||||
@ -70,15 +75,18 @@ class FluidCullSectionPreparer(
|
||||
block is FluidFillable -> block.fluid
|
||||
else -> continue
|
||||
}
|
||||
val stillTexture = fluid.stillTexture ?: continue
|
||||
val flowingTexture = fluid.flowingTexture ?: continue
|
||||
position = Vec3i(offsetX + x, offsetY + y, offsetZ + z)
|
||||
tints = tintManager.getAverageTint(chunk, neighbourChunks, blockState, fluid, position.x, position.y, position.z)
|
||||
|
||||
val skipTop = fluid.matches(chunk.get(x, offsetY + y + 1, z))
|
||||
val skipBottom = !shouldRenderSide(position, Directions.DOWN)
|
||||
val skipNorth = !shouldRenderSide(position, Directions.NORTH)
|
||||
val skipSouth = !shouldRenderSide(position, Directions.SOUTH)
|
||||
val skipWest = !shouldRenderSide(position, Directions.WEST)
|
||||
val skipEast = !shouldRenderSide(position, Directions.EAST)
|
||||
// ToDo
|
||||
val skipBottom = !shouldRenderSide(position, Directions.DOWN, fluid, flowingTexture) /* ToDo */
|
||||
val skipNorth = !shouldRenderSide(position, Directions.NORTH, fluid, flowingTexture)
|
||||
val skipSouth = !shouldRenderSide(position, Directions.SOUTH, fluid, flowingTexture)
|
||||
val skipWest = !shouldRenderSide(position, Directions.WEST, fluid, flowingTexture)
|
||||
val skipEast = !shouldRenderSide(position, Directions.EAST, fluid, flowingTexture)
|
||||
|
||||
if (skipTop && skipBottom && skipNorth && skipSouth && skipWest && skipEast) {
|
||||
continue
|
||||
@ -189,6 +197,7 @@ class FluidCullSectionPreparer(
|
||||
v2 = cornerHeights[2]
|
||||
}
|
||||
}
|
||||
// ToDo: Prevent face fighting with transparent neighbours
|
||||
|
||||
val positions = arrayOf(
|
||||
Vec3(position.x + faceX, position.y + v1, position.z + faceZ),
|
||||
@ -203,11 +212,9 @@ class FluidCullSectionPreparer(
|
||||
Vec2(0.0f, v1 / 2),
|
||||
)
|
||||
|
||||
val texture = (fluid as FlowableFluid).flowingTexture!!
|
||||
|
||||
val meshToUse = texture.transparency.getMesh(mesh)
|
||||
val meshToUse = flowingTexture.transparency.getMesh(mesh)
|
||||
for ((positionIndex, textureIndex) in meshToUse.order) {
|
||||
meshToUse.addVertex(positions[positionIndex].array, texturePositions[textureIndex], texture, tints?.get(0) ?: 0xFFFFFF, 0xFF)
|
||||
meshToUse.addVertex(positions[positionIndex].array, texturePositions[textureIndex], flowingTexture, tints?.get(0) ?: 0xFFFFFF, chunk.getLight(position))
|
||||
}
|
||||
rendered = true
|
||||
}
|
||||
@ -229,12 +236,25 @@ class FluidCullSectionPreparer(
|
||||
return mesh
|
||||
}
|
||||
|
||||
private fun isSideCovered(position: Vec3i, direction: Directions, height: Float): Boolean {
|
||||
return world[position + direction] != null
|
||||
private fun isSideCovered(position: Vec3i, direction: Directions, texture: AbstractTexture, height: Float): Boolean {
|
||||
val faceProperties = FaceProperties(
|
||||
Vec2.EMPTY,
|
||||
Vec2(1.0f, height),
|
||||
TextureTransparencies.OPAQUE,
|
||||
)
|
||||
val neighbourPosition = position + direction
|
||||
val neighbour = world[neighbourPosition] ?: return false
|
||||
val model = neighbour.blockModel ?: return false
|
||||
val random = Random(VecUtil.generatePositionHash(neighbourPosition.x, neighbourPosition.y, neighbourPosition.z))
|
||||
val size = model.getTouchingFaceProperties(random, direction.inverted)
|
||||
return size.canCull(faceProperties, false)
|
||||
}
|
||||
|
||||
private fun shouldRenderSide(position: Vec3i, direction: Directions, height: Float = 1.0f): Boolean {
|
||||
return !isSideCovered(position, direction, height) /* && fluid.matches(other) */
|
||||
private fun shouldRenderSide(position: Vec3i, direction: Directions, fluid: Fluid, texture: AbstractTexture, height: Float = 1.0f): Boolean {
|
||||
if (fluid.matches(world[position + direction])) {
|
||||
return false
|
||||
}
|
||||
return !isSideCovered(position, direction, texture, height)
|
||||
}
|
||||
|
||||
private fun getCornerHeight(position: Vec3i, fluid: Fluid): Float {
|
||||
|
Loading…
x
Reference in New Issue
Block a user