Use AVL tree for chunk map

This commit is contained in:
DBotThePony 2022-02-22 07:35:23 +07:00
parent 66d7a267b2
commit 186144c8cc
Signed by: DBot
GPG Key ID: DCC23B5715498507
4 changed files with 37 additions and 8 deletions

View File

@ -189,8 +189,8 @@ fun main() {
client.camera.pos.y = 10f
client.gl.box2dRenderer.drawShapes = true
client.gl.box2dRenderer.drawPairs = true
client.gl.box2dRenderer.drawShapes = false
client.gl.box2dRenderer.drawPairs = false
client.gl.box2dRenderer.drawAABB = false
client.gl.box2dRenderer.drawJoints = false

View File

@ -58,7 +58,7 @@ class StarboundPakFile(
}
fun read(storage: StarboundPak, reader: DataInputStream): StarboundPakFile {
val readLength = reader.read()
val readLength = reader.readVarInt()
val name = reader.readASCIIString(readLength)
require(name[0] == '/') { "$name appears to be not an absolute filename" }
val offset = reader.readLong()

View File

@ -163,7 +163,7 @@ const val CHUNK_SIZE_FF = CHUNK_SIZE - 1
const val CHUNK_SIZEf = CHUNK_SIZE.toFloat()
const val CHUNK_SIZEd = CHUNK_SIZE.toDouble()
data class ChunkPos(val x: Int, val y: Int) {
class ChunkPos(val x: Int, val y: Int) : Comparable<ChunkPos> {
constructor(pos: IStruct2i) : this(pos.component1(), pos.component2())
val firstBlock get() = Vector2i(x shl CHUNK_SHIFT, y shl CHUNK_SHIFT)
@ -185,6 +185,31 @@ data class ChunkPos(val x: Int, val y: Int) {
return ChunkPos(x - 1, y)
}
override fun equals(other: Any?): Boolean {
if (other is ChunkPos)
return other.x == x && other.y == y
return false
}
override fun hashCode(): Int {
return (y shl 16) xor x
}
override fun toString(): String {
return "ChunkPos[$x $y]"
}
override fun compareTo(other: ChunkPos): Int {
if (x > other.x) {
return 1
} else if (x < other.x) {
return -1
}
return y.compareTo(other.y)
}
companion object {
val ZERO = ChunkPos(0, 0)

View File

@ -1,5 +1,7 @@
package ru.dbotthepony.kstarbound.world
import it.unimi.dsi.fastutil.objects.Object2ObjectAVLTreeMap
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
import ru.dbotthepony.kbox2d.api.ContactImpulse
import ru.dbotthepony.kbox2d.api.IContactFilter
import ru.dbotthepony.kbox2d.api.IContactListener
@ -140,7 +142,9 @@ class Timer(val period: Double, val executionTimes: Int, val func: (Timer) -> Un
}
abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, ChunkType>>(val seed: Long = 0L) {
protected val chunkMap = HashMap<ChunkPos, IMutableWorldChunkTuple<This, ChunkType>>()
protected val chunkMap = Object2ObjectAVLTreeMap<ChunkPos, IMutableWorldChunkTuple<This, ChunkType>> cmp@{ a, b ->
return@cmp a.compareTo(b)
}
/**
* Chunks, which have their collision mesh changed
@ -335,7 +339,7 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
return lastAccessedChunk!!
}
return chunkMap.computeIfAbsent(pos) lazy@{
return chunkMap.computeIfAbsent(pos, Object2ObjectFunction {
val chunk = chunkFactory(pos)
val top = getChunkInternal(pos.up())
@ -373,8 +377,8 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
ent.chunk = chunk
}
return@lazy tuple
}
return@Object2ObjectFunction tuple
})
}
open fun computeIfAbsent(pos: ChunkPos): IWorldChunkTuple<This, ChunkType> {