KStarbound/src/main/kotlin/ru/dbotthepony/kstarbound/world/ChunkPos.kt

191 lines
4.2 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package ru.dbotthepony.kstarbound.world
import ru.dbotthepony.kstarbound.math.roundByAbsoluteValue
import ru.dbotthepony.kvector.api.IStruct2d
import ru.dbotthepony.kvector.api.IStruct2i
import ru.dbotthepony.kvector.vector.nint.Vector2i
import kotlin.math.absoluteValue
private fun circulate(value: Int, bounds: Int): Int {
require(bounds > 0) { "Bounds must be positive ($bounds given)" }
if (value >= bounds) {
return value % bounds
} else if (value < 0) {
return bounds + value % bounds
}
return value
}
/**
* Сетка чанков идёт как и сетка тайлов.
*
* * Вправо у нас положительный X
* * Влево у нас отрицательный X
* * Вверх у нас положительный Y
* * Вниз у нас отрицательный Y
*/
class ChunkPos(val x: Int, val y: Int) : Comparable<ChunkPos> {
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)
/**
* Координата тайла на 0 позиции по оси X внутри чанка в мире
*/
val tileX: Int get() = x shl CHUNK_SHIFT
/**
* Координата тайла на 0 позиции по оси Y внутри чанка в мире
*/
val tileY: Int get() = y shl CHUNK_SHIFT
val top: ChunkPos
get() {
return ChunkPos(x, y + 1)
}
val bottom: ChunkPos
get() {
return ChunkPos(x, y - 1)
}
val left: ChunkPos
get() {
return ChunkPos(x - 1, y)
}
val topLeft: ChunkPos
get() {
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 {
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)
}
fun circular(xWrap: Int): ChunkPos {
val x = circulate(x, xWrap)
if (x == this.x) {
return this
}
return ChunkPos(x, y)
}
fun toLong(): Long {
return toLong(x, y)
}
companion object {
val ZERO = ChunkPos(0, 0)
fun toLong(x: Int, y: Int): Long {
return x.toLong() or (y.toLong() shl 32)
}
fun fromTilePosition(input: IStruct2i): ChunkPos {
val (x, y) = input
return ChunkPos(tileToChunkComponent(x), tileToChunkComponent(y))
}
fun fromTilePosition(input: IStruct2i, xWrap: Int): ChunkPos {
val (x, y) = input
return ChunkPos(circulate(tileToChunkComponent(x), xWrap), tileToChunkComponent(y))
}
fun fromTilePosition(input: IStruct2d): ChunkPos {
val (x, y) = input
return fromTilePosition(x, y)
}
fun fromTilePosition(input: IStruct2d, xWrap: Int): ChunkPos {
val (x, y) = input
return fromTilePosition(x, y, xWrap)
}
fun fromTilePosition(x: Int, y: Int): ChunkPos {
return ChunkPos(tileToChunkComponent(x), tileToChunkComponent(y))
}
fun fromTilePosition(x: Int, y: Int, xWrap: Int): ChunkPos {
return ChunkPos(circulate(tileToChunkComponent(x), xWrap), tileToChunkComponent(y))
}
fun fromTilePosition(x: Double, y: Double): ChunkPos {
return ChunkPos(
tileToChunkComponent(roundByAbsoluteValue(x)),
tileToChunkComponent(roundByAbsoluteValue(y))
)
}
fun fromTilePosition(x: Double, y: Double, xWrap: Int): ChunkPos {
return ChunkPos(
circulate(tileToChunkComponent(roundByAbsoluteValue(x)), xWrap),
tileToChunkComponent(roundByAbsoluteValue(y))
)
}
fun normalizeCoordinate(input: Int): Int {
val band = input and CHUNK_SIZE_FF
if (band < 0) {
return band + CHUNK_SIZE_FF
}
return band
}
fun tileToChunkComponent(comp: Int): Int {
if (comp < 0) {
return -(comp.absoluteValue shr CHUNK_SHIFT) - 1
}
return comp shr CHUNK_SHIFT
}
}
}