mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-23 20:46:44 -04:00
world renderer: fix bug that empty sections won't get unloaded
This commit is contained in:
parent
b86740b8d0
commit
e81b354124
@ -18,5 +18,6 @@ import glm_.vec2.Vec2i
|
|||||||
|
|
||||||
class SectionPrepareTask(
|
class SectionPrepareTask(
|
||||||
val chunkPosition: Vec2i,
|
val chunkPosition: Vec2i,
|
||||||
|
val sectionHeight: Int,
|
||||||
val runnable: ThreadPoolRunnable,
|
val runnable: ThreadPoolRunnable,
|
||||||
)
|
)
|
||||||
|
@ -26,7 +26,7 @@ class WorldQueueItem(
|
|||||||
val chunk: Chunk?,
|
val chunk: Chunk?,
|
||||||
val section: ChunkSection?,
|
val section: ChunkSection?,
|
||||||
val center: Vec3,
|
val center: Vec3,
|
||||||
val neighbours: Array<ChunkSection?>?,
|
var neighbours: Array<ChunkSection?>?,
|
||||||
) {
|
) {
|
||||||
var mesh: WorldMesh? = null
|
var mesh: WorldMesh? = null
|
||||||
|
|
||||||
|
@ -416,14 +416,14 @@ class WorldRenderer(
|
|||||||
}
|
}
|
||||||
queueLock.unlock()
|
queueLock.unlock()
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
val task = SectionPrepareTask(item.chunkPosition, ThreadPoolRunnable(if (item.chunkPosition == cameraChunkPosition) HIGH else LOW)) // Our own chunk is the most important one ToDo: Also make neighbour chunks important
|
val task = SectionPrepareTask(item.chunkPosition, item.sectionHeight, ThreadPoolRunnable(if (item.chunkPosition == cameraChunkPosition) HIGH else LOW)) // Our own chunk is the most important one ToDo: Also make neighbour chunks important
|
||||||
task.runnable.runnable = Runnable {
|
task.runnable.runnable = Runnable {
|
||||||
var locked = false
|
var locked = false
|
||||||
try {
|
try {
|
||||||
val chunk = item.chunk ?: world[item.chunkPosition] ?: return@Runnable
|
val chunk = item.chunk ?: world[item.chunkPosition] ?: return@Runnable
|
||||||
val section = chunk[item.sectionHeight] ?: return@Runnable
|
val section = chunk[item.sectionHeight] ?: return@Runnable
|
||||||
if (section.blocks.isEmpty) {
|
if (section.blocks.isEmpty) {
|
||||||
return@Runnable
|
return@Runnable queueItemUnload(item)
|
||||||
}
|
}
|
||||||
val neighbourChunks: Array<Chunk>
|
val neighbourChunks: Array<Chunk>
|
||||||
world.getChunkNeighbours(item.chunkPosition).let {
|
world.getChunkNeighbours(item.chunkPosition).let {
|
||||||
@ -439,7 +439,7 @@ class WorldRenderer(
|
|||||||
fluidSectionPreparer.prepareFluid(item.chunkPosition, item.sectionHeight, chunk, section, neighbours, neighbourChunks, mesh)
|
fluidSectionPreparer.prepareFluid(item.chunkPosition, item.sectionHeight, chunk, section, neighbours, neighbourChunks, mesh)
|
||||||
}
|
}
|
||||||
if (mesh.clearEmpty() == 0) {
|
if (mesh.clearEmpty() == 0) {
|
||||||
return@Runnable
|
return@Runnable queueItemUnload(item)
|
||||||
}
|
}
|
||||||
item.mesh = mesh
|
item.mesh = mesh
|
||||||
meshesToLoadLock.lock()
|
meshesToLoadLock.lock()
|
||||||
@ -474,10 +474,55 @@ class WorldRenderer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun queueItemUnload(item: WorldQueueItem) {
|
||||||
|
queueLock.lock()
|
||||||
|
culledQueueLock.lock()
|
||||||
|
meshesToLoadLock.lock()
|
||||||
|
meshesToUnloadLock.lock()
|
||||||
|
loadedMeshesLock.lock()
|
||||||
|
loadedMeshes[item.chunkPosition]?.let {
|
||||||
|
meshesToUnload += it.remove(item.sectionHeight) ?: return@let
|
||||||
|
if (it.isEmpty()) {
|
||||||
|
loadedMeshes -= item.chunkPosition
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
culledQueue[item.chunkPosition]?.let {
|
||||||
|
it.remove(item.sectionHeight)
|
||||||
|
if (it.isEmpty()) {
|
||||||
|
loadedMeshes -= item.chunkPosition
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
queue.removeAll { it.chunkPosition == item.chunkPosition && it.sectionHeight == item.sectionHeight }
|
||||||
|
|
||||||
|
meshesToLoad.removeAll { it.chunkPosition == item.chunkPosition && it.sectionHeight == item.sectionHeight }
|
||||||
|
|
||||||
|
preparingTasksLock.acquire()
|
||||||
|
for (task in preparingTasks.toMutableSet()) {
|
||||||
|
if (task.chunkPosition == item.chunkPosition && task.sectionHeight == item.sectionHeight) {
|
||||||
|
task.runnable.interrupt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
preparingTasksLock.release()
|
||||||
|
|
||||||
|
loadedMeshesLock.unlock()
|
||||||
|
queueLock.unlock()
|
||||||
|
culledQueueLock.unlock()
|
||||||
|
meshesToLoadLock.unlock()
|
||||||
|
meshesToUnloadLock.unlock()
|
||||||
|
}
|
||||||
|
|
||||||
private fun internalQueueSection(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk, section: ChunkSection, ignoreFrustum: Boolean): Boolean {
|
private fun internalQueueSection(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk, section: ChunkSection, ignoreFrustum: Boolean): Boolean {
|
||||||
if (!chunk.isFullyLoaded || section.blocks.isEmpty) { // ToDo: Unload if empty
|
if (!chunk.isFullyLoaded) { // ToDo: Unload if empty
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
val item = WorldQueueItem(chunkPosition, sectionHeight, chunk, section, Vec3i.of(chunkPosition, sectionHeight).toVec3() + CHUNK_CENTER, null)
|
||||||
|
if (section.blocks.isEmpty) {
|
||||||
|
queueItemUnload(item)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
val neighbours = world.getChunkNeighbours(chunkPosition)
|
val neighbours = world.getChunkNeighbours(chunkPosition)
|
||||||
if (!neighbours.received) {
|
if (!neighbours.received) {
|
||||||
return false
|
return false
|
||||||
@ -485,7 +530,7 @@ class WorldRenderer(
|
|||||||
|
|
||||||
val visible = ignoreFrustum || isSectionVisible(chunkPosition, sectionHeight, section.blocks.minPosition, section.blocks.maxPosition, true)
|
val visible = ignoreFrustum || isSectionVisible(chunkPosition, sectionHeight, section.blocks.minPosition, section.blocks.maxPosition, true)
|
||||||
if (visible) {
|
if (visible) {
|
||||||
val item = WorldQueueItem(chunkPosition, sectionHeight, chunk, section, Vec3i.of(chunkPosition, sectionHeight).toVec3() + CHUNK_CENTER, ChunkUtil.getDirectNeighbours(neighbours.unsafeCast(), chunk, sectionHeight))
|
item.neighbours = ChunkUtil.getDirectNeighbours(neighbours.unsafeCast(), chunk, sectionHeight)
|
||||||
queueLock.lock()
|
queueLock.lock()
|
||||||
queue.removeAll { it == item } // Prevent duplicated entries (to not prepare the same chunk twice (if it changed and was not prepared yet or ...)
|
queue.removeAll { it == item } // Prevent duplicated entries (to not prepare the same chunk twice (if it changed and was not prepared yet or ...)
|
||||||
if (chunkPosition == cameraChunkPosition) {
|
if (chunkPosition == cameraChunkPosition) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user