mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-13 17:37:58 -04:00
section occlusion: set invalid region for full opaque blocks
No need to check if the block is full opaque multiple times. Benchmark time goes down from 18s to 15s, so 17% improvement. Not bad.
This commit is contained in:
parent
3fadadd441
commit
dbd4752d09
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* Minosoft
|
||||||
* Copyright (C) 2020-2024 Moritz Zwerger
|
* Copyright (C) 2020-2025 Moritz Zwerger
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
@ -33,7 +33,7 @@ class ChunkNeighbours(val chunk: Chunk) : Iterable<Chunk?> {
|
|||||||
val complete: Boolean get() = count == COUNT
|
val complete: Boolean get() = count == COUNT
|
||||||
|
|
||||||
fun get(): Array<Chunk>? {
|
fun get(): Array<Chunk>? {
|
||||||
if (count == COUNT) {
|
if (count == COUNT) { // TODO: Race condition!
|
||||||
return neighbours.unsafeCast()
|
return neighbours.unsafeCast()
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
|
@ -58,13 +58,14 @@ class SectionOcclusion(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun ShortArray.updateRegion(x: Int, y: Int, z: Int, id: Short): Boolean {
|
private inline fun ShortArray.setIfUnset(x: Int, y: Int, z: Int, id: Short): Boolean {
|
||||||
val index = y shl 8 or (z shl 4) or x
|
val index = y shl 8 or (z shl 4) or x
|
||||||
if (this[index] > 0) {
|
if (this[index] != EMPTY_REGION) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
val state = provider[index]
|
val state = provider[index]
|
||||||
if (state.isFullyOpaque()) {
|
if (state.isFullyOpaque()) {
|
||||||
|
this[index] = INVALID_REGION
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
this[index] = id
|
this[index] = id
|
||||||
@ -72,7 +73,7 @@ class SectionOcclusion(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun startTrace(regions: ShortArray, x: Int, y: Int, z: Int, nextId: Short) {
|
private fun startTrace(regions: ShortArray, x: Int, y: Int, z: Int, nextId: Short) {
|
||||||
if (regions.updateRegion(x, y, z, nextId)) return
|
if (regions.setIfUnset(x, y, z, nextId)) return
|
||||||
|
|
||||||
// no need to trace negative coordinates initially
|
// no need to trace negative coordinates initially
|
||||||
if (x < ProtocolDefinition.SECTION_MAX_X) trace(regions, x + 1, y, z, nextId)
|
if (x < ProtocolDefinition.SECTION_MAX_X) trace(regions, x + 1, y, z, nextId)
|
||||||
@ -81,7 +82,7 @@ class SectionOcclusion(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun trace(regions: ShortArray, x: Int, y: Int, z: Int, nextId: Short) {
|
private fun trace(regions: ShortArray, x: Int, y: Int, z: Int, nextId: Short) {
|
||||||
if (regions.updateRegion(x, y, z, nextId)) return
|
if (regions.setIfUnset(x, y, z, nextId)) return
|
||||||
|
|
||||||
if (x > 0) trace(regions, x - 1, y, z, nextId)
|
if (x > 0) trace(regions, x - 1, y, z, nextId)
|
||||||
if (x < ProtocolDefinition.SECTION_MAX_X) trace(regions, x + 1, y, z, nextId)
|
if (x < ProtocolDefinition.SECTION_MAX_X) trace(regions, x + 1, y, z, nextId)
|
||||||
@ -93,9 +94,9 @@ class SectionOcclusion(
|
|||||||
|
|
||||||
private fun floodFill(array: ShortArray): ShortArray {
|
private fun floodFill(array: ShortArray): ShortArray {
|
||||||
// mark regions and check direct neighbours
|
// mark regions and check direct neighbours
|
||||||
Arrays.fill(array, 0.toShort())
|
Arrays.fill(array, EMPTY_REGION)
|
||||||
|
|
||||||
var next: Short = 0
|
var next = EMPTY_REGION
|
||||||
for (y in 0 until ProtocolDefinition.SECTION_HEIGHT_Y) {
|
for (y in 0 until ProtocolDefinition.SECTION_HEIGHT_Y) {
|
||||||
for (z in 0 until ProtocolDefinition.SECTION_WIDTH_Z) {
|
for (z in 0 until ProtocolDefinition.SECTION_WIDTH_Z) {
|
||||||
for (x in 0 until ProtocolDefinition.SECTION_WIDTH_X) {
|
for (x in 0 until ProtocolDefinition.SECTION_WIDTH_X) {
|
||||||
@ -124,7 +125,7 @@ class SectionOcclusion(
|
|||||||
Axes.Z -> Directions.NORTH
|
Axes.Z -> Directions.NORTH
|
||||||
}
|
}
|
||||||
val nRegion = regions[indexPrefix].toInt()
|
val nRegion = regions[indexPrefix].toInt()
|
||||||
if (nRegion > 0) {
|
if (nRegion > EMPTY_REGION) {
|
||||||
sideRegions[nDirection.ordinal].add(nRegion) // primitive
|
sideRegions[nDirection.ordinal].add(nRegion) // primitive
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,6 +204,8 @@ class SectionOcclusion(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private const val EMPTY_REGION = 0.toShort()
|
||||||
|
private const val INVALID_REGION = (-1).toShort()
|
||||||
private val EMPTY = BooleanArray(CubeDirections.CUBE_DIRECTION_COMBINATIONS)
|
private val EMPTY = BooleanArray(CubeDirections.CUBE_DIRECTION_COMBINATIONS)
|
||||||
private val ALLOCATOR = ShortAllocator()
|
private val ALLOCATOR = ShortAllocator()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user