From 4782e6eb3038e34d559e3f56b74a6acedf58edf3 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Thu, 1 Jun 2023 00:16:45 +0200 Subject: [PATCH] chunk queue comparator This reduces meshing overhead and sorting time minimal --- .../world/queue/meshing/ChunkMeshingQueue.kt | 17 ++------ .../queue/meshing/ChunkQueueComparator.kt | 43 +++++++++++++++++++ 2 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/world/queue/meshing/ChunkQueueComparator.kt diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/queue/meshing/ChunkMeshingQueue.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/queue/meshing/ChunkMeshingQueue.kt index d20c4cf7b..00a2ca59c 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/queue/meshing/ChunkMeshingQueue.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/queue/meshing/ChunkMeshingQueue.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 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. * @@ -13,13 +13,11 @@ package de.bixilon.minosoft.gui.rendering.world.queue.meshing -import de.bixilon.kotlinglm.vec3.Vec3i import de.bixilon.kutil.cast.CastUtil.unsafeCast import de.bixilon.kutil.concurrent.lock.simple.SimpleLock import de.bixilon.kutil.concurrent.pool.ThreadPool import de.bixilon.kutil.concurrent.pool.ThreadPoolRunnable import de.bixilon.minosoft.data.world.positions.ChunkPosition -import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.length2 import de.bixilon.minosoft.gui.rendering.world.WorldQueueItem import de.bixilon.minosoft.gui.rendering.world.WorldRenderer import de.bixilon.minosoft.gui.rendering.world.queue.QueuePosition @@ -30,6 +28,7 @@ import de.bixilon.minosoft.util.SystemInformation class ChunkMeshingQueue( private val renderer: WorldRenderer, ) { + private val comparator = ChunkQueueComparator() val tasks = MeshPrepareTaskManager(renderer) val maxMeshesToLoad = if (SystemInformation.RUNTIME.maxMemory() > 1_000_000_000) 150 else 80 @@ -46,16 +45,8 @@ class ChunkMeshingQueue( fun sort() { lock() - val position = renderer.cameraChunkPosition - val height = renderer.cameraSectionHeight - val cameraSectionPosition = Vec3i(position.x, height, position.y) - queue.sortBy { - if (it.chunkPosition == position) { - // our own chunk always has the highest priority - return@sortBy -Int.MAX_VALUE - } - (it.sectionPosition - cameraSectionPosition).length2() - } + comparator.update(renderer) + queue.sortWith(comparator) unlock() } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/queue/meshing/ChunkQueueComparator.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/queue/meshing/ChunkQueueComparator.kt new file mode 100644 index 000000000..335a882bc --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/queue/meshing/ChunkQueueComparator.kt @@ -0,0 +1,43 @@ +/* + * Minosoft + * Copyright (C) 2020-2023 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 distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.world.queue.meshing + +import de.bixilon.kotlinglm.vec2.Vec2i +import de.bixilon.minosoft.data.world.positions.ChunkPosition +import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY +import de.bixilon.minosoft.gui.rendering.world.WorldQueueItem +import de.bixilon.minosoft.gui.rendering.world.WorldRenderer + +class ChunkQueueComparator : Comparator { + private var position: ChunkPosition = Vec2i.EMPTY + private var height = 0 + + + fun update(renderer: WorldRenderer) { + this.position = renderer.cameraChunkPosition + this.height = renderer.cameraSectionHeight + } + + private fun compare(item: WorldQueueItem): Int { + val array = item.sectionPosition.array + val x = array[0] - position.x + val y = array[1] - height + val z = array[2] - position.y + return (x * x + y * y + z * z) + } + + override fun compare(a: WorldQueueItem, b: WorldQueueItem): Int { + return compare(a).compareTo(compare(b)) + } +}