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> { fun getPositions(from: Vec3, to: Vec3): Array<Vec3> {
return when (this) { 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)) 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(to, Vec3(from.x, to.y, to.z), Vec3(from.x, to.y, from.z), Vec3(to.x, to.y, from.z)) 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)) 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)) 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, to.z), Vec3(from.x, from.y, to.z), from, Vec3(from.x, to.y, from.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(Vec3(to.x, from.y, from.z), Vec3(to.x, from.y, to.z), to, Vec3(to.x, to.y, from.z)) 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 return false
} }
if (other is BlockState) { 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) { if (other is ResourceLocation) {
return super.equals(other) return super.equals(other)

View File

@ -72,8 +72,15 @@ class WorldRenderer(
val random = Random(0L) val random = Random(0L)
val blockState = connection.registries.blockRegistry["end_portal_frame"]?.defaultState val blockState1 = connection.registries.blockRegistry["end_portal_frame"]?.defaultState
val section = ChunkSection(Array(4096) { if (random.nextBoolean()) blockState else null }) 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 }) //val section = ChunkSection(Array(4096) { if (it < 1) blockState else null })
mesh = sectionPreparer.prepare(section) mesh = sectionPreparer.prepare(section)

View File

@ -23,7 +23,7 @@ import de.bixilon.minosoft.util.logging.LogMessageType
class GenericSectionPreparer( class GenericSectionPreparer(
val renderWindow: RenderWindow, val renderWindow: RenderWindow,
private val preparer: AbstractSectionPreparer = GreedySectionPreparer(renderWindow), private val preparer: AbstractSectionPreparer = CullSectionPreparer(renderWindow),
) : AbstractSectionPreparer { ) : AbstractSectionPreparer {
override fun prepare(section: ChunkSection): ChunkSectionMesh { override fun prepare(section: ChunkSection): ChunkSectionMesh {
@ -33,7 +33,7 @@ class GenericSectionPreparer(
val time = System.nanoTime() val time = System.nanoTime()
val delta = time - startTime 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 return mesh
} }

View File

@ -51,7 +51,8 @@ class GreedySectionPreparer(
var l: Int var l: Int
var w: Int var w: Int
var h: 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) val endOffset = IntArray(3)
for (direction in Directions.VALUES) { for (direction in Directions.VALUES) {
@ -92,10 +93,27 @@ class GreedySectionPreparer(
} else { } else {
currentBlock 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[nextAxis]
} }
++position[nextNextAxis] ++position[nextNextAxis]
@ -109,11 +127,11 @@ class GreedySectionPreparer(
while (j < SECTION_SIZE) { while (j < SECTION_SIZE) {
i = 0 i = 0
while (i < SECTION_SIZE) { while (i < SECTION_SIZE) {
if (mask[n]) { if (stateMask[n] != null) {
// Compute the width of this quad and store it in w // 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 // This is done by searching along the current axis until mask[n + w] is false
w = 1 w = 1
while (i + w < SECTION_SIZE && mask[n + w]) { while (i + w < SECTION_SIZE && stateMask[n + w] == stateMask[n]) {
w++ w++
} }
@ -128,9 +146,9 @@ class GreedySectionPreparer(
while (j + h < SECTION_SIZE) { while (j + h < SECTION_SIZE) {
k = 0 k = 0
while (k < w) { 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 done = true
break
} }
k++ k++
} }
@ -172,8 +190,11 @@ class GreedySectionPreparer(
end = Vec3i(endOffset) 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) { while (l < h) {
k = 0 k = 0
while (k < w) { while (k < w) {
mask[n + k + l * SECTION_SIZE] = false val index = n + k + l * SECTION_SIZE
stateMask[index] = null
meshableMask[index] = true
++k ++k
} }
++l ++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 columnConstraints: Array<GridColumnConstraint> = Array(grid.x) { GridColumnConstraint() }
val rowConstraints: Array<GridRowConstraint> = Array(grid.y) { GridRowConstraint() } 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 columnStart = IntArray(grid.x)
private var rowStart = IntArray(grid.y) private var rowStart = IntArray(grid.y)

View File

@ -26,6 +26,7 @@ class BakedBlockStateModel(
val faces: Array<Array<BakedFace>>, val faces: Array<Array<BakedFace>>,
) : BakedBlockModel, GreedyBakedBlockModel { // ToDo: Greedy meshable ) : BakedBlockModel, GreedyBakedBlockModel { // ToDo: Greedy meshable
override val canGreedyMesh: Boolean = true 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> { override fun getFaceSize(direction: Directions, random: Random): Array<FaceSize> {
return arrayOf() // ToDo return arrayOf() // ToDo

View File

@ -19,6 +19,7 @@ import glm_.vec3.Vec3i
interface GreedyBakedBlockModel { interface GreedyBakedBlockModel {
val canGreedyMesh: Boolean val canGreedyMesh: Boolean
val greedyMeshableFaces: BooleanArray
// ToDo: Tint // ToDo: Tint
fun greedyRender(start: Vec3i, end: Vec3i, side: Directions, mesh: ChunkSectionMesh, light: Int) 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()) { for ((index, faceArray) in faces.withIndex()) {
finalFaces[index] = faceArray.toTypedArray() finalFaces[index] = faceArray.toTypedArray()