diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/world/CellView.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/world/CellView.kt index 8b10fd45..89d795b1 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/world/CellView.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/world/CellView.kt @@ -2,10 +2,10 @@ package ru.dbotthepony.kstarbound.world import ru.dbotthepony.kstarbound.world.api.BackgroundView import ru.dbotthepony.kstarbound.world.api.CHUNK_SIZE -import ru.dbotthepony.kstarbound.world.api.CHUNK_SIZE_FF import ru.dbotthepony.kstarbound.world.api.ForegroundView import ru.dbotthepony.kstarbound.world.api.IChunk import ru.dbotthepony.kstarbound.world.api.IChunkCell +import ru.dbotthepony.kvector.arrays.Object2DArray /** * Предоставляет доступ к чанку и его соседям @@ -16,54 +16,56 @@ import ru.dbotthepony.kstarbound.world.api.IChunkCell */ class CellView( override val pos: ChunkPos, - val center: IChunk?, - - val right: IChunk?, - val top: IChunk?, - val topRight: IChunk?, - val topLeft: IChunk?, val left: IChunk?, - val bottom: IChunk?, + val center: IChunk?, + val right: IChunk?, + + val topRight: IChunk?, + val top: IChunk?, + val topLeft: IChunk?, + val bottomLeft: IChunk?, + val bottom: IChunk?, val bottomRight: IChunk?, ) : IChunk { val backgroundView = BackgroundView(this) val foregroundView = ForegroundView(this) override fun getCell(x: Int, y: Int): IChunkCell { - if (x in 0 ..CHUNK_SIZE_FF) { - if (y in 0 ..CHUNK_SIZE_FF) { - return center?.getCell(x, y) ?: IChunkCell.Companion - } + val ix = x + CHUNK_SIZE + val iy = y + CHUNK_SIZE - if (y < 0) { - return bottom?.getCell(x, y + CHUNK_SIZE) ?: IChunkCell.Companion - } else { - return top?.getCell(x, y - CHUNK_SIZE) ?: IChunkCell.Companion + if (ix in 0 until CHUNK_SIZE * 3 - 1 && iy in 0 until CHUNK_SIZE * 3 - 1) { + return indices[ix, iy].invoke(this) ?: IChunkCell.Companion + } else { + return IChunkCell.Companion + } + } + + companion object { + private val indices = Object2DArray.nulls<(CellView) -> IChunkCell?>(CHUNK_SIZE * 3, CHUNK_SIZE * 3) as Object2DArray<(CellView) -> IChunkCell?> + + private fun put(half: (CellView) -> IChunk?, x: Int, y: Int) { + for (ix in 0 until CHUNK_SIZE) { + for (iy in 0 until CHUNK_SIZE) { + indices[x + ix, y + iy] = { half(it)?.getCell(ix, iy) } + } } } - if (x < 0) { - if (y in 0 ..CHUNK_SIZE_FF) { - return left?.getCell(x + CHUNK_SIZE, y) ?: IChunkCell.Companion - } + init { + put(CellView::bottomLeft, 0, 0) + put(CellView::bottom, CHUNK_SIZE, 0) + put(CellView::bottomRight, CHUNK_SIZE * 2, 0) - if (y < 0) { - return bottomLeft?.getCell(x + CHUNK_SIZE, y + CHUNK_SIZE) ?: IChunkCell.Companion - } else { - return topLeft?.getCell(x + CHUNK_SIZE, y - CHUNK_SIZE) ?: IChunkCell.Companion - } - } else { - if (y in 0 ..CHUNK_SIZE_FF) { - return right?.getCell(x - CHUNK_SIZE, y) ?: IChunkCell.Companion - } + put(CellView::left, 0, CHUNK_SIZE) + put(CellView::center, CHUNK_SIZE, CHUNK_SIZE) + put(CellView::right, CHUNK_SIZE * 2, CHUNK_SIZE) - if (y < 0) { - return bottomRight?.getCell(x - CHUNK_SIZE, y + CHUNK_SIZE) ?: IChunkCell.Companion - } else { - return topRight?.getCell(x - CHUNK_SIZE, y - CHUNK_SIZE) ?: IChunkCell.Companion - } + put(CellView::topLeft, 0, CHUNK_SIZE * 2) + put(CellView::top, CHUNK_SIZE, CHUNK_SIZE * 2) + put(CellView::topRight, CHUNK_SIZE * 2, CHUNK_SIZE * 2) } } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/world/Chunk.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/world/Chunk.kt index d01bd6ca..6f6bebf6 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/world/Chunk.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/world/Chunk.kt @@ -8,7 +8,7 @@ import ru.dbotthepony.kstarbound.defs.tile.LiquidDefinition import ru.dbotthepony.kstarbound.defs.tile.MaterialModifier import ru.dbotthepony.kstarbound.defs.tile.TileDefinition import ru.dbotthepony.kstarbound.world.api.BackgroundView -import ru.dbotthepony.kstarbound.world.api.CHUNK_SHIFT +import ru.dbotthepony.kstarbound.world.api.CHUNK_SIZE_BITS import ru.dbotthepony.kstarbound.world.api.CHUNK_SIZE import ru.dbotthepony.kstarbound.world.api.CHUNK_SIZE_FF import ru.dbotthepony.kstarbound.world.api.CHUNK_SIZEd @@ -261,7 +261,7 @@ abstract class Chunk, This : Chunk { constructor(pos: IStruct2i) : this(pos.component1(), pos.component2()) val firstBlock get() = Vector2i(tileX, tileY) - val lastBlock get() = Vector2i(((x + 1) shl CHUNK_SHIFT) - 1, ((y + 1) shl CHUNK_SHIFT) - 1) + val lastBlock get() = Vector2i(((x + 1) shl CHUNK_SIZE_BITS) - 1, ((y + 1) shl CHUNK_SIZE_BITS) - 1) /** * Координата тайла на 0 позиции по оси X внутри чанка в мире */ - val tileX: Int get() = x shl CHUNK_SHIFT + val tileX: Int get() = x shl CHUNK_SIZE_BITS /** * Координата тайла на 0 позиции по оси Y внутри чанка в мире */ - val tileY: Int get() = y shl CHUNK_SHIFT + val tileY: Int get() = y shl CHUNK_SIZE_BITS val top: ChunkPos get() { @@ -184,10 +184,10 @@ class ChunkPos(val x: Int, val y: Int) : Comparable { fun tileToChunkComponent(comp: Int): Int { if (comp < 0) { - return -(comp.absoluteValue shr CHUNK_SHIFT) - 1 + return -(comp.absoluteValue shr CHUNK_SIZE_BITS) - 1 } - return comp shr CHUNK_SHIFT + return comp shr CHUNK_SIZE_BITS } } } \ No newline at end of file diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/Constants.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/Constants.kt index d3025bf5..e59b64ac 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/Constants.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/Constants.kt @@ -1,7 +1,7 @@ package ru.dbotthepony.kstarbound.world.api -const val CHUNK_SHIFT = 5 -const val CHUNK_SIZE = 1 shl CHUNK_SHIFT // 32 +const val CHUNK_SIZE_BITS = 5 +const val CHUNK_SIZE = 1 shl CHUNK_SIZE_BITS // 32 const val CHUNK_SIZE_FF = CHUNK_SIZE - 1 const val CHUNK_SIZEf = CHUNK_SIZE.toFloat() -const val CHUNK_SIZEd = CHUNK_SIZE.toDouble() \ No newline at end of file +const val CHUNK_SIZEd = CHUNK_SIZE.toDouble() diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/IChunk.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/IChunk.kt index 4f4a7a0f..aae6a610 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/IChunk.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/IChunk.kt @@ -17,7 +17,7 @@ interface IChunk { * Для использования в рендерах и прочих вещах, которым нужно стабильное число на основе своей позиции */ fun randomLongFor(x: Int, y: Int): Long { - var long = (x or (pos.x shl CHUNK_SHIFT)) * 738548L + (y or (pos.y shl CHUNK_SHIFT)) * 2191293543L + var long = (x or (pos.x shl CHUNK_SIZE_BITS)) * 738548L + (y or (pos.y shl CHUNK_SIZE_BITS)) * 2191293543L long = long xor 8339437585692L long = (long ushr 4) or (long shl 52) long *= 7848344324L diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/world/phys/RectTileFlooderDepthFirst.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/world/phys/RectTileFlooderDepthFirst.kt index 29e62e59..15b2a75c 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/world/phys/RectTileFlooderDepthFirst.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/world/phys/RectTileFlooderDepthFirst.kt @@ -1,6 +1,6 @@ package ru.dbotthepony.kstarbound.world.phys -import ru.dbotthepony.kstarbound.world.api.CHUNK_SHIFT +import ru.dbotthepony.kstarbound.world.api.CHUNK_SIZE_BITS import ru.dbotthepony.kstarbound.world.api.CHUNK_SIZE_FF import ru.dbotthepony.kstarbound.world.api.IChunkCell import ru.dbotthepony.kvector.arrays.Object2DArray @@ -24,7 +24,7 @@ class RectTileFlooderDepthFirst( return false } - return !seen[x or (y shl CHUNK_SHIFT)] && tiles[x, y].foreground.material != null + return !seen[x or (y shl CHUNK_SIZE_BITS)] && tiles[x, y].foreground.material != null } init { @@ -169,7 +169,7 @@ class RectTileFlooderDepthFirst( fun markSeen() { for (x in mins.x .. maxs.x) { for (y in mins.y .. maxs.y) { - seen[x or (y shl CHUNK_SHIFT)] = true + seen[x or (y shl CHUNK_SIZE_BITS)] = true } } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/world/phys/RectTileFlooderSizeFirst.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/world/phys/RectTileFlooderSizeFirst.kt index db155b90..2f022713 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/world/phys/RectTileFlooderSizeFirst.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/world/phys/RectTileFlooderSizeFirst.kt @@ -1,6 +1,6 @@ package ru.dbotthepony.kstarbound.world.phys -import ru.dbotthepony.kstarbound.world.api.CHUNK_SHIFT +import ru.dbotthepony.kstarbound.world.api.CHUNK_SIZE_BITS import ru.dbotthepony.kstarbound.world.api.CHUNK_SIZE_FF import ru.dbotthepony.kstarbound.world.api.IChunkCell import ru.dbotthepony.kvector.arrays.Object2DArray @@ -24,7 +24,7 @@ class RectTileFlooderSizeFirst( return false } - return !seen[x or (y shl CHUNK_SHIFT)] && tiles[x, y].foreground.material != null + return !seen[x or (y shl CHUNK_SIZE_BITS)] && tiles[x, y].foreground.material != null } private var widthPositive = 0 @@ -138,7 +138,7 @@ class RectTileFlooderSizeFirst( fun markSeen() { for (x in mins.x .. maxs.x) { for (y in mins.y .. maxs.y) { - seen[x or (y shl CHUNK_SHIFT)] = true + seen[x or (y shl CHUNK_SIZE_BITS)] = true } } }