meshing experiements

This commit is contained in:
Bixilon 2021-11-09 17:37:41 +01:00
parent df21556171
commit c999d5a6fe
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
9 changed files with 52 additions and 20 deletions

View File

@ -73,12 +73,12 @@ enum class Directions(
fun getPositions(from: Vec3, to: Vec3): Array<Vec3> {
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))
}
}

View File

@ -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)

View File

@ -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)

View File

@ -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
}

View File

@ -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<BlockState?> = 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

View File

@ -28,7 +28,7 @@ class GridLayout(hudRenderer: HUDRenderer, val grid: Vec2i) : Element(hudRendere
val columnConstraints: Array<GridColumnConstraint> = Array(grid.x) { GridColumnConstraint() }
val rowConstraints: Array<GridRowConstraint> = Array(grid.y) { GridRowConstraint() }
private val children: Array<Array<GridCell?>> = Array(grid.x) { Array(grid.y) { null } }
private val children: Array<Array<GridCell?>> = Array(grid.x) { arrayOfNulls(grid.y) }
private var columnStart = IntArray(grid.x)
private var rowStart = IntArray(grid.y)

View File

@ -26,6 +26,7 @@ class BakedBlockStateModel(
val faces: Array<Array<BakedFace>>,
) : 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<FaceSize> {
return arrayOf() // ToDo

View File

@ -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)

View File

@ -96,7 +96,7 @@ data class UnbakedBlockStateModel(
}
}
val finalFaces: Array<Array<BakedFace>?> = Array(faces.size) { null }
val finalFaces: Array<Array<BakedFace>?> = arrayOfNulls(faces.size)
for ((index, faceArray) in faces.withIndex()) {
finalFaces[index] = faceArray.toTypedArray()