Optimize cell view
This commit is contained in:
parent
e459db83b2
commit
e436864e12
@ -2,10 +2,10 @@ package ru.dbotthepony.kstarbound.world
|
|||||||
|
|
||||||
import ru.dbotthepony.kstarbound.world.api.BackgroundView
|
import ru.dbotthepony.kstarbound.world.api.BackgroundView
|
||||||
import ru.dbotthepony.kstarbound.world.api.CHUNK_SIZE
|
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.ForegroundView
|
||||||
import ru.dbotthepony.kstarbound.world.api.IChunk
|
import ru.dbotthepony.kstarbound.world.api.IChunk
|
||||||
import ru.dbotthepony.kstarbound.world.api.IChunkCell
|
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(
|
class CellView(
|
||||||
override val pos: ChunkPos,
|
override val pos: ChunkPos,
|
||||||
val center: IChunk?,
|
|
||||||
|
|
||||||
val right: IChunk?,
|
|
||||||
val top: IChunk?,
|
|
||||||
val topRight: IChunk?,
|
|
||||||
val topLeft: IChunk?,
|
|
||||||
|
|
||||||
val left: 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 bottomLeft: IChunk?,
|
||||||
|
val bottom: IChunk?,
|
||||||
val bottomRight: IChunk?,
|
val bottomRight: IChunk?,
|
||||||
) : IChunk {
|
) : IChunk {
|
||||||
val backgroundView = BackgroundView(this)
|
val backgroundView = BackgroundView(this)
|
||||||
val foregroundView = ForegroundView(this)
|
val foregroundView = ForegroundView(this)
|
||||||
|
|
||||||
override fun getCell(x: Int, y: Int): IChunkCell {
|
override fun getCell(x: Int, y: Int): IChunkCell {
|
||||||
if (x in 0 ..CHUNK_SIZE_FF) {
|
val ix = x + CHUNK_SIZE
|
||||||
if (y in 0 ..CHUNK_SIZE_FF) {
|
val iy = y + CHUNK_SIZE
|
||||||
return center?.getCell(x, y) ?: IChunkCell.Companion
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y < 0) {
|
if (ix in 0 until CHUNK_SIZE * 3 - 1 && iy in 0 until CHUNK_SIZE * 3 - 1) {
|
||||||
return bottom?.getCell(x, y + CHUNK_SIZE) ?: IChunkCell.Companion
|
return indices[ix, iy].invoke(this) ?: IChunkCell.Companion
|
||||||
} else {
|
} else {
|
||||||
return top?.getCell(x, y - CHUNK_SIZE) ?: IChunkCell.Companion
|
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) {
|
init {
|
||||||
if (y in 0 ..CHUNK_SIZE_FF) {
|
put(CellView::bottomLeft, 0, 0)
|
||||||
return left?.getCell(x + CHUNK_SIZE, y) ?: IChunkCell.Companion
|
put(CellView::bottom, CHUNK_SIZE, 0)
|
||||||
}
|
put(CellView::bottomRight, CHUNK_SIZE * 2, 0)
|
||||||
|
|
||||||
if (y < 0) {
|
put(CellView::left, 0, CHUNK_SIZE)
|
||||||
return bottomLeft?.getCell(x + CHUNK_SIZE, y + CHUNK_SIZE) ?: IChunkCell.Companion
|
put(CellView::center, CHUNK_SIZE, CHUNK_SIZE)
|
||||||
} else {
|
put(CellView::right, CHUNK_SIZE * 2, CHUNK_SIZE)
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y < 0) {
|
put(CellView::topLeft, 0, CHUNK_SIZE * 2)
|
||||||
return bottomRight?.getCell(x - CHUNK_SIZE, y + CHUNK_SIZE) ?: IChunkCell.Companion
|
put(CellView::top, CHUNK_SIZE, CHUNK_SIZE * 2)
|
||||||
} else {
|
put(CellView::topRight, CHUNK_SIZE * 2, CHUNK_SIZE * 2)
|
||||||
return topRight?.getCell(x - CHUNK_SIZE, y - CHUNK_SIZE) ?: IChunkCell.Companion
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import ru.dbotthepony.kstarbound.defs.tile.LiquidDefinition
|
|||||||
import ru.dbotthepony.kstarbound.defs.tile.MaterialModifier
|
import ru.dbotthepony.kstarbound.defs.tile.MaterialModifier
|
||||||
import ru.dbotthepony.kstarbound.defs.tile.TileDefinition
|
import ru.dbotthepony.kstarbound.defs.tile.TileDefinition
|
||||||
import ru.dbotthepony.kstarbound.world.api.BackgroundView
|
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
|
||||||
import ru.dbotthepony.kstarbound.world.api.CHUNK_SIZE_FF
|
import ru.dbotthepony.kstarbound.world.api.CHUNK_SIZE_FF
|
||||||
import ru.dbotthepony.kstarbound.world.api.CHUNK_SIZEd
|
import ru.dbotthepony.kstarbound.world.api.CHUNK_SIZEd
|
||||||
@ -261,7 +261,7 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
|||||||
|
|
||||||
for (y in 0 .. CHUNK_SIZE_FF) {
|
for (y in 0 .. CHUNK_SIZE_FF) {
|
||||||
for (x in 0..CHUNK_SIZE_FF) {
|
for (x in 0..CHUNK_SIZE_FF) {
|
||||||
if (!seen[x or (y shl CHUNK_SHIFT)] && cells[x, y].foreground.material != null) {
|
if (!seen[x or (y shl CHUNK_SIZE_BITS)] && cells[x, y].foreground.material != null) {
|
||||||
val depthFirst = RectTileFlooderDepthFirst(cells, seen, x, y)
|
val depthFirst = RectTileFlooderDepthFirst(cells, seen, x, y)
|
||||||
val sizeFirst = RectTileFlooderSizeFirst(cells, seen, x, y)
|
val sizeFirst = RectTileFlooderSizeFirst(cells, seen, x, y)
|
||||||
val xSpanDepth = depthFirst.maxs.x - depthFirst.mins.x
|
val xSpanDepth = depthFirst.maxs.x - depthFirst.mins.x
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package ru.dbotthepony.kstarbound.world
|
package ru.dbotthepony.kstarbound.world
|
||||||
|
|
||||||
import ru.dbotthepony.kstarbound.math.roundByAbsoluteValue
|
import ru.dbotthepony.kstarbound.math.roundByAbsoluteValue
|
||||||
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.CHUNK_SIZE_FF
|
||||||
import ru.dbotthepony.kvector.api.IStruct2d
|
import ru.dbotthepony.kvector.api.IStruct2d
|
||||||
import ru.dbotthepony.kvector.api.IStruct2i
|
import ru.dbotthepony.kvector.api.IStruct2i
|
||||||
@ -32,17 +32,17 @@ class ChunkPos(val x: Int, val y: Int) : Comparable<ChunkPos> {
|
|||||||
constructor(pos: IStruct2i) : this(pos.component1(), pos.component2())
|
constructor(pos: IStruct2i) : this(pos.component1(), pos.component2())
|
||||||
|
|
||||||
val firstBlock get() = Vector2i(tileX, tileY)
|
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 внутри чанка в мире
|
* Координата тайла на 0 позиции по оси X внутри чанка в мире
|
||||||
*/
|
*/
|
||||||
val tileX: Int get() = x shl CHUNK_SHIFT
|
val tileX: Int get() = x shl CHUNK_SIZE_BITS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Координата тайла на 0 позиции по оси Y внутри чанка в мире
|
* Координата тайла на 0 позиции по оси Y внутри чанка в мире
|
||||||
*/
|
*/
|
||||||
val tileY: Int get() = y shl CHUNK_SHIFT
|
val tileY: Int get() = y shl CHUNK_SIZE_BITS
|
||||||
|
|
||||||
val top: ChunkPos
|
val top: ChunkPos
|
||||||
get() {
|
get() {
|
||||||
@ -184,10 +184,10 @@ class ChunkPos(val x: Int, val y: Int) : Comparable<ChunkPos> {
|
|||||||
|
|
||||||
fun tileToChunkComponent(comp: Int): Int {
|
fun tileToChunkComponent(comp: Int): Int {
|
||||||
if (comp < 0) {
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package ru.dbotthepony.kstarbound.world.api
|
package ru.dbotthepony.kstarbound.world.api
|
||||||
|
|
||||||
const val CHUNK_SHIFT = 5
|
const val CHUNK_SIZE_BITS = 5
|
||||||
const val CHUNK_SIZE = 1 shl CHUNK_SHIFT // 32
|
const val CHUNK_SIZE = 1 shl CHUNK_SIZE_BITS // 32
|
||||||
const val CHUNK_SIZE_FF = CHUNK_SIZE - 1
|
const val CHUNK_SIZE_FF = CHUNK_SIZE - 1
|
||||||
const val CHUNK_SIZEf = CHUNK_SIZE.toFloat()
|
const val CHUNK_SIZEf = CHUNK_SIZE.toFloat()
|
||||||
const val CHUNK_SIZEd = CHUNK_SIZE.toDouble()
|
const val CHUNK_SIZEd = CHUNK_SIZE.toDouble()
|
||||||
|
@ -17,7 +17,7 @@ interface IChunk {
|
|||||||
* Для использования в рендерах и прочих вещах, которым нужно стабильное число на основе своей позиции
|
* Для использования в рендерах и прочих вещах, которым нужно стабильное число на основе своей позиции
|
||||||
*/
|
*/
|
||||||
fun randomLongFor(x: Int, y: Int): Long {
|
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 xor 8339437585692L
|
||||||
long = (long ushr 4) or (long shl 52)
|
long = (long ushr 4) or (long shl 52)
|
||||||
long *= 7848344324L
|
long *= 7848344324L
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package ru.dbotthepony.kstarbound.world.phys
|
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.CHUNK_SIZE_FF
|
||||||
import ru.dbotthepony.kstarbound.world.api.IChunkCell
|
import ru.dbotthepony.kstarbound.world.api.IChunkCell
|
||||||
import ru.dbotthepony.kvector.arrays.Object2DArray
|
import ru.dbotthepony.kvector.arrays.Object2DArray
|
||||||
@ -24,7 +24,7 @@ class RectTileFlooderDepthFirst(
|
|||||||
return false
|
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 {
|
init {
|
||||||
@ -169,7 +169,7 @@ class RectTileFlooderDepthFirst(
|
|||||||
fun markSeen() {
|
fun markSeen() {
|
||||||
for (x in mins.x .. maxs.x) {
|
for (x in mins.x .. maxs.x) {
|
||||||
for (y in mins.y .. maxs.y) {
|
for (y in mins.y .. maxs.y) {
|
||||||
seen[x or (y shl CHUNK_SHIFT)] = true
|
seen[x or (y shl CHUNK_SIZE_BITS)] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package ru.dbotthepony.kstarbound.world.phys
|
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.CHUNK_SIZE_FF
|
||||||
import ru.dbotthepony.kstarbound.world.api.IChunkCell
|
import ru.dbotthepony.kstarbound.world.api.IChunkCell
|
||||||
import ru.dbotthepony.kvector.arrays.Object2DArray
|
import ru.dbotthepony.kvector.arrays.Object2DArray
|
||||||
@ -24,7 +24,7 @@ class RectTileFlooderSizeFirst(
|
|||||||
return false
|
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
|
private var widthPositive = 0
|
||||||
@ -138,7 +138,7 @@ class RectTileFlooderSizeFirst(
|
|||||||
fun markSeen() {
|
fun markSeen() {
|
||||||
for (x in mins.x .. maxs.x) {
|
for (x in mins.x .. maxs.x) {
|
||||||
for (y in mins.y .. maxs.y) {
|
for (y in mins.y .. maxs.y) {
|
||||||
seen[x or (y shl CHUNK_SHIFT)] = true
|
seen[x or (y shl CHUNK_SIZE_BITS)] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user