diff --git a/src/main/java/de/bixilon/minosoft/data/direction/Directions.kt b/src/main/java/de/bixilon/minosoft/data/direction/Directions.kt index 1e35dc1da..22bb52f39 100644 --- a/src/main/java/de/bixilon/minosoft/data/direction/Directions.kt +++ b/src/main/java/de/bixilon/minosoft/data/direction/Directions.kt @@ -73,12 +73,12 @@ enum class Directions( fun getPositions(from: Vec3, to: Vec3): Array { return when (this) { - DOWN -> arrayOf(from, Vec3(from.x, from.y, to.z), Vec3(to.x, from.y, to.z), Vec3(to.x, from.y, from.z)) - UP -> arrayOf(to, Vec3(from.x, to.y, to.z), Vec3(from.x, to.y, from.z), Vec3(to.x, to.y, from.z)) + DOWN -> arrayOf(Vec3(from.x, from.y, to.z), Vec3(to.x, from.y, to.z), Vec3(to.x, from.y, from.z), from) + UP -> arrayOf(Vec3(from.x, to.y, from.z), Vec3(to.x, to.y, from.z), to, Vec3(from.x, to.y, to.z)) NORTH -> arrayOf(Vec3(to.x, to.y, from.y), Vec3(from.x, to.y, from.z), from, Vec3(to.x, from.y, from.z)) - SOUTH -> arrayOf(Vec3(from.x, from.y, to.z), Vec3(from.x, to.y, to.z), to, Vec3(to.x, from.y, to.z)) - WEST -> arrayOf(Vec3(from.x, to.y, to.z), Vec3(from.x, from.y, to.z), from, Vec3(from.x, to.y, from.z)) - EAST -> arrayOf(Vec3(to.x, from.y, from.z), Vec3(to.x, from.y, to.z), to, Vec3(to.x, to.y, from.z)) + SOUTH -> arrayOf(Vec3(from.x, to.y, to.z), to, Vec3(to.x, from.y, to.z), Vec3(from.x, from.y, to.z)) + WEST -> arrayOf(Vec3(from.x, to.y, from.z), Vec3(from.x, to.y, to.z), Vec3(from.x, from.y, to.z), from) + EAST -> arrayOf(to, Vec3(to.x, to.y, from.z), Vec3(to.x, from.y, from.z), Vec3(to.x, from.y, to.z)) } } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/blocks/BlockState.kt b/src/main/java/de/bixilon/minosoft/data/registries/blocks/BlockState.kt index ace802df1..f57ad8d8a 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/blocks/BlockState.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/blocks/BlockState.kt @@ -79,7 +79,7 @@ data class BlockState( return false } if (other is BlockState) { - return block.resourceLocation == other.block.resourceLocation && properties == other.properties && block.resourceLocation.namespace == other.block.resourceLocation.namespace + return block.resourceLocation.path == other.block.resourceLocation.path && properties == other.properties && block.resourceLocation.namespace == other.block.resourceLocation.namespace } if (other is ResourceLocation) { return super.equals(other) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt index 4378fcdff..1752c5c11 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt @@ -72,8 +72,15 @@ class WorldRenderer( val random = Random(0L) - val blockState = connection.registries.blockRegistry["end_portal_frame"]?.defaultState - val section = ChunkSection(Array(4096) { if (random.nextBoolean()) blockState else null }) + val blockState1 = connection.registries.blockRegistry["end_portal_frame"]?.defaultState + val blockState2 = connection.registries.blockRegistry["carved_pumpkin"]?.defaultState + val section = ChunkSection(Array(4096) { + when (random.nextInt(3)) { + 1 -> blockState2 + 2 -> blockState2 + else -> blockState2 + } + }) //val section = ChunkSection(Array(4096) { if (it < 1) blockState else null }) mesh = sectionPreparer.prepare(section) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/block/preparer/GenericSectionPreparer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/block/preparer/GenericSectionPreparer.kt index 6eaac372f..cabb4a580 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/block/preparer/GenericSectionPreparer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/block/preparer/GenericSectionPreparer.kt @@ -23,7 +23,7 @@ import de.bixilon.minosoft.util.logging.LogMessageType class GenericSectionPreparer( val renderWindow: RenderWindow, - private val preparer: AbstractSectionPreparer = GreedySectionPreparer(renderWindow), + private val preparer: AbstractSectionPreparer = CullSectionPreparer(renderWindow), ) : AbstractSectionPreparer { override fun prepare(section: ChunkSection): ChunkSectionMesh { @@ -33,7 +33,7 @@ class GenericSectionPreparer( val time = System.nanoTime() val delta = time - startTime - Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Preparing took ${delta}ns, ${delta / 1000}µs, ${delta / 1000000}ms" } + Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Preparing took ${delta}ns, ${delta / 1000}µs, ${delta / 1000_000}ms" } return mesh } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/block/preparer/GreedySectionPreparer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/block/preparer/GreedySectionPreparer.kt index 97b4dc983..ee6d2b5f7 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/block/preparer/GreedySectionPreparer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/block/preparer/GreedySectionPreparer.kt @@ -51,7 +51,8 @@ class GreedySectionPreparer( var l: Int var w: Int var h: Int - val mask = BooleanArray(SECTION_SIZE * SECTION_SIZE) + val stateMask: Array = arrayOfNulls(SECTION_SIZE * SECTION_SIZE) + val meshableMask = BooleanArray(SECTION_SIZE * SECTION_SIZE) { true } val endOffset = IntArray(3) for (direction in Directions.VALUES) { @@ -92,10 +93,27 @@ class GreedySectionPreparer( } else { currentBlock } + val model = primaryBlock?.model + + val meshable = model is GreedyBakedBlockModel + && model.canGreedyMesh + && model.greedyMeshableFaces[direction.ordinal] + val face = currentBlock == null + || compareBlock == null + || currentBlock != compareBlock + || !meshable + + if (!meshable) { + meshableMask[n] = false + } + + if (face) { + stateMask[n] = primaryBlock + } + n++ - mask[n++] = primaryBlock != null && currentBlock != compareBlock ++position[nextAxis] } ++position[nextNextAxis] @@ -109,11 +127,11 @@ class GreedySectionPreparer( while (j < SECTION_SIZE) { i = 0 while (i < SECTION_SIZE) { - if (mask[n]) { + if (stateMask[n] != null) { // Compute the width of this quad and store it in w // This is done by searching along the current axis until mask[n + w] is false w = 1 - while (i + w < SECTION_SIZE && mask[n + w]) { + while (i + w < SECTION_SIZE && stateMask[n + w] == stateMask[n]) { w++ } @@ -128,9 +146,9 @@ class GreedySectionPreparer( while (j + h < SECTION_SIZE) { k = 0 while (k < w) { - if (!mask[n + k + h * SECTION_SIZE]) { + val compareIndex = n + k + h * SECTION_SIZE + if (stateMask[compareIndex] != stateMask[n] || !meshableMask[compareIndex]) { done = true - break } k++ } @@ -172,8 +190,11 @@ class GreedySectionPreparer( end = Vec3i(endOffset) + val model = currentBlock.model + model as GreedyBakedBlockModel - (currentBlock.model as GreedyBakedBlockModel).greedyRender(start, end, direction, mesh, 0xFF) + + model.greedyRender(start, end, direction, mesh, 0xFF) } @@ -186,7 +207,9 @@ class GreedySectionPreparer( while (l < h) { k = 0 while (k < w) { - mask[n + k + l * SECTION_SIZE] = false + val index = n + k + l * SECTION_SIZE + stateMask[index] = null + meshableMask[index] = true ++k } ++l diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/layout/grid/GridLayout.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/layout/grid/GridLayout.kt index 05f257a97..e6e16d47e 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/layout/grid/GridLayout.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/layout/grid/GridLayout.kt @@ -28,7 +28,7 @@ class GridLayout(hudRenderer: HUDRenderer, val grid: Vec2i) : Element(hudRendere val columnConstraints: Array = Array(grid.x) { GridColumnConstraint() } val rowConstraints: Array = Array(grid.y) { GridRowConstraint() } - private val children: Array> = Array(grid.x) { Array(grid.y) { null } } + private val children: Array> = Array(grid.x) { arrayOfNulls(grid.y) } private var columnStart = IntArray(grid.x) private var rowStart = IntArray(grid.y) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/BakedBlockStateModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/BakedBlockStateModel.kt index dccbc67ea..a297462e9 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/BakedBlockStateModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/BakedBlockStateModel.kt @@ -26,6 +26,7 @@ class BakedBlockStateModel( val faces: Array>, ) : BakedBlockModel, GreedyBakedBlockModel { // ToDo: Greedy meshable override val canGreedyMesh: Boolean = true + override val greedyMeshableFaces: BooleanArray = booleanArrayOf(true, false, true, true, true, true) override fun getFaceSize(direction: Directions, random: Random): Array { return arrayOf() // ToDo diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/GreedyBakedBlockModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/GreedyBakedBlockModel.kt index e4066cb1b..680e521be 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/GreedyBakedBlockModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/GreedyBakedBlockModel.kt @@ -19,6 +19,7 @@ import glm_.vec3.Vec3i interface GreedyBakedBlockModel { val canGreedyMesh: Boolean + val greedyMeshableFaces: BooleanArray // ToDo: Tint fun greedyRender(start: Vec3i, end: Vec3i, side: Directions, mesh: ChunkSectionMesh, light: Int) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/unbaked/block/UnbakedBlockStateModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/unbaked/block/UnbakedBlockStateModel.kt index 2919bd1e2..b137c0617 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/unbaked/block/UnbakedBlockStateModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/unbaked/block/UnbakedBlockStateModel.kt @@ -96,7 +96,7 @@ data class UnbakedBlockStateModel( } } - val finalFaces: Array?> = Array(faces.size) { null } + val finalFaces: Array?> = arrayOfNulls(faces.size) for ((index, faceArray) in faces.withIndex()) { finalFaces[index] = faceArray.toTypedArray()