Gjallarhorn Improvements

This commit is contained in:
Kenneth Endfinger
2022-02-20 04:03:21 -05:00
parent 86800e59f4
commit 1afb1c7148
6 changed files with 25 additions and 11 deletions

View File

@ -2,8 +2,8 @@ package cloud.kubelet.foundation.gjallarhorn.commands
import cloud.kubelet.foundation.gjallarhorn.export.ChunkExportLoader import cloud.kubelet.foundation.gjallarhorn.export.ChunkExportLoader
import cloud.kubelet.foundation.gjallarhorn.state.BlockExpanse import cloud.kubelet.foundation.gjallarhorn.state.BlockExpanse
import cloud.kubelet.foundation.gjallarhorn.state.BlockLogTracker
import cloud.kubelet.foundation.gjallarhorn.state.ChangelogSlice import cloud.kubelet.foundation.gjallarhorn.state.ChangelogSlice
import cloud.kubelet.foundation.gjallarhorn.state.SparseBlockStateMap
import cloud.kubelet.foundation.gjallarhorn.util.savePngFile import cloud.kubelet.foundation.gjallarhorn.util.savePngFile
import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.requireObject import com.github.ajalt.clikt.core.requireObject
@ -22,12 +22,12 @@ class ChunkExportLoaderCommand : CliktCommand("Chunk Export Loader", name = "chu
private val render by option("--render", help = "Render Top Down Image").enum<ImageRenderType> { it.id } private val render by option("--render", help = "Render Top Down Image").enum<ImageRenderType> { it.id }
override fun run() { override fun run() {
val map = SparseBlockStateMap() val tracker = BlockLogTracker(isConcurrent = true)
val loader = ChunkExportLoader(map) val loader = ChunkExportLoader(tracker = tracker)
loader.loadAllChunksForWorld(exportDirectoryPath, world, fast = true) loader.loadAllChunksForWorld(exportDirectoryPath, world, fast = true)
if (render != null) { if (render != null) {
val expanse = BlockExpanse.offsetAndMax(map.calculateZeroBlockOffset(), map.calculateMaxBlock()) val expanse = BlockExpanse.zeroOffsetAndMax(tracker.calculateZeroBlockOffset(), tracker.calculateMaxBlock())
map.applyCoordinateOffset(expanse.offset) val map = tracker.buildBlockMap(expanse.offset)
val renderer = render!!.create(expanse, db) val renderer = render!!.create(expanse, db)
val image = renderer.render(ChangelogSlice.none, map) val image = renderer.render(ChangelogSlice.none, map)
image.savePngFile("full.png") image.savePngFile("full.png")

View File

@ -1,6 +1,7 @@
package cloud.kubelet.foundation.gjallarhorn.export package cloud.kubelet.foundation.gjallarhorn.export
import cloud.kubelet.foundation.gjallarhorn.state.BlockCoordinate import cloud.kubelet.foundation.gjallarhorn.state.BlockCoordinate
import cloud.kubelet.foundation.gjallarhorn.state.BlockLogTracker
import cloud.kubelet.foundation.gjallarhorn.state.BlockState import cloud.kubelet.foundation.gjallarhorn.state.BlockState
import cloud.kubelet.foundation.gjallarhorn.state.SparseBlockStateMap import cloud.kubelet.foundation.gjallarhorn.state.SparseBlockStateMap
import cloud.kubelet.foundation.heimdall.export.ExportedChunk import cloud.kubelet.foundation.heimdall.export.ExportedChunk
@ -12,7 +13,7 @@ import java.util.zip.GZIPInputStream
import kotlin.io.path.inputStream import kotlin.io.path.inputStream
import kotlin.io.path.listDirectoryEntries import kotlin.io.path.listDirectoryEntries
class ChunkExportLoader(val map: SparseBlockStateMap) { class ChunkExportLoader(val map: SparseBlockStateMap? = null, val tracker: BlockLogTracker? = null) {
fun loadAllChunksForWorld(path: Path, world: String, fast: Boolean = false) { fun loadAllChunksForWorld(path: Path, world: String, fast: Boolean = false) {
val chunkFiles = path.listDirectoryEntries("${world}_chunk_*.json.gz") val chunkFiles = path.listDirectoryEntries("${world}_chunk_*.json.gz")
if (fast) { if (fast) {
@ -30,6 +31,7 @@ class ChunkExportLoader(val map: SparseBlockStateMap) {
val chunk = Json.decodeFromStream(ExportedChunk.serializer(), gzipInputStream) val chunk = Json.decodeFromStream(ExportedChunk.serializer(), gzipInputStream)
var blockCount = 0L var blockCount = 0L
val allBlocks = if (tracker != null) mutableMapOf<BlockCoordinate, BlockState>() else null
for (section in chunk.sections) { for (section in chunk.sections) {
val x = (chunk.x * 16) + section.x val x = (chunk.x * 16) + section.x
val z = (chunk.z * 16) + section.z val z = (chunk.z * 16) + section.z
@ -40,10 +42,18 @@ class ChunkExportLoader(val map: SparseBlockStateMap) {
val coordinate = BlockCoordinate(x.toLong(), y.toLong(), z.toLong()) val coordinate = BlockCoordinate(x.toLong(), y.toLong(), z.toLong())
val state = BlockState.cached(block.type) val state = BlockState.cached(block.type)
map.put(coordinate, state) map?.put(coordinate, state)
if (allBlocks != null) {
allBlocks[coordinate] = state
}
blockCount++ blockCount++
} }
} }
if (allBlocks != null) {
tracker?.placeAll(allBlocks)
}
logger.info("($id) Chunk X=${chunk.x} Z=${chunk.z} had $blockCount blocks") logger.info("($id) Chunk X=${chunk.x} Z=${chunk.z} had $blockCount blocks")
} }

View File

@ -57,8 +57,8 @@ open class BlockCoordinateSparseMap<T> : BlockCoordinateStore<T> {
val zSectionMap = TreeMap<Long, TreeMap<Long, T>>() val zSectionMap = TreeMap<Long, TreeMap<Long, T>>()
(xSection.key + offset.x) to xSection.value.map { zSection -> (xSection.key + offset.x) to xSection.value.map { zSection ->
val ySectionMap = TreeMap<Long, T>() val ySectionMap = TreeMap<Long, T>()
(zSection.key + offset.z) to zSection.value.map { ySection -> (zSection.key + offset.z) to zSection.value.mapKeys {
(ySection.key + offset.y) to ySection.value (it.key + offset.y)
}.toMap(ySectionMap) }.toMap(ySectionMap)
}.toMap(zSectionMap) }.toMap(zSectionMap)
}.toMap(root) }.toMap(root)

View File

@ -5,7 +5,7 @@ class BlockExpanse(
val size: BlockCoordinate val size: BlockCoordinate
) { ) {
companion object { companion object {
fun offsetAndMax(offset: BlockCoordinate, max: BlockCoordinate) = BlockExpanse( fun zeroOffsetAndMax(offset: BlockCoordinate, max: BlockCoordinate) = BlockExpanse(
offset, offset,
offset.applyAsOffset(max) offset.applyAsOffset(max)
) )

View File

@ -10,6 +10,10 @@ class BlockLogTracker(private val mode: BlockTrackMode = BlockTrackMode.RemoveOn
blocks[position] = state blocks[position] = state
} }
fun placeAll(map: Map<BlockCoordinate, BlockState>) {
blocks.putAll(map)
}
fun delete(position: BlockCoordinate) { fun delete(position: BlockCoordinate) {
if (mode == BlockTrackMode.AirOnDelete) { if (mode == BlockTrackMode.AirOnDelete) {
blocks[position] = BlockState.AirBlock blocks[position] = BlockState.AirBlock

View File

@ -17,7 +17,7 @@ class BlockMapTimelapse<T> :
val globalBlockOffset = BlockCoordinate.maxOf(allBlockOffsets) val globalBlockOffset = BlockCoordinate.maxOf(allBlockOffsets)
val allBlockMaxes = trackers.map { it.value.calculateMaxBlock() } val allBlockMaxes = trackers.map { it.value.calculateMaxBlock() }
val globalBlockMax = BlockCoordinate.maxOf(allBlockMaxes) val globalBlockMax = BlockCoordinate.maxOf(allBlockMaxes)
val globalBlockExpanse = BlockExpanse.offsetAndMax(globalBlockOffset, globalBlockMax) val globalBlockExpanse = BlockExpanse.zeroOffsetAndMax(globalBlockOffset, globalBlockMax)
val renderer = pool.createRendererFunction(globalBlockExpanse) val renderer = pool.createRendererFunction(globalBlockExpanse)
for ((slice, tracker) in trackers) { for ((slice, tracker) in trackers) {