Get rid of chunk tuples as we know them
because they are useless in this form
This commit is contained in:
parent
c1d19d951d
commit
af97c80cdd
@ -101,30 +101,40 @@ fun main() {
|
|||||||
val ent = PlayerEntity(client.world!!)
|
val ent = PlayerEntity(client.world!!)
|
||||||
|
|
||||||
Starbound.onInitialize {
|
Starbound.onInitialize {
|
||||||
|
var find = 0L
|
||||||
|
var set = 0L
|
||||||
|
var parse = 0L
|
||||||
|
|
||||||
for (chunkX in 0 .. 61) {
|
for (chunkX in 0 .. 61) {
|
||||||
for (chunkY in 0 .. 61) {
|
for (chunkY in 0 .. 61) {
|
||||||
|
var t = System.currentTimeMillis()
|
||||||
val data = db.read(byteArrayOf(1, 0, chunkX.toByte(), 0, chunkY.toByte()))
|
val data = db.read(byteArrayOf(1, 0, chunkX.toByte(), 0, chunkY.toByte()))
|
||||||
|
find += System.currentTimeMillis() - t
|
||||||
|
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
val chunk = client.world!!.computeIfAbsent(ChunkPos(chunkX, chunkY))
|
val chunk = client.world!!.computeIfAbsent(ChunkPos(chunkX, chunkY))
|
||||||
val inflater = Inflater()
|
val inflater = Inflater()
|
||||||
inflater.setInput(data)
|
inflater.setInput(data)
|
||||||
|
|
||||||
|
t = System.currentTimeMillis()
|
||||||
val output = ByteArray(64_000)
|
val output = ByteArray(64_000)
|
||||||
val actual = inflater.inflate(output)
|
val actual = inflater.inflate(output)
|
||||||
val reader = DataInputStream(ByteArrayInputStream(output))
|
val reader = DataInputStream(ByteArrayInputStream(output))
|
||||||
|
parse += System.currentTimeMillis() - t
|
||||||
|
|
||||||
reader.skipBytes(3)
|
reader.skipBytes(3)
|
||||||
|
|
||||||
var hitTile = false
|
var hitTile = false
|
||||||
|
|
||||||
|
t = System.currentTimeMillis()
|
||||||
|
|
||||||
for (y in 0 .. 31) {
|
for (y in 0 .. 31) {
|
||||||
for (x in 0 .. 31) {
|
for (x in 0 .. 31) {
|
||||||
val materialID = reader.readShort()
|
val materialID = reader.readShort()
|
||||||
val getMat = Starbound.tilesAccessID[materialID.toInt()]
|
val getMat = Starbound.tilesAccessID[materialID.toInt()]
|
||||||
|
|
||||||
if (getMat != null) {
|
if (getMat != null) {
|
||||||
chunk.chunk.foreground[x, y] = getMat
|
chunk.foreground[x, y] = getMat
|
||||||
hitTile = true
|
hitTile = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +144,7 @@ fun main() {
|
|||||||
val getMat2 = Starbound.tilesAccessID[materialID2.toInt()]
|
val getMat2 = Starbound.tilesAccessID[materialID2.toInt()]
|
||||||
|
|
||||||
if (getMat2 != null) {
|
if (getMat2 != null) {
|
||||||
chunk.chunk.background[x, y] = getMat2
|
chunk.background[x, y] = getMat2
|
||||||
hitTile = true
|
hitTile = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +152,8 @@ fun main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set += System.currentTimeMillis() - t
|
||||||
|
|
||||||
if (hitTile) {
|
if (hitTile) {
|
||||||
//println(chunk.chunk.posVector2d)
|
//println(chunk.chunk.posVector2d)
|
||||||
// ent.position = chunk.chunk.posVector2d + Vector2d(16.0, 34.0)
|
// ent.position = chunk.chunk.posVector2d + Vector2d(16.0, 34.0)
|
||||||
@ -149,6 +161,8 @@ fun main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println("$find $set $parse")
|
||||||
}
|
}
|
||||||
|
|
||||||
//ent.position += Vector2d(y = 14.0, x = -10.0)
|
//ent.position += Vector2d(y = 14.0, x = -10.0)
|
||||||
|
@ -119,9 +119,9 @@ class ClientWorld(val client: StarboundClient, seed: Long = 0L) : World<ClientWo
|
|||||||
|
|
||||||
val determineRenderers = ArrayList<ClientChunk>()
|
val determineRenderers = ArrayList<ClientChunk>()
|
||||||
|
|
||||||
for (chunk in collectInternal(size.encasingChunkPosAABB())) {
|
for (chunk in collect(size.encasingChunkPosAABB())) {
|
||||||
determineRenderers.add(chunk.chunk)
|
determineRenderers.add(chunk)
|
||||||
chunk.chunk.bake()
|
chunk.bake()
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLayeredList(client.gl.matrixStack, determineRenderers)
|
renderLayeredList(client.gl.matrixStack, determineRenderers)
|
||||||
|
@ -163,26 +163,50 @@ 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()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Сетка чанков идёт как и сетка тайлов.
|
||||||
|
*
|
||||||
|
* * Вправо у нас положительный X
|
||||||
|
* * Влево у нас отрицательный X
|
||||||
|
* * Вверх у нас положительный Y
|
||||||
|
* * Вниз у нас отрицательный Y
|
||||||
|
*/
|
||||||
class ChunkPos(val x: Int, val y: Int) : Comparable<ChunkPos> {
|
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(x shl CHUNK_SHIFT, y shl CHUNK_SHIFT)
|
val firstBlock get() = Vector2i(x shl CHUNK_SHIFT, y shl CHUNK_SHIFT)
|
||||||
val lastBlock get() = Vector2i(((x + 1) shl CHUNK_SHIFT) - 1, ((y + 1) shl CHUNK_SHIFT) - 1)
|
val lastBlock get() = Vector2i(((x + 1) shl CHUNK_SHIFT) - 1, ((y + 1) shl CHUNK_SHIFT) - 1)
|
||||||
|
|
||||||
fun up(): ChunkPos {
|
val top: ChunkPos get() {
|
||||||
return ChunkPos(x, y + 1)
|
return ChunkPos(x, y + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun down(): ChunkPos {
|
val bottom: ChunkPos get() {
|
||||||
return ChunkPos(x, y - 1)
|
return ChunkPos(x, y - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun left(): ChunkPos {
|
val left: ChunkPos get() {
|
||||||
return ChunkPos(x + 1, y)
|
return ChunkPos(x - 1, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun right(): ChunkPos {
|
val topLeft: ChunkPos get() {
|
||||||
return ChunkPos(x - 1, y)
|
return ChunkPos(x - 1, y + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
val topRight: ChunkPos get() {
|
||||||
|
return ChunkPos(x + 1, y + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
val bottomLeft: ChunkPos get() {
|
||||||
|
return ChunkPos(x - 1, y - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
val bottomRight: ChunkPos get() {
|
||||||
|
return ChunkPos(x + 1, y - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
val right: ChunkPos get() {
|
||||||
|
return ChunkPos(x + 1, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
@ -258,7 +282,7 @@ class ChunkPos(val x: Int, val y: Int) : Comparable<ChunkPos> {
|
|||||||
* и при этом координаты проверяются относительно чанка и могут спокойно выйти за его пределы,
|
* и при этом координаты проверяются относительно чанка и могут спокойно выйти за его пределы,
|
||||||
* с желанием получить тайл из соседнего чанка
|
* с желанием получить тайл из соседнего чанка
|
||||||
*/
|
*/
|
||||||
open class TileChunkView(
|
open class TileView(
|
||||||
open val center: ITileChunk,
|
open val center: ITileChunk,
|
||||||
|
|
||||||
open val right: ITileChunk?,
|
open val right: ITileChunk?,
|
||||||
@ -311,7 +335,7 @@ open class TileChunkView(
|
|||||||
get() = center.pos
|
get() = center.pos
|
||||||
}
|
}
|
||||||
|
|
||||||
class MutableTileChunkView(
|
class MutableTileView(
|
||||||
override val center: IMutableTileChunk,
|
override val center: IMutableTileChunk,
|
||||||
|
|
||||||
override val right: IMutableTileChunk?,
|
override val right: IMutableTileChunk?,
|
||||||
@ -323,7 +347,7 @@ class MutableTileChunkView(
|
|||||||
override val bottom: IMutableTileChunk?,
|
override val bottom: IMutableTileChunk?,
|
||||||
override val bottomLeft: IMutableTileChunk?,
|
override val bottomLeft: IMutableTileChunk?,
|
||||||
override val bottomRight: IMutableTileChunk?,
|
override val bottomRight: IMutableTileChunk?,
|
||||||
) : TileChunkView(center, right, top, topRight, topLeft, left, bottom, bottomLeft, bottomRight), IMutableTileChunk {
|
) : TileView(center, right, top, topRight, topLeft, left, bottom, bottomLeft, bottomRight), IMutableTileChunk {
|
||||||
override fun set(x: Int, y: Int, tile: TileDefinition?): ChunkTile? {
|
override fun set(x: Int, y: Int, tile: TileDefinition?): ChunkTile? {
|
||||||
if (x in 0 .. CHUNK_SIZE_FF) {
|
if (x in 0 .. CHUNK_SIZE_FF) {
|
||||||
if (y in 0 .. CHUNK_SIZE_FF) {
|
if (y in 0 .. CHUNK_SIZE_FF) {
|
||||||
@ -765,6 +789,15 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
|||||||
changeset++
|
changeset++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val left get() = pos.left
|
||||||
|
val right get() = pos.right
|
||||||
|
val top get() = pos.top
|
||||||
|
val bottom get() = pos.bottom
|
||||||
|
val topLeft get() = pos.topLeft
|
||||||
|
val topRight get() = pos.topRight
|
||||||
|
val bottomLeft get() = pos.bottomLeft
|
||||||
|
val bottomRight get() = pos.bottomRight
|
||||||
|
|
||||||
val aabb = aabbBase + Vector2d(pos.x * CHUNK_SIZE.toDouble(), pos.y * CHUNK_SIZE.toDouble())
|
val aabb = aabbBase + Vector2d(pos.x * CHUNK_SIZE.toDouble(), pos.y * CHUNK_SIZE.toDouble())
|
||||||
|
|
||||||
var isPhysicsDirty = false
|
var isPhysicsDirty = false
|
||||||
@ -962,6 +995,15 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
|||||||
override val pos: ChunkPos
|
override val pos: ChunkPos
|
||||||
get() = this@Chunk.pos
|
get() = this@Chunk.pos
|
||||||
|
|
||||||
|
inline val left get() = pos.left
|
||||||
|
inline val right get() = pos.right
|
||||||
|
inline val top get() = pos.top
|
||||||
|
inline val bottom get() = pos.bottom
|
||||||
|
inline val topLeft get() = pos.topLeft
|
||||||
|
inline val topRight get() = pos.topRight
|
||||||
|
inline val bottomLeft get() = pos.bottomLeft
|
||||||
|
inline val bottomRight get() = pos.bottomRight
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Хранит тайлы как x + y * CHUNK_SIZE
|
* Хранит тайлы как x + y * CHUNK_SIZE
|
||||||
*/
|
*/
|
||||||
|
@ -14,7 +14,6 @@ import ru.dbotthepony.kstarbound.defs.TileDefinition
|
|||||||
import ru.dbotthepony.kstarbound.math.*
|
import ru.dbotthepony.kstarbound.math.*
|
||||||
import ru.dbotthepony.kstarbound.world.entities.CollisionResolution
|
import ru.dbotthepony.kstarbound.world.entities.CollisionResolution
|
||||||
import ru.dbotthepony.kstarbound.world.entities.Entity
|
import ru.dbotthepony.kstarbound.world.entities.Entity
|
||||||
import ru.dbotthepony.kstarbound.world.entities.MovementController
|
|
||||||
import ru.dbotthepony.kstarbound.world.entities.projectile.AbstractProjectileMovementController
|
import ru.dbotthepony.kstarbound.world.entities.projectile.AbstractProjectileMovementController
|
||||||
import ru.dbotthepony.kvector.util2d.AABB
|
import ru.dbotthepony.kvector.util2d.AABB
|
||||||
import ru.dbotthepony.kvector.util2d.AABBi
|
import ru.dbotthepony.kvector.util2d.AABBi
|
||||||
@ -32,69 +31,52 @@ interface IWorldChunkTuple<WorldType : World<WorldType, ChunkType>, ChunkType :
|
|||||||
val left: IWorldChunkTuple<WorldType, ChunkType>?
|
val left: IWorldChunkTuple<WorldType, ChunkType>?
|
||||||
val right: IWorldChunkTuple<WorldType, ChunkType>?
|
val right: IWorldChunkTuple<WorldType, ChunkType>?
|
||||||
val bottom: IWorldChunkTuple<WorldType, ChunkType>?
|
val bottom: IWorldChunkTuple<WorldType, ChunkType>?
|
||||||
|
|
||||||
|
val topLeft: IWorldChunkTuple<WorldType, ChunkType>?
|
||||||
|
val topRight: IWorldChunkTuple<WorldType, ChunkType>?
|
||||||
|
val bottomLeft: IWorldChunkTuple<WorldType, ChunkType>?
|
||||||
|
val bottomRight: IWorldChunkTuple<WorldType, ChunkType>?
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IMutableWorldChunkTuple<WorldType : World<WorldType, ChunkType>, ChunkType : Chunk<WorldType, ChunkType>> : IWorldChunkTuple<WorldType, ChunkType> {
|
class ProxiedWorldChunkTuple<WorldType : World<WorldType, ChunkType>, ChunkType : Chunk<WorldType, ChunkType>>(
|
||||||
override var top: IMutableWorldChunkTuple<WorldType, ChunkType>?
|
|
||||||
override var left: IMutableWorldChunkTuple<WorldType, ChunkType>?
|
|
||||||
override var right: IMutableWorldChunkTuple<WorldType, ChunkType>?
|
|
||||||
override var bottom: IMutableWorldChunkTuple<WorldType, ChunkType>?
|
|
||||||
}
|
|
||||||
|
|
||||||
class WorldChunkTuple<WorldType : World<WorldType, ChunkType>, ChunkType : Chunk<WorldType, ChunkType>>(
|
|
||||||
private val parent: IWorldChunkTuple<WorldType, ChunkType>
|
private val parent: IWorldChunkTuple<WorldType, ChunkType>
|
||||||
) : IWorldChunkTuple<WorldType, ChunkType> {
|
) : IWorldChunkTuple<WorldType, ChunkType> {
|
||||||
override val world get() = parent.world
|
override val world get() = parent.world
|
||||||
override val chunk get() = parent.chunk
|
override val chunk get() = parent.chunk
|
||||||
override val top: IWorldChunkTuple<WorldType, ChunkType>? get() {
|
|
||||||
val getValue = parent.top
|
|
||||||
|
|
||||||
if (getValue != null) {
|
override val top: IWorldChunkTuple<WorldType, ChunkType>? get() = parent.top?.let(::ProxiedWorldChunkTuple)
|
||||||
return WorldChunkTuple(getValue)
|
override val left: IWorldChunkTuple<WorldType, ChunkType>? get() = parent.left?.let(::ProxiedWorldChunkTuple)
|
||||||
}
|
override val right: IWorldChunkTuple<WorldType, ChunkType>? get() = parent.right?.let(::ProxiedWorldChunkTuple)
|
||||||
|
override val bottom: IWorldChunkTuple<WorldType, ChunkType>? get() = parent.bottom?.let(::ProxiedWorldChunkTuple)
|
||||||
return null
|
override val topLeft: IWorldChunkTuple<WorldType, ChunkType>? get() = parent.topLeft?.let(::ProxiedWorldChunkTuple)
|
||||||
}
|
override val topRight: IWorldChunkTuple<WorldType, ChunkType>? get() = parent.topRight?.let(::ProxiedWorldChunkTuple)
|
||||||
|
override val bottomLeft: IWorldChunkTuple<WorldType, ChunkType>? get() = parent.bottomLeft?.let(::ProxiedWorldChunkTuple)
|
||||||
override val left: IWorldChunkTuple<WorldType, ChunkType>? get() {
|
override val bottomRight: IWorldChunkTuple<WorldType, ChunkType>? get() = parent.bottomRight?.let(::ProxiedWorldChunkTuple)
|
||||||
val getValue = parent.left
|
|
||||||
|
|
||||||
if (getValue != null) {
|
|
||||||
return WorldChunkTuple(getValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override val right: IWorldChunkTuple<WorldType, ChunkType>? get() {
|
|
||||||
val getValue = parent.right
|
|
||||||
|
|
||||||
if (getValue != null) {
|
|
||||||
return WorldChunkTuple(getValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override val bottom: IWorldChunkTuple<WorldType, ChunkType>? get() {
|
|
||||||
val getValue = parent.bottom
|
|
||||||
|
|
||||||
if (getValue != null) {
|
|
||||||
return WorldChunkTuple(getValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open class MutableWorldChunkTuple<WorldType : World<WorldType, ChunkType>, ChunkType : Chunk<WorldType, ChunkType>>(
|
class InstantWorldChunkTuple<WorldType : World<WorldType, ChunkType>, ChunkType : Chunk<WorldType, ChunkType>>(
|
||||||
override val world: WorldType,
|
override val world: WorldType,
|
||||||
override val chunk: ChunkType,
|
override val chunk: ChunkType
|
||||||
override var top: IMutableWorldChunkTuple<WorldType, ChunkType>?,
|
) : IWorldChunkTuple<WorldType, ChunkType> {
|
||||||
override var left: IMutableWorldChunkTuple<WorldType, ChunkType>?,
|
|
||||||
override var right: IMutableWorldChunkTuple<WorldType, ChunkType>?,
|
private val _top = world[chunk.top]
|
||||||
override var bottom: IMutableWorldChunkTuple<WorldType, ChunkType>?,
|
private val _left = world[chunk.left]
|
||||||
) : IMutableWorldChunkTuple<WorldType, ChunkType>
|
private val _right = world[chunk.right]
|
||||||
|
private val _bottom = world[chunk.bottom]
|
||||||
|
private val _topLeft = world[chunk.topLeft]
|
||||||
|
private val _topRight = world[chunk.topRight]
|
||||||
|
private val _bottomLeft = world[chunk.bottomLeft]
|
||||||
|
private val _bottomRight = world[chunk.bottomRight]
|
||||||
|
|
||||||
|
override val top: IWorldChunkTuple<WorldType, ChunkType>? by lazy { _top?.let { InstantWorldChunkTuple(world, it) } }
|
||||||
|
override val left: IWorldChunkTuple<WorldType, ChunkType>? by lazy { _left?.let { InstantWorldChunkTuple(world, it) } }
|
||||||
|
override val right: IWorldChunkTuple<WorldType, ChunkType>? by lazy { _right?.let { InstantWorldChunkTuple(world, it) } }
|
||||||
|
override val bottom: IWorldChunkTuple<WorldType, ChunkType>? by lazy { _bottom?.let { InstantWorldChunkTuple(world, it) } }
|
||||||
|
override val topLeft: IWorldChunkTuple<WorldType, ChunkType>? by lazy { _topLeft?.let { InstantWorldChunkTuple(world, it) } }
|
||||||
|
override val topRight: IWorldChunkTuple<WorldType, ChunkType>? by lazy { _topRight?.let { InstantWorldChunkTuple(world, it) } }
|
||||||
|
override val bottomLeft: IWorldChunkTuple<WorldType, ChunkType>? by lazy { _bottomLeft?.let { InstantWorldChunkTuple(world, it) } }
|
||||||
|
override val bottomRight: IWorldChunkTuple<WorldType, ChunkType>? by lazy { _bottomRight?.let { InstantWorldChunkTuple(world, it) } }
|
||||||
|
}
|
||||||
|
|
||||||
const val EARTH_FREEFALL_ACCELERATION = 9.8312 / METRES_IN_STARBOUND_UNIT
|
const val EARTH_FREEFALL_ACCELERATION = 9.8312 / METRES_IN_STARBOUND_UNIT
|
||||||
|
|
||||||
@ -142,7 +124,7 @@ 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) {
|
abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, ChunkType>>(val seed: Long = 0L) {
|
||||||
protected val chunkMap = Object2ObjectAVLTreeMap<ChunkPos, IMutableWorldChunkTuple<This, ChunkType>> cmp@{ a, b ->
|
protected val chunkMap = Object2ObjectAVLTreeMap<ChunkPos, ChunkType> cmp@{ a, b ->
|
||||||
return@cmp a.compareTo(b)
|
return@cmp a.compareTo(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +133,7 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
*/
|
*/
|
||||||
val dirtyPhysicsChunks = HashSet<ChunkType>()
|
val dirtyPhysicsChunks = HashSet<ChunkType>()
|
||||||
|
|
||||||
protected var lastAccessedChunk: IMutableWorldChunkTuple<This, ChunkType>? = null
|
protected var lastAccessedChunk: ChunkType? = null
|
||||||
|
|
||||||
val physics = B2World(Vector2d(0.0, -EARTH_FREEFALL_ACCELERATION))
|
val physics = B2World(Vector2d(0.0, -EARTH_FREEFALL_ACCELERATION))
|
||||||
|
|
||||||
@ -317,51 +299,37 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
pos: ChunkPos,
|
pos: ChunkPos,
|
||||||
): ChunkType
|
): ChunkType
|
||||||
|
|
||||||
protected fun getChunkInternal(pos: ChunkPos): IMutableWorldChunkTuple<This, ChunkType>? {
|
/**
|
||||||
if (lastAccessedChunk?.chunk?.pos == pos) {
|
* Возвращает чанк на указанной позиции если он существует
|
||||||
|
*/
|
||||||
|
open operator fun get(pos: ChunkPos): ChunkType? {
|
||||||
|
val lastAccessedChunk = lastAccessedChunk
|
||||||
|
|
||||||
|
if (lastAccessedChunk?.pos == pos) {
|
||||||
return lastAccessedChunk
|
return lastAccessedChunk
|
||||||
}
|
}
|
||||||
|
|
||||||
return chunkMap[pos]
|
return chunkMap[pos]
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun getChunk(pos: ChunkPos): IWorldChunkTuple<This, ChunkType>? {
|
open fun getInstantTuple(pos: ChunkPos): IWorldChunkTuple<This, ChunkType>? {
|
||||||
val getTuple = getChunkInternal(pos)
|
return this[pos]?.let { InstantWorldChunkTuple(this as This, it) }
|
||||||
|
|
||||||
if (getTuple != null)
|
|
||||||
return WorldChunkTuple(getTuple)
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun computeIfAbsentInternal(pos: ChunkPos): IWorldChunkTuple<This, ChunkType> {
|
/**
|
||||||
if (lastAccessedChunk?.chunk?.pos == pos) {
|
* Возвращает чанк на заданной позиции, создаёт его если он не существует
|
||||||
return lastAccessedChunk!!
|
*/
|
||||||
|
open fun computeIfAbsent(pos: ChunkPos): ChunkType {
|
||||||
|
val _lastAccessedChunk = lastAccessedChunk
|
||||||
|
|
||||||
|
if (_lastAccessedChunk?.pos == pos) {
|
||||||
|
return _lastAccessedChunk
|
||||||
}
|
}
|
||||||
|
|
||||||
return chunkMap.computeIfAbsent(pos, Object2ObjectFunction {
|
return chunkMap.computeIfAbsent(pos, Object2ObjectFunction {
|
||||||
val chunk = chunkFactory(pos)
|
val chunk = chunkFactory(pos)
|
||||||
|
|
||||||
val top = getChunkInternal(pos.up())
|
lastAccessedChunk = chunk
|
||||||
val left = getChunkInternal(pos.left())
|
|
||||||
val right = getChunkInternal(pos.right())
|
|
||||||
val bottom = getChunkInternal(pos.down())
|
|
||||||
|
|
||||||
val tuple = MutableWorldChunkTuple(
|
|
||||||
world = this as This,
|
|
||||||
chunk = chunk,
|
|
||||||
top = top,
|
|
||||||
left = left,
|
|
||||||
right = right,
|
|
||||||
bottom = bottom,
|
|
||||||
)
|
|
||||||
|
|
||||||
top?.bottom = tuple
|
|
||||||
left?.right = tuple
|
|
||||||
right?.left = tuple
|
|
||||||
bottom?.top = tuple
|
|
||||||
|
|
||||||
lastAccessedChunk = tuple
|
|
||||||
|
|
||||||
val orphanedInThisChunk = ArrayList<Entity>()
|
val orphanedInThisChunk = ArrayList<Entity>()
|
||||||
|
|
||||||
@ -377,88 +345,76 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
ent.chunk = chunk
|
ent.chunk = chunk
|
||||||
}
|
}
|
||||||
|
|
||||||
return@Object2ObjectFunction tuple
|
return@Object2ObjectFunction chunk
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun computeIfAbsent(pos: ChunkPos): IWorldChunkTuple<This, ChunkType> {
|
open fun getForegroundView(pos: ChunkPos): TileView? {
|
||||||
return WorldChunkTuple(computeIfAbsentInternal(pos))
|
val get = get(pos) ?: return null
|
||||||
}
|
val tuple = InstantWorldChunkTuple(this as This, get)
|
||||||
|
|
||||||
open fun getForegroundView(pos: ChunkPos): TileChunkView? {
|
return TileView(
|
||||||
val get = getChunkInternal(pos) ?: return null
|
center = tuple.chunk.foreground,
|
||||||
|
left = tuple.left?.chunk?.foreground,
|
||||||
return TileChunkView(
|
top = tuple.top?.chunk?.foreground,
|
||||||
center = get.chunk.foreground,
|
topLeft = tuple.topLeft?.chunk?.foreground,
|
||||||
left = get.left?.chunk?.foreground,
|
topRight = tuple.topRight?.chunk?.foreground,
|
||||||
top = get.top?.chunk?.foreground,
|
right = tuple.right?.chunk?.foreground,
|
||||||
topLeft = getChunkInternal(pos.up().left())?.chunk?.foreground,
|
bottom = tuple.bottom?.chunk?.foreground,
|
||||||
topRight = getChunkInternal(pos.up().right())?.chunk?.foreground,
|
bottomLeft = tuple.bottomLeft?.chunk?.foreground,
|
||||||
right = get.right?.chunk?.foreground,
|
bottomRight = tuple.bottomRight?.chunk?.foreground,
|
||||||
bottom = get.bottom?.chunk?.foreground,
|
|
||||||
bottomLeft = getChunkInternal(pos.down().left())?.chunk?.foreground,
|
|
||||||
bottomRight = getChunkInternal(pos.down().right())?.chunk?.foreground,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun getBackgroundView(pos: ChunkPos): TileChunkView? {
|
open fun getBackgroundView(pos: ChunkPos): TileView? {
|
||||||
val get = getChunkInternal(pos) ?: return null
|
val get = get(pos) ?: return null
|
||||||
|
val tuple = InstantWorldChunkTuple(this as This, get)
|
||||||
|
|
||||||
return TileChunkView(
|
return TileView(
|
||||||
center = get.chunk.background,
|
center = tuple.chunk.background,
|
||||||
left = get.left?.chunk?.background,
|
left = tuple.left?.chunk?.background,
|
||||||
top = get.top?.chunk?.background,
|
top = tuple.top?.chunk?.background,
|
||||||
topLeft = getChunkInternal(pos.up().left())?.chunk?.background,
|
topLeft = tuple.topLeft?.chunk?.background,
|
||||||
topRight = getChunkInternal(pos.up().right())?.chunk?.background,
|
topRight = tuple.topRight?.chunk?.background,
|
||||||
right = get.right?.chunk?.background,
|
right = tuple.right?.chunk?.background,
|
||||||
bottom = get.bottom?.chunk?.background,
|
bottom = tuple.bottom?.chunk?.background,
|
||||||
bottomLeft = getChunkInternal(pos.down().left())?.chunk?.background,
|
bottomLeft = tuple.bottomLeft?.chunk?.background,
|
||||||
bottomRight = getChunkInternal(pos.down().right())?.chunk?.background,
|
bottomRight = tuple.bottomRight?.chunk?.background,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getTile(pos: Vector2i): ChunkTile? {
|
fun getTile(pos: Vector2i): ChunkTile? {
|
||||||
return getChunkInternal(ChunkPos.fromTilePosition(pos))?.chunk?.foreground?.get(ChunkPos.normalizeCoordinate(pos.x), ChunkPos.normalizeCoordinate(pos.y))
|
return get(ChunkPos.fromTilePosition(pos))?.foreground?.get(ChunkPos.normalizeCoordinate(pos.x), ChunkPos.normalizeCoordinate(pos.y))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setTile(pos: Vector2i, tile: TileDefinition?): IWorldChunkTuple<This, ChunkType> {
|
fun setTile(pos: Vector2i, tile: TileDefinition?): ChunkType {
|
||||||
val chunk = computeIfAbsentInternal(ChunkPos.fromTilePosition(pos))
|
val chunk = computeIfAbsent(ChunkPos.fromTilePosition(pos))
|
||||||
chunk.chunk.foreground[ChunkPos.normalizeCoordinate(pos.x), ChunkPos.normalizeCoordinate(pos.y)] = tile
|
chunk.foreground[ChunkPos.normalizeCoordinate(pos.x), ChunkPos.normalizeCoordinate(pos.y)] = tile
|
||||||
return chunk
|
return chunk
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getBackgroundTile(pos: Vector2i): ChunkTile? {
|
fun getBackgroundTile(pos: Vector2i): ChunkTile? {
|
||||||
return getChunkInternal(ChunkPos.fromTilePosition(pos))?.chunk?.background?.get(ChunkPos.normalizeCoordinate(pos.x), ChunkPos.normalizeCoordinate(pos.y))
|
return get(ChunkPos.fromTilePosition(pos))?.background?.get(ChunkPos.normalizeCoordinate(pos.x), ChunkPos.normalizeCoordinate(pos.y))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setBackgroundTile(pos: Vector2i, tile: TileDefinition?): IWorldChunkTuple<This, ChunkType> {
|
fun setBackgroundTile(pos: Vector2i, tile: TileDefinition?): ChunkType {
|
||||||
val chunk = computeIfAbsentInternal(ChunkPos.fromTilePosition(pos))
|
val chunk = computeIfAbsent(ChunkPos.fromTilePosition(pos))
|
||||||
chunk.chunk.background[ChunkPos.normalizeCoordinate(pos.x), ChunkPos.normalizeCoordinate(pos.y)] = tile
|
chunk.background[ChunkPos.normalizeCoordinate(pos.x), ChunkPos.normalizeCoordinate(pos.y)] = tile
|
||||||
return chunk
|
return chunk
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun collectInternal(boundingBox: AABBi): List<IMutableWorldChunkTuple<This, ChunkType>> {
|
|
||||||
val output = ArrayList<IMutableWorldChunkTuple<This, ChunkType>>()
|
|
||||||
|
|
||||||
for (pos in boundingBox.chunkPositions) {
|
|
||||||
val chunk = getChunkInternal(pos)
|
|
||||||
|
|
||||||
if (chunk != null) {
|
|
||||||
output.add(chunk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return output
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Возвращает все чанки, которые пересекаются с заданным [boundingBox]
|
* Возвращает все чанки, которые пересекаются с заданным [boundingBox]
|
||||||
*/
|
*/
|
||||||
open fun collect(boundingBox: AABBi): List<IWorldChunkTuple<This, ChunkType>> {
|
open fun collect(boundingBox: AABBi): List<ChunkType> {
|
||||||
val output = ArrayList<IWorldChunkTuple<This, ChunkType>>()
|
val output = ArrayList<ChunkType>()
|
||||||
|
|
||||||
for (chunk in collectInternal(boundingBox)) {
|
for (pos in boundingBox.chunkPositions) {
|
||||||
output.add(WorldChunkTuple(chunk))
|
val chunk = get(pos)
|
||||||
|
|
||||||
|
if (chunk != null) {
|
||||||
|
output.add(chunk)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return output
|
return output
|
||||||
@ -475,11 +431,11 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
): WorldSweepResult {
|
): WorldSweepResult {
|
||||||
var deltaMovement = _deltaMovement
|
var deltaMovement = _deltaMovement
|
||||||
|
|
||||||
var potentialAABB = worldaabb + deltaMovement
|
val potentialAABB = worldaabb + deltaMovement
|
||||||
var combined = worldaabb.combine(potentialAABB)
|
val combined = worldaabb.combine(potentialAABB)
|
||||||
|
|
||||||
val collected = collectInternal((combined).encasingChunkPosAABB())
|
val collected = collect((combined).encasingChunkPosAABB())
|
||||||
.map { it.chunk.foreground.collisionLayers() }
|
.map { it.foreground.collisionLayers() }
|
||||||
.flatten()
|
.flatten()
|
||||||
.sortedWith { o1, o2 ->
|
.sortedWith { o1, o2 ->
|
||||||
val a = o1.distance(worldaabb)
|
val a = o1.distance(worldaabb)
|
||||||
@ -630,8 +586,8 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
* Возвращает, застрянет ли сущность будет с коллизией [worldaabb]
|
* Возвращает, застрянет ли сущность будет с коллизией [worldaabb]
|
||||||
*/
|
*/
|
||||||
fun isSpaceEmptyFromTiles(worldaabb: AABB): Boolean {
|
fun isSpaceEmptyFromTiles(worldaabb: AABB): Boolean {
|
||||||
val collected = collectInternal(worldaabb.encasingChunkPosAABB())
|
val collected = collect(worldaabb.encasingChunkPosAABB())
|
||||||
.map { it.chunk.foreground.collisionLayers() }
|
.map { it.foreground.collisionLayers() }
|
||||||
.flatten()
|
.flatten()
|
||||||
.sortedWith { o1, o2 ->
|
.sortedWith { o1, o2 ->
|
||||||
val a = o1.distance(worldaabb)
|
val a = o1.distance(worldaabb)
|
||||||
|
@ -130,7 +130,7 @@ abstract class Entity(override val world: World<*, *>) : IEntity {
|
|||||||
val newChunkPos = ChunkPos.fromTilePosition(value)
|
val newChunkPos = ChunkPos.fromTilePosition(value)
|
||||||
|
|
||||||
if (oldChunkPos != newChunkPos) {
|
if (oldChunkPos != newChunkPos) {
|
||||||
chunk = world.getChunk(newChunkPos)?.chunk
|
chunk = world[newChunkPos]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@ abstract class Entity(override val world: World<*, *>) : IEntity {
|
|||||||
|
|
||||||
isSpawned = true
|
isSpawned = true
|
||||||
world.entities.add(this)
|
world.entities.add(this)
|
||||||
chunk = world.getChunk(ChunkPos.fromTilePosition(position))?.chunk
|
chunk = world[ChunkPos.fromTilePosition(position)]
|
||||||
|
|
||||||
if (chunk == null) {
|
if (chunk == null) {
|
||||||
world.orphanedEntities.add(this)
|
world.orphanedEntities.add(this)
|
||||||
|
Loading…
Reference in New Issue
Block a user