mesher: improve (fluid) perpare speed

This commit is contained in:
Bixilon 2022-05-04 19:45:00 +02:00
parent cea55b610a
commit 971ed120cf
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
12 changed files with 51 additions and 31 deletions

View File

@ -147,7 +147,7 @@ data class BlockState(
fallSoundEvent = data["fall_sound_type"]?.toInt()?.let { registries.soundEventRegistry[it] },
soundEventVolume = data["sound_type_volume"]?.toFloat() ?: 1.0f,
soundEventPitch = data["sound_type_pitch"]?.toFloat() ?: 1.0f,
isSolid = data["solid_render"]?.toBoolean() ?: true, // ToDo: This should normally be false, but pixlyzers default value is true. Might break if the data is missing
isSolid = data["solid_render"]?.toBoolean() ?: false,
)
}

View File

@ -73,7 +73,7 @@ class Chunk(
operator fun get(position: Vec3i): BlockState? = get(position.x, position.y, position.z)
fun set(x: Int, y: Int, z: Int, blockState: BlockState?, blockEntity: BlockEntity? = null) {
val section = getOrPut(y.sectionHeight)
val section = getOrPut(y.sectionHeight) ?: return
section.blocks[x, y.inSectionHeight, z] = blockState
section.blockEntities[x, y.inSectionHeight, z] = blockEntity // ToDo
}
@ -103,7 +103,7 @@ class Chunk(
return null
}
blockEntity = block.block.factory?.build(connection) ?: return null
this.getOrPut(sectionHeight).blockEntities[x, inSectionHeight, z] = blockEntity
(this.getOrPut(sectionHeight) ?: return null).blockEntities[x, inSectionHeight, z] = blockEntity
return blockEntity
}
@ -112,7 +112,7 @@ class Chunk(
fun getOrPutBlockEntity(position: Vec3i): BlockEntity? = getOrPutBlockEntity(position.x, position.y, position.z)
fun setBlockEntity(x: Int, y: Int, z: Int, blockEntity: BlockEntity?) {
getOrPut(y.sectionHeight).blockEntities[x, y.inSectionHeight, z] = blockEntity
(getOrPut(y.sectionHeight) ?: return).blockEntities[x, y.inSectionHeight, z] = blockEntity
}
fun setBlockEntity(position: Vec3i, blockEntity: BlockEntity?) = setBlockEntity(position.x, position.y, position.z, blockEntity)
@ -133,7 +133,7 @@ class Chunk(
data.blocks?.let {
for ((index, blocks) in it.withIndex()) {
blocks ?: continue
val section = getOrPut(index + lowestSection)
val section = getOrPut(index + lowestSection) ?: return@let
section.blocks = blocks
}
blocksInitialized = true
@ -146,7 +146,7 @@ class Chunk(
data.light?.let {
for ((index, light) in it.withIndex()) {
light ?: continue
val section = getOrPut(index + lowestSection)
val section = getOrPut(index + lowestSection) ?: return@let
section.light = light
}
lightInitialized = true
@ -170,9 +170,12 @@ class Chunk(
}
@Synchronized
private fun getOrPut(sectionHeight: Int): ChunkSection {
private fun getOrPut(sectionHeight: Int): ChunkSection? {
val sections = sections ?: throw NullPointerException("Sections not initialized yet!")
val sectionIndex = sectionHeight - lowestSection
if (sectionIndex < 0 || sectionIndex > sections.size) {
return null
}
var section = sections[sectionIndex]
if (section == null) {

View File

@ -20,5 +20,5 @@ import java.util.*
interface SingleBlockRenderable {
fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, light: ByteArray, ambientLight: FloatArray, tints: IntArray?): Boolean
fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, light: ByteArray, tints: IntArray?): Boolean
}

View File

@ -32,10 +32,10 @@ class MultipartBakedModel(
return sizes[direction.ordinal]
}
override fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, light: ByteArray, ambientLight: FloatArray, tints: IntArray?): Boolean {
override fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, light: ByteArray, tints: IntArray?): Boolean {
var rendered = false
for (model in models) {
if (model.singleRender(position, mesh, random, blockState, neighbours, light, ambientLight, tints) && !rendered) {
if (model.singleRender(position, mesh, random, blockState, neighbours, light, tints) && !rendered) {
rendered = true
}
}

View File

@ -58,8 +58,8 @@ class WeightedBakedModel(
throw IllegalStateException("Could not find a model: This should never happen!")
}
override fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, light: ByteArray, ambientLight: FloatArray, tints: IntArray?): Boolean {
return getModel(random)?.singleRender(position, mesh, random, blockState, neighbours, light, ambientLight, tints) ?: false
override fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, light: ByteArray, tints: IntArray?): Boolean {
return getModel(random)?.singleRender(position, mesh, random, blockState, neighbours, light, tints) ?: false
}
override fun getParticleTexture(random: Random, blockPosition: Vec3i): AbstractTexture? {

View File

@ -36,7 +36,7 @@ class BakedBlockStateModel(
return touchingFaceProperties[direction.ordinal]
}
override fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, light: ByteArray, ambientLight: FloatArray, tints: IntArray?): Boolean {
override fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, light: ByteArray, tints: IntArray?): Boolean {
val floatPosition = position.toVec3()
blockState.block.randomOffsetType?.let {
floatPosition += position.getWorldOffset(blockState.block)
@ -68,7 +68,7 @@ class BakedBlockStateModel(
}
tint = tints?.getOrNull(face.tintIndex) ?: -1
currentLight = (face.cullFace?.let { light[it.ordinal] } ?: light[SolidCullSectionPreparer.SELF_LIGHT_INDEX]).toInt()
face.singleRender(positionArray, mesh, currentLight, ambientLight, tint)
face.singleRender(positionArray, mesh, currentLight, tint)
if (!rendered) {
rendered = true
}

View File

@ -38,7 +38,7 @@ class BakedFace(
override val transparency: TextureTransparencies
get() = texture.transparency // ToDo
fun singleRender(position: FloatArray, mesh: WorldMesh, light: Int, ambientLight: FloatArray, tint: Int) {
fun singleRender(position: FloatArray, mesh: WorldMesh, light: Int, tint: Int) {
val meshToUse = transparency.getMesh(mesh)
// ToDo: Ambient light
val color = Vec3(shade)

View File

@ -45,7 +45,7 @@ class SignBlockEntityRenderer(
override val blockState: BlockState,
) : OnlyMeshedBlockEntityRenderer<SignBlockEntity> {
override fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, light: ByteArray, ambientLight: FloatArray, tints: IntArray?): Boolean {
override fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, light: ByteArray, tints: IntArray?): Boolean {
val block = this.blockState.block
if (block is StandingSignBlock) {
renderStandingText(position, mesh, light[SolidCullSectionPreparer.SELF_LIGHT_INDEX].toInt())

View File

@ -37,6 +37,8 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparenci
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.chunkPosition
import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkPosition
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
@ -128,10 +130,10 @@ class FluidCullSectionPreparer(
}
val cornerHeights = floatArrayOf(
getCornerHeight(position, fluid),
getCornerHeight(position + Directions.EAST, fluid),
getCornerHeight(position + Directions.EAST + Directions.SOUTH, fluid),
getCornerHeight(position + Directions.SOUTH, fluid),
getCornerHeight(chunk, chunkPosition, position, fluid),
getCornerHeight(chunk, chunkPosition, position + Directions.EAST, fluid),
getCornerHeight(chunk, chunkPosition, position + Directions.EAST + Directions.SOUTH, fluid),
getCornerHeight(chunk, chunkPosition, position + Directions.SOUTH, fluid),
)
if (!skip[Directions.O_UP]) {
@ -262,21 +264,38 @@ class FluidCullSectionPreparer(
neighbours.release()
}
private fun getCornerHeight(position: Vec3i, fluid: Fluid): Float {
// ToDo: Optimize
private fun getCornerHeight(providedChunk: Chunk, providedChunkPosition: Vec2i, position: Vec3i, fluid: Fluid): Float {
// ToDo: Optimize more
var totalHeight = 0.0f
var count = 0
var lastChunkPosition = providedChunkPosition
var lastChunk: Chunk? = providedChunk
for (side in 0 until 4) {
val blockPosition = position + Vec3i(-(side and 0x01), 0, -(side shr 1 and 0x01))
if (fluid.matches(world[blockPosition + Directions.UP])) {
val chunkPosition = blockPosition.chunkPosition
if (chunkPosition != lastChunkPosition) {
lastChunkPosition = chunkPosition
lastChunk = world[chunkPosition]
}
if (lastChunk == null) {
count++
continue
}
val inChunkPosition = blockPosition.inChunkPosition
if (fluid.matches(lastChunk[inChunkPosition + Directions.UP])) {
return 1.0f
}
val blockState = world[blockPosition]
val blockState = lastChunk[inChunkPosition]
if (blockState == null) {
count++
continue
}
if (blockState == null || !fluid.matches(blockState)) {
if (blockState?.material?.solid != true) {
if (!fluid.matches(blockState)) {
if (!blockState.material.solid) {
count++
}
continue

View File

@ -49,7 +49,6 @@ class SolidCullSectionPreparer(
private val bedrock = renderWindow.connection.registries.blockRegistry[MinecraftBlocks.BEDROCK]?.defaultState
private val someFullBlock = renderWindow.connection.registries.blockRegistry[MinecraftBlocks.COMMAND_BLOCK]?.defaultState
private val tintColorCalculator = renderWindow.tintManager
private val ambientLight = floatArrayOf(1.0f, 1.0f, 1.0f, 1.0f)
private var fastBedrock = false
init {
@ -167,10 +166,10 @@ class SolidCullSectionPreparer(
random.setSeed(0L)
}
tints = tintColorCalculator.getAverageTint(chunk, neighbourChunks, blockState, x, y, z)
rendered = model.singleRender(position, mesh, random, blockState, neighbourBlocks, light, ambientLight, tints)
rendered = model.singleRender(position, mesh, random, blockState, neighbourBlocks, light, tints)
if (blockEntityModel is MeshedBlockEntityRenderer<*>) {
rendered = blockEntityModel.singleRender(position, mesh, random, blockState, neighbourBlocks, light, ambientLight, tints) || rendered
rendered = blockEntityModel.singleRender(position, mesh, random, blockState, neighbourBlocks, light, tints) || rendered
}
if (rendered) {

View File

@ -420,7 +420,7 @@ open class InByteBuffer {
return Pair(resourceLocation, Tag(items.toSet()))
}
@Deprecated("Use readArray")
@Deprecated("Use readArray", ReplaceWith("mapOf(*(readArray(length) { readTag(idResolver) }))"))
fun <T> readTagArray(length: Int = readVarInt(), idResolver: (Int) -> T): Map<ResourceLocation, Tag<T>> {
return mapOf(*(readArray(length) { readTag(idResolver) }))
}

View File

@ -217,7 +217,6 @@ class PlayInByteBuffer : InByteBuffer {
return readArray(length) { readEntityId() }
}
fun readPlayerProperties(): PlayerProperties {
var textures: PlayerTextures? = null
for (i in 0 until readVarInt()) {