mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-13 09:26:11 -04:00
inline block, chunk, in chunk position
This commit is contained in:
parent
387877fe27
commit
b655998304
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2024 Moritz Zwerger
|
||||
* Copyright (C) 2020-2025 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -37,7 +37,6 @@ class WorldBiomes(val world: World) : BiomeAccessor {
|
||||
operator fun get(position: BlockPosition) = getBiome(position)
|
||||
override fun getBiome(position: BlockPosition) = getBiome(position.x, position.y, position.z)
|
||||
|
||||
operator fun get(x: Int, y: Int, z: Int) = getBiome(x, y, z)
|
||||
override fun getBiome(x: Int, y: Int, z: Int): Biome? {
|
||||
val chunk = world.chunks[x shr 4, z shr 4] ?: return null
|
||||
return getBiome(x and 0x0F, y.clamp(world.dimension.minY, world.dimension.maxY), z and 0x0F, chunk)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
* Copyright (C) 2020-2025 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -13,15 +13,11 @@
|
||||
|
||||
package de.bixilon.minosoft.data.world.biome.accessor
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3i
|
||||
import de.bixilon.minosoft.data.registries.biomes.Biome
|
||||
import de.bixilon.minosoft.data.world.positions.InChunkPosition
|
||||
|
||||
|
||||
interface BiomeAccessor {
|
||||
|
||||
fun getBiome(position: Vec3i): Biome? {
|
||||
return getBiome(position.x, position.y, position.z)
|
||||
}
|
||||
|
||||
fun getBiome(x: Int, y: Int, z: Int): Biome?
|
||||
fun getBiome(position: InChunkPosition): Biome?
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
* Copyright (C) 2020-2025 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -13,17 +13,10 @@
|
||||
|
||||
package de.bixilon.minosoft.data.world.biome.accessor
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3i
|
||||
import de.bixilon.minosoft.data.registries.biomes.Biome
|
||||
import de.bixilon.minosoft.data.world.positions.InChunkPosition
|
||||
|
||||
|
||||
object NullBiomeAccessor : BiomeAccessor {
|
||||
|
||||
override fun getBiome(position: Vec3i): Biome? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getBiome(x: Int, y: Int, z: Int): Biome? {
|
||||
return null
|
||||
}
|
||||
override fun getBiome(position: InChunkPosition) = null
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2024 Moritz Zwerger
|
||||
* Copyright (C) 2020-2025 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -33,8 +33,8 @@ import de.bixilon.minosoft.data.world.chunk.update.chunk.prototype.PrototypeChan
|
||||
import de.bixilon.minosoft.data.world.positions.ChunkPosition
|
||||
|
||||
class ChunkManager(val world: World, chunkCapacity: Int = 0, prototypeCapacity: Int = 0) {
|
||||
val chunks: LockMap<Vec2i, Chunk> = LockMap(HashMap(chunkCapacity), world.lock)
|
||||
val prototypes: LockMap<Vec2i, ChunkPrototype> = LockMap(HashMap(prototypeCapacity), world.lock)
|
||||
val chunks: LockMap<ChunkPosition, Chunk> = LockMap(HashMap(chunkCapacity), world.lock)
|
||||
val prototypes: LockMap<ChunkPosition, ChunkPrototype> = LockMap(HashMap(prototypeCapacity), world.lock)
|
||||
val size = WorldSizeManager(world)
|
||||
val ticker = ChunkTicker(this)
|
||||
var revision by observed(0)
|
||||
@ -45,7 +45,7 @@ class ChunkManager(val world: World, chunkCapacity: Int = 0, prototypeCapacity:
|
||||
}
|
||||
|
||||
operator fun get(x: Int, z: Int): Chunk? {
|
||||
return this[Vec2i(x, z)]
|
||||
return this[ChunkPosition(x, z)]
|
||||
}
|
||||
|
||||
fun unload(position: ChunkPosition) {
|
||||
|
@ -21,6 +21,7 @@ import de.bixilon.minosoft.data.registries.blocks.state.BlockState
|
||||
import de.bixilon.minosoft.data.world.biome.accessor.noise.NoiseBiomeAccessor
|
||||
import de.bixilon.minosoft.data.world.chunk.ChunkSection
|
||||
import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
|
||||
import de.bixilon.minosoft.data.world.positions.ChunkPosition
|
||||
import de.bixilon.minosoft.data.world.positions.ChunkPositionUtil.chunkPosition
|
||||
import de.bixilon.minosoft.data.world.positions.SectionHeight
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.inChunkPosition
|
||||
@ -52,7 +53,7 @@ class ChunkNeighbours(val chunk: Chunk) : Iterable<Chunk?> {
|
||||
this.chunk.lock.unlock()
|
||||
}
|
||||
|
||||
operator fun set(offset: Vec2i, chunk: Chunk) {
|
||||
operator fun set(offset: ChunkPosition, chunk: Chunk) {
|
||||
set(getIndex(offset), chunk)
|
||||
}
|
||||
|
||||
@ -66,7 +67,7 @@ class ChunkNeighbours(val chunk: Chunk) : Iterable<Chunk?> {
|
||||
chunk.lock.unlock()
|
||||
}
|
||||
|
||||
fun remove(offset: Vec2i) {
|
||||
fun remove(offset: ChunkPosition) {
|
||||
remove(getIndex(offset))
|
||||
}
|
||||
|
||||
@ -114,8 +115,8 @@ class ChunkNeighbours(val chunk: Chunk) : Iterable<Chunk?> {
|
||||
}
|
||||
}
|
||||
|
||||
fun trace(offset: Vec2i): Chunk? {
|
||||
return trace(offset.x, offset.y)
|
||||
fun trace(offset: ChunkPosition): Chunk? {
|
||||
return trace(offset.x, offset.z)
|
||||
}
|
||||
|
||||
fun trace(offsetX: Int, offsetZ: Int): Chunk? = when {
|
||||
@ -177,26 +178,26 @@ class ChunkNeighbours(val chunk: Chunk) : Iterable<Chunk?> {
|
||||
*/
|
||||
|
||||
val OFFSETS = arrayOf(
|
||||
Vec2i(-1, -1), // 0
|
||||
Vec2i(-1, +0), // 1
|
||||
Vec2i(-1, +1), // 2
|
||||
Vec2i(+0, -1), // 3
|
||||
Vec2i(+0, +1), // 4
|
||||
Vec2i(+1, -1), // 5
|
||||
Vec2i(+1, +0), // 6
|
||||
Vec2i(+1, +1), // 7
|
||||
ChunkPosition(-1, -1), // 0
|
||||
ChunkPosition(-1, +0), // 1
|
||||
ChunkPosition(-1, +1), // 2
|
||||
ChunkPosition(+0, -1), // 3
|
||||
ChunkPosition(+0, +1), // 4
|
||||
ChunkPosition(+1, -1), // 5
|
||||
ChunkPosition(+1, +0), // 6
|
||||
ChunkPosition(+1, +1), // 7
|
||||
)
|
||||
|
||||
fun getIndex(offset: Vec2i): Int {
|
||||
fun getIndex(offset: ChunkPosition): Int {
|
||||
return when {
|
||||
offset.x == -1 && offset.y == -1 -> 0
|
||||
offset.x == -1 && offset.y == 0 -> 1
|
||||
offset.x == -1 && offset.y == 1 -> 2
|
||||
offset.x == 0 && offset.y == -1 -> 3
|
||||
offset.x == 0 && offset.y == 1 -> 4
|
||||
offset.x == 1 && offset.y == -1 -> 5
|
||||
offset.x == 1 && offset.y == 0 -> 6
|
||||
offset.x == 1 && offset.y == 1 -> 7
|
||||
offset.x == -1 && offset.z == -1 -> 0
|
||||
offset.x == -1 && offset.z == 0 -> 1
|
||||
offset.x == -1 && offset.z == 1 -> 2
|
||||
offset.x == 0 && offset.z == -1 -> 3
|
||||
offset.x == 0 && offset.z == 1 -> 4
|
||||
offset.x == 1 && offset.z == -1 -> 5
|
||||
offset.x == 1 && offset.z == 0 -> 6
|
||||
offset.x == 1 && offset.z == 1 -> 7
|
||||
else -> Broken("Can not get neighbour chunk from offset $offset")
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ class BiomeSectionDataProvider(
|
||||
var biome = super.get(x, inSectionY, z)
|
||||
if (biome != null) return biome
|
||||
biome = section.chunk.world.biomes.noise?.get(x, y, z, section.chunk)
|
||||
unsafeSet(x, inSectionY, z, biome)
|
||||
unsafeSet(InSectionPosition(x, inSectionY, z), biome)
|
||||
return biome
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* Copyright (C) 2020-2025 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -13,7 +13,102 @@
|
||||
|
||||
package de.bixilon.minosoft.data.world.positions
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3i
|
||||
import de.bixilon.minosoft.data.text.formatting.TextFormattable
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.util.KUtil.format
|
||||
|
||||
typealias BlockPosition = Vec3i
|
||||
typealias MutableBlockPosition = Vec3i
|
||||
@JvmInline
|
||||
value class BlockPosition(
|
||||
inline val index: Long,
|
||||
) : TextFormattable {
|
||||
|
||||
constructor(x: Int, y: Int, z: Int) : this((y and 0xFFF shl SHIFT_Y) or (z shl SHIFT_Z) or (x shl SHIFT_X)) {
|
||||
assert(x >= 0)
|
||||
assert(x <= ProtocolDefinition.SECTION_MAX_X)
|
||||
assert(y >= ProtocolDefinition.CHUNK_MIN_Y)
|
||||
assert(y <= ProtocolDefinition.CHUNK_MAX_Y)
|
||||
assert(z >= 0)
|
||||
assert(z <= ProtocolDefinition.SECTION_MAX_Z)
|
||||
}
|
||||
|
||||
inline val x: Int get() = (index and MASK_X) shr SHIFT_X
|
||||
inline val y: Int get() = (index and MASK_Y) shr SHIFT_Y
|
||||
inline val z: Int get() = (index and MASK_Z) shr SHIFT_Z
|
||||
inline val xz: Int get() = (index and MASK_Z or MASK_X)
|
||||
|
||||
|
||||
inline fun plusX(): BlockPosition {
|
||||
assert(this.x < ProtocolDefinition.SECTION_MAX_X)
|
||||
return BlockPosition(index + X * 1)
|
||||
}
|
||||
|
||||
inline fun plusX(x: Int): BlockPosition {
|
||||
assert(this.x + x < ProtocolDefinition.SECTION_MAX_X)
|
||||
assert(this.x + x > 0)
|
||||
return BlockPosition(index + X * x)
|
||||
}
|
||||
|
||||
inline fun minusX(): BlockPosition {
|
||||
assert(this.x > 0)
|
||||
return BlockPosition(index - X * 1)
|
||||
}
|
||||
|
||||
inline fun plusY(): BlockPosition {
|
||||
assert(this.y < ProtocolDefinition.CHUNK_MAX_Y)
|
||||
return BlockPosition(index + Y * 1)
|
||||
}
|
||||
|
||||
inline fun plusY(y: Int): BlockPosition {
|
||||
assert(this.y + y < ProtocolDefinition.CHUNK_MAX_Y)
|
||||
assert(this.y + y > ProtocolDefinition.CHUNK_MIN_Y)
|
||||
return BlockPosition(index + Y * y)
|
||||
}
|
||||
|
||||
inline fun minusY(): BlockPosition {
|
||||
assert(this.y > ProtocolDefinition.CHUNK_MIN_Y)
|
||||
return BlockPosition(index - Y * 1)
|
||||
}
|
||||
|
||||
inline fun plusZ(): BlockPosition {
|
||||
assert(this.z < ProtocolDefinition.SECTION_MAX_Z)
|
||||
return BlockPosition(index + Z * 1)
|
||||
}
|
||||
|
||||
inline fun plusZ(z: Int): BlockPosition {
|
||||
assert(this.z + z < ProtocolDefinition.SECTION_MAX_Z)
|
||||
assert(this.z + z > 0)
|
||||
return BlockPosition(index + Z * z)
|
||||
}
|
||||
|
||||
inline fun minusZ(): BlockPosition {
|
||||
assert(this.z > 0)
|
||||
return BlockPosition(index - Z * 1)
|
||||
}
|
||||
|
||||
inline fun with(x: Int = this.x, y: Int = this.y, z: Int = this.z) = BlockPosition(x, y, z)
|
||||
|
||||
inline operator fun plus(position: BlockPosition) = BlockPosition(this.x + position.x, this.y + position.y, this.z + position.z)
|
||||
|
||||
inline operator fun unaryMinus() = BlockPosition(-this.x, -this.y, -this.z)
|
||||
inline operator fun unaryPlus() = this
|
||||
|
||||
companion object {
|
||||
const val MASK_X = 0x00F
|
||||
const val SHIFT_X = 0
|
||||
|
||||
const val MASK_Z = 0x0F0
|
||||
const val SHIFT_Z = 4
|
||||
|
||||
const val MASK_Y = 0xFFF00
|
||||
const val SHIFT_Y = 8
|
||||
|
||||
const val X = 1 shl SHIFT_X
|
||||
const val Z = 1 shl SHIFT_Z
|
||||
const val Y = 1 shl SHIFT_Y
|
||||
|
||||
|
||||
val EMPTY = BlockPosition(0, 0, 0)
|
||||
}
|
||||
|
||||
override fun toText() = "(${this.x.format()} ${this.y.format()} ${this.z.format()})"
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* Copyright (C) 2020-2025 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -13,7 +13,79 @@
|
||||
|
||||
package de.bixilon.minosoft.data.world.positions
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.minosoft.data.text.formatting.TextFormattable
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.util.KUtil.format
|
||||
|
||||
typealias ChunkPosition = Vec2i
|
||||
typealias MutableChunkPosition = Vec2i
|
||||
@JvmInline
|
||||
value class ChunkPosition(
|
||||
inline val index: Long,
|
||||
) : TextFormattable {
|
||||
|
||||
constructor(x: Int, z: Int) : this((z shl SHIFT_Z) or (x shl SHIFT_X)) {
|
||||
assert(x >= 0)
|
||||
assert(x <= ProtocolDefinition.SECTION_MAX_X)
|
||||
assert(z >= 0)
|
||||
assert(z <= ProtocolDefinition.SECTION_MAX_Z)
|
||||
}
|
||||
|
||||
inline val x: Int get() = (index and MASK_X) shr SHIFT_X
|
||||
inline val z: Int get() = (index and MASK_Z) shr SHIFT_Z
|
||||
inline val xz: Int get() = (index and MASK_Z or MASK_X)
|
||||
|
||||
|
||||
inline fun plusX(): ChunkPosition {
|
||||
assert(this.x < ProtocolDefinition.SECTION_MAX_X)
|
||||
return ChunkPosition(index + X * 1)
|
||||
}
|
||||
|
||||
inline fun plusX(x: Int): ChunkPosition {
|
||||
assert(this.x + x < ProtocolDefinition.SECTION_MAX_X)
|
||||
assert(this.x + x > 0)
|
||||
return ChunkPosition(index + X * x)
|
||||
}
|
||||
|
||||
inline fun minusX(): ChunkPosition {
|
||||
assert(this.x > 0)
|
||||
return ChunkPosition(index - X * 1)
|
||||
}
|
||||
|
||||
inline fun plusZ(): ChunkPosition {
|
||||
assert(this.z < ProtocolDefinition.SECTION_MAX_Z)
|
||||
return ChunkPosition(index + Z * 1)
|
||||
}
|
||||
|
||||
inline fun plusZ(z: Int): ChunkPosition {
|
||||
assert(this.z + z < ProtocolDefinition.SECTION_MAX_Z)
|
||||
assert(this.z + z > 0)
|
||||
return ChunkPosition(index + Z * z)
|
||||
}
|
||||
|
||||
inline fun minusZ(): ChunkPosition {
|
||||
assert(this.z > 0)
|
||||
return ChunkPosition(index - Z * 1)
|
||||
}
|
||||
|
||||
inline fun with(x: Int = this.x, y: Int = this.y, z: Int = this.z) = ChunkPosition(x, y, z)
|
||||
|
||||
inline operator fun plus(position: ChunkPosition) = ChunkPosition(this.x + position.x, this.z + position.z)
|
||||
|
||||
inline operator fun unaryMinus() = ChunkPosition(-this.x, -this.z)
|
||||
inline operator fun unaryPlus() = this
|
||||
|
||||
companion object {
|
||||
const val MASK_X = 0x00F
|
||||
const val SHIFT_X = 0
|
||||
|
||||
const val MASK_Z = 0x0F0
|
||||
const val SHIFT_Z = 4
|
||||
|
||||
const val X = 1 shl SHIFT_X
|
||||
const val Z = 1 shl SHIFT_Z
|
||||
|
||||
|
||||
val EMPTY = ChunkPosition(0, 0)
|
||||
}
|
||||
|
||||
override fun toText() = "(${this.x.format()} ${this.z.format()})"
|
||||
}
|
||||
|
@ -13,9 +13,7 @@
|
||||
|
||||
package de.bixilon.minosoft.data.world.positions
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.kotlinglm.vec3.Vec3d
|
||||
import de.bixilon.kotlinglm.vec3.Vec3i
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.inSectionHeight
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight
|
||||
|
||||
@ -32,20 +30,8 @@ object ChunkPositionUtil {
|
||||
get() = ChunkPosition(x.toInt() shr 4, z.toInt() shr 4)
|
||||
|
||||
val BlockPosition.inChunkPosition: InChunkPosition
|
||||
get() = Vec3i(x and 0x0F, y, this.z and 0x0F)
|
||||
get() = InChunkPosition(x and 0x0F, y, this.z and 0x0F)
|
||||
|
||||
val BlockPosition.inSectionPosition: InSectionPosition
|
||||
get() = InSectionPosition(x and 0x0F, y.inSectionHeight, z and 0x0F)
|
||||
|
||||
|
||||
fun Vec2i.assignChunkPosition(position: Vec3i) {
|
||||
this.x = position.x shr 4
|
||||
this.y = position.z shr 4
|
||||
}
|
||||
|
||||
fun Vec3i.assignInChunkPosition(position: Vec3i) {
|
||||
this.x = position.x and 0x0F
|
||||
this.y = position.y and 0x0F
|
||||
this.z = position.z and 0x0F
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* Copyright (C) 2020-2025 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -13,7 +13,99 @@
|
||||
|
||||
package de.bixilon.minosoft.data.world.positions
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3i
|
||||
import de.bixilon.minosoft.data.text.formatting.TextFormattable
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.util.KUtil.format
|
||||
|
||||
typealias InChunkPosition = Vec3i
|
||||
typealias MutableInChunkPosition = Vec3i
|
||||
@JvmInline
|
||||
value class InChunkPosition(
|
||||
inline val index: Int,
|
||||
) : TextFormattable {
|
||||
|
||||
constructor(x: Int, y: Int, z: Int) : this((y and 0xFFF shl SHIFT_Y) or (z shl SHIFT_Z) or (x shl SHIFT_X)) {
|
||||
assert(x >= 0)
|
||||
assert(x <= ProtocolDefinition.SECTION_MAX_X)
|
||||
assert(y >= ProtocolDefinition.CHUNK_MIN_Y)
|
||||
assert(y <= ProtocolDefinition.CHUNK_MAX_Y)
|
||||
assert(z >= 0)
|
||||
assert(z <= ProtocolDefinition.SECTION_MAX_Z)
|
||||
}
|
||||
|
||||
inline val x: Int get() = (index and MASK_X) shr SHIFT_X
|
||||
inline val y: Int get() = (index and MASK_Y) shr SHIFT_Y
|
||||
inline val z: Int get() = (index and MASK_Z) shr SHIFT_Z
|
||||
inline val xz: Int get() = (index and MASK_Z or MASK_X)
|
||||
|
||||
|
||||
inline fun plusX(): InChunkPosition {
|
||||
assert(this.x < ProtocolDefinition.SECTION_MAX_X)
|
||||
return InChunkPosition(index + X * 1)
|
||||
}
|
||||
|
||||
inline fun plusX(x: Int): InChunkPosition {
|
||||
assert(this.x + x < ProtocolDefinition.SECTION_MAX_X)
|
||||
assert(this.x + x > 0)
|
||||
return InChunkPosition(index + X * x)
|
||||
}
|
||||
|
||||
inline fun minusX(): InChunkPosition {
|
||||
assert(this.x > 0)
|
||||
return InChunkPosition(index - X * 1)
|
||||
}
|
||||
|
||||
inline fun plusY(): InChunkPosition {
|
||||
assert(this.y < ProtocolDefinition.CHUNK_MAX_Y)
|
||||
return InChunkPosition(index + Y * 1)
|
||||
}
|
||||
|
||||
inline fun plusY(y: Int): InChunkPosition {
|
||||
assert(this.y + y < ProtocolDefinition.CHUNK_MAX_Y)
|
||||
assert(this.y + y > ProtocolDefinition.CHUNK_MIN_Y)
|
||||
return InChunkPosition(index + Y * y)
|
||||
}
|
||||
|
||||
inline fun minusY(): InChunkPosition {
|
||||
assert(this.y > ProtocolDefinition.CHUNK_MIN_Y)
|
||||
return InChunkPosition(index - Y * 1)
|
||||
}
|
||||
|
||||
inline fun plusZ(): InChunkPosition {
|
||||
assert(this.z < ProtocolDefinition.SECTION_MAX_Z)
|
||||
return InChunkPosition(index + Z * 1)
|
||||
}
|
||||
|
||||
inline fun plusZ(z: Int): InChunkPosition {
|
||||
assert(this.z + z < ProtocolDefinition.SECTION_MAX_Z)
|
||||
assert(this.z + z > 0)
|
||||
return InChunkPosition(index + Z * z)
|
||||
}
|
||||
|
||||
inline fun minusZ(): InChunkPosition {
|
||||
assert(this.z > 0)
|
||||
return InChunkPosition(index - Z * 1)
|
||||
}
|
||||
|
||||
inline fun with(x: Int = this.x, y: Int = this.y, z: Int = this.z) = InChunkPosition(x, y, z)
|
||||
|
||||
inline operator fun plus(position: InChunkPosition) = InChunkPosition(this.x + position.x, this.y + position.y, this.z + position.z)
|
||||
|
||||
companion object {
|
||||
const val MASK_X = 0x00F
|
||||
const val SHIFT_X = 0
|
||||
|
||||
const val MASK_Z = 0x0F0
|
||||
const val SHIFT_Z = 4
|
||||
|
||||
const val MASK_Y = 0xFFF00
|
||||
const val SHIFT_Y = 8
|
||||
|
||||
const val X = 1 shl SHIFT_X
|
||||
const val Z = 1 shl SHIFT_Z
|
||||
const val Y = 1 shl SHIFT_Y
|
||||
|
||||
|
||||
val EMPTY = InChunkPosition(0, 0, 0)
|
||||
}
|
||||
|
||||
override fun toText() = "(${this.x.format()} ${this.y.format()} ${this.z.format()})"
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.data.world.positions
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3i
|
||||
|
||||
typealias InChunkSectionPosition = Vec3i
|
||||
typealias MutableInChunkSectionPosition = Vec3i
|
@ -35,6 +35,8 @@ value class InSectionPosition(
|
||||
inline val y: Int get() = (index and MASK_Y) shr SHIFT_Y
|
||||
inline val z: Int get() = (index and MASK_Z) shr SHIFT_Z
|
||||
|
||||
inline val xz: Int get() = index and (MASK_X or MASK_Z)
|
||||
|
||||
|
||||
inline fun plusX(): InSectionPosition {
|
||||
assert(this.x < ProtocolDefinition.SECTION_MAX_X)
|
||||
|
@ -34,6 +34,7 @@ import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
|
||||
import de.bixilon.minosoft.data.world.chunk.light.SectionLight
|
||||
import de.bixilon.minosoft.data.world.chunk.neighbours.ChunkNeighbours
|
||||
import de.bixilon.minosoft.data.world.positions.BlockPosition
|
||||
import de.bixilon.minosoft.data.world.positions.InChunkPosition
|
||||
import de.bixilon.minosoft.data.world.positions.InSectionPosition
|
||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||
import de.bixilon.minosoft.gui.rendering.chunk.entities.BlockEntityRenderer
|
||||
@ -97,7 +98,6 @@ class SolidSectionMesher(
|
||||
position.x = offsetX + x
|
||||
floatOffset[0] = (position.x - cameraOffset.x).toFloat()
|
||||
for (z in blocks.minPosition.z..blocks.maxPosition.z) {
|
||||
val baseIndex = (z shl 4) or x
|
||||
inSectionPosition = inSectionPosition.with(z = z)
|
||||
val state = blocks[inSectionPosition] ?: continue
|
||||
if (state.block is FluidBlock) continue // fluids are rendered in a different renderer
|
||||
@ -112,18 +112,18 @@ class SolidSectionMesher(
|
||||
position.z = offsetZ + z
|
||||
floatOffset[2] = (position.z - cameraOffset.z).toFloat()
|
||||
|
||||
val maxHeight = chunk.light.heightmap[baseIndex]
|
||||
val maxHeight = chunk.light.heightmap[inSectionPosition.xz]
|
||||
if (position.y >= maxHeight) {
|
||||
light[SELF_LIGHT_INDEX] = (light[SELF_LIGHT_INDEX].toInt() or 0xF0).toByte()
|
||||
}
|
||||
|
||||
checkDown(state, fastBedrock, baseIndex, isLowestSection, neighbourBlocks, neighbours, x, y, z, light, section, chunk)
|
||||
checkUp(isHighestSection, baseIndex, neighbourBlocks, neighbours, x, y, z, light, section, chunk)
|
||||
checkDown(state, fastBedrock, inSectionPosition, isLowestSection, neighbourBlocks, neighbours, light, section, chunk)
|
||||
checkUp(isHighestSection, inSectionPosition, neighbourBlocks, neighbours, light, section, chunk)
|
||||
|
||||
checkNorth(neighbourBlocks, neighbours, x, y, z, light, position, neighbourChunks, section, chunk)
|
||||
checkSouth(neighbourBlocks, neighbours, x, y, z, light, position, neighbourChunks, section, chunk)
|
||||
checkWest(neighbourBlocks, neighbours, x, y, z, light, position, neighbourChunks, section, chunk)
|
||||
checkEast(neighbourBlocks, neighbours, x, y, z, light, position, neighbourChunks, section, chunk)
|
||||
checkNorth(neighbourBlocks, inSectionPosition, neighbours, light, position, neighbourChunks, section, chunk)
|
||||
checkSouth(neighbourBlocks, inSectionPosition, neighbours, light, position, neighbourChunks, section, chunk)
|
||||
checkWest(neighbourBlocks, inSectionPosition, neighbours, light, position, neighbourChunks, section, chunk)
|
||||
checkEast(neighbourBlocks, inSectionPosition, neighbours, light, position, neighbourChunks, section, chunk)
|
||||
|
||||
// TODO: cull neighbours
|
||||
|
||||
@ -167,31 +167,31 @@ class SolidSectionMesher(
|
||||
mesh.blockEntities = entities
|
||||
}
|
||||
|
||||
private inline fun checkDown(state: BlockState, fastBedrock: Boolean, baseIndex: Int, lowest: Boolean, neighbourBlocks: Array<BlockState?>, neighbours: Array<ChunkSection?>, x: Int, y: Int, z: Int, light: ByteArray, section: ChunkSection, chunk: Chunk) {
|
||||
if (y == 0) {
|
||||
private inline fun checkDown(state: BlockState, fastBedrock: Boolean, position: InSectionPosition, lowest: Boolean, neighbourBlocks: Array<BlockState?>, neighbours: Array<ChunkSection?>, light: ByteArray, section: ChunkSection, chunk: Chunk) {
|
||||
if (position.y == 0) {
|
||||
if (fastBedrock && state === bedrock) {
|
||||
neighbourBlocks[O_DOWN] = bedrock
|
||||
} else {
|
||||
neighbourBlocks[O_DOWN] = neighbours[O_DOWN]?.blocks?.let { it[x, ProtocolDefinition.SECTION_MAX_Y, z] }
|
||||
light[O_DOWN] = (if (lowest) chunk.light.bottom else neighbours[O_DOWN]?.light)?.get(ProtocolDefinition.SECTION_MAX_Y shl 8 or baseIndex) ?: 0x00
|
||||
neighbourBlocks[O_DOWN] = neighbours[O_DOWN]?.blocks?.let { it[position.with(y = ProtocolDefinition.SECTION_MAX_Y)] }
|
||||
light[O_DOWN] = (if (lowest) chunk.light.bottom else neighbours[O_DOWN]?.light)?.get(position.with(y = ProtocolDefinition.SECTION_MAX_Y).index) ?: 0x00
|
||||
}
|
||||
} else {
|
||||
neighbourBlocks[O_DOWN] = section.blocks[(y - 1) shl 8 or baseIndex]
|
||||
light[O_DOWN] = section.light[(y - 1) shl 8 or baseIndex]
|
||||
neighbourBlocks[O_DOWN] = section.blocks[position.minusY()]
|
||||
light[O_DOWN] = section.light[position.minusY().index]
|
||||
}
|
||||
}
|
||||
|
||||
fun checkUp(highest: Boolean, baseIndex: Int, neighbourBlocks: Array<BlockState?>, neighbours: Array<ChunkSection?>, x: Int, y: Int, z: Int, light: ByteArray, section: ChunkSection, chunk: Chunk) {
|
||||
fun checkUp(highest: Boolean, position: InSectionPosition, neighbourBlocks: Array<BlockState?>, neighbours: Array<ChunkSection?>, light: ByteArray, section: ChunkSection, chunk: Chunk) {
|
||||
if (y == ProtocolDefinition.SECTION_MAX_Y) {
|
||||
neighbourBlocks[O_UP] = neighbours[O_UP]?.blocks?.let { it[x, 0, z] }
|
||||
light[O_UP] = (if (highest) chunk.light.top else neighbours[O_UP]?.light)?.get((z shl 4) or x) ?: 0x00
|
||||
neighbourBlocks[O_UP] = neighbours[O_UP]?.blocks?.let { it[position.with(y = 0)] }
|
||||
light[O_UP] = (if (highest) chunk.light.top else neighbours[O_UP]?.light)?.get(position.with(y = 0).index) ?: 0x00
|
||||
} else {
|
||||
neighbourBlocks[O_UP] = section.blocks[(y + 1) shl 8 or baseIndex]
|
||||
light[O_UP] = section.light[(y + 1) shl 8 or baseIndex]
|
||||
neighbourBlocks[O_UP] = section.blocks[position.plusY()]
|
||||
light[O_UP] = section.light[position.plusY().index]
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun checkNorth(neighbourBlocks: Array<BlockState?>, neighbours: Array<ChunkSection?>, x: Int, y: Int, z: Int, light: ByteArray, position: Vec3i, neighbourChunks: Array<Chunk>, section: ChunkSection, chunk: Chunk) {
|
||||
private inline fun checkNorth(neighbourBlocks: Array<BlockState?>, position: InSectionPosition, neighbours: Array<ChunkSection?>, light: ByteArray, position: Vec3i, neighbourChunks: Array<Chunk>, section: ChunkSection, chunk: Chunk) {
|
||||
if (z == 0) {
|
||||
setNeighbour(neighbourBlocks, x, y, ProtocolDefinition.SECTION_MAX_Z, light, position, neighbours[O_NORTH], neighbourChunks[ChunkNeighbours.NORTH], O_NORTH)
|
||||
} else {
|
||||
@ -199,7 +199,7 @@ class SolidSectionMesher(
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun checkSouth(neighbourBlocks: Array<BlockState?>, neighbours: Array<ChunkSection?>, x: Int, y: Int, z: Int, light: ByteArray, position: Vec3i, neighbourChunks: Array<Chunk>, section: ChunkSection, chunk: Chunk) {
|
||||
private inline fun checkSouth(neighbourBlocks: Array<BlockState?>, position: InSectionPosition, neighbours: Array<ChunkSection?>, light: ByteArray, position: Vec3i, neighbourChunks: Array<Chunk>, section: ChunkSection, chunk: Chunk) {
|
||||
if (z == ProtocolDefinition.SECTION_MAX_Z) {
|
||||
setNeighbour(neighbourBlocks, x, y, 0, light, position, neighbours[O_SOUTH], neighbourChunks[ChunkNeighbours.SOUTH], O_SOUTH)
|
||||
} else {
|
||||
@ -207,7 +207,7 @@ class SolidSectionMesher(
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun checkWest(neighbourBlocks: Array<BlockState?>, neighbours: Array<ChunkSection?>, x: Int, y: Int, z: Int, light: ByteArray, position: Vec3i, neighbourChunks: Array<Chunk>, section: ChunkSection, chunk: Chunk) {
|
||||
private inline fun checkWest(neighbourBlocks: Array<BlockState?>, position: InSectionPosition, neighbours: Array<ChunkSection?>, light: ByteArray, position: Vec3i, neighbourChunks: Array<Chunk>, section: ChunkSection, chunk: Chunk) {
|
||||
if (x == 0) {
|
||||
setNeighbour(neighbourBlocks, ProtocolDefinition.SECTION_MAX_X, y, z, light, position, neighbours[O_WEST], neighbourChunks[ChunkNeighbours.WEST], O_WEST)
|
||||
} else {
|
||||
@ -215,7 +215,7 @@ class SolidSectionMesher(
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun checkEast(neighbourBlocks: Array<BlockState?>, neighbours: Array<ChunkSection?>, x: Int, y: Int, z: Int, light: ByteArray, position: Vec3i, neighbourChunks: Array<Chunk>, section: ChunkSection, chunk: Chunk) {
|
||||
private inline fun checkEast(neighbourBlocks: Array<BlockState?>, position: InSectionPosition, neighbours: Array<ChunkSection?>, light: ByteArray, position: Vec3i, neighbourChunks: Array<Chunk>, section: ChunkSection, chunk: Chunk) {
|
||||
if (x == ProtocolDefinition.SECTION_MAX_X) {
|
||||
setNeighbour(neighbourBlocks, 0, y, z, light, position, neighbours[O_EAST], neighbourChunks[ChunkNeighbours.EAST], O_EAST)
|
||||
} else {
|
||||
@ -223,12 +223,10 @@ class SolidSectionMesher(
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun setNeighbour(neighbourBlocks: Array<BlockState?>, x: Int, y: Int, z: Int, light: ByteArray, position: Vec3i, section: ChunkSection?, chunk: Chunk, ordinal: Int) {
|
||||
val heightmapIndex = (z shl 4) or x
|
||||
val neighbourIndex = y shl 8 or heightmapIndex
|
||||
neighbourBlocks[ordinal] = section?.blocks?.let { it[neighbourIndex] }
|
||||
light[ordinal] = section?.light?.get(neighbourIndex) ?: 0x00
|
||||
if (position.y >= chunk.light.heightmap[heightmapIndex]) {
|
||||
private inline fun setNeighbour(neighbourBlocks: Array<BlockState?>, position: InChunkPosition, light: ByteArray, section: ChunkSection?, chunk: Chunk, ordinal: Int) {
|
||||
neighbourBlocks[ordinal] = section?.blocks?.let { it[position] }
|
||||
light[ordinal] = section?.light?.get(position.index) ?: 0x00
|
||||
if (position.y >= chunk.light.heightmap[position.x]) {
|
||||
light[ordinal] = (light[ordinal].toInt() or SectionLight.SKY_LIGHT_MASK).toByte() // set sky light to 0x0F
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2025 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.data.world.positions
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class BlockPositionTest {
|
||||
|
||||
@Test
|
||||
fun `init correct min`() {
|
||||
val position = BlockPosition(-30_000_000, -2048, -30_000_000)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `init correct max`() {
|
||||
val position = BlockPosition(30_000_000, 2047, 30_000_000)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `init badly`() {
|
||||
assertThrows<AssertionError> { BlockPosition(-40_000_000, -5000, -40_000_000) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct positive x`() {
|
||||
val position = BlockPosition(2, 0xF, 0xF)
|
||||
assertEquals(position.x, 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct negative x`() {
|
||||
val position = BlockPosition(-2, 0xF, 0xF)
|
||||
assertEquals(position.x, -2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus x`() {
|
||||
val position = BlockPosition(2, 0xF, 0xF)
|
||||
assertEquals(position.plusX().x, 3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus 2 x`() {
|
||||
val position = BlockPosition(2, 0xF, 0xF)
|
||||
assertEquals(position.plusX(2).x, 4)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct minus x`() {
|
||||
val position = BlockPosition(2, 0xF, 0xF)
|
||||
assertEquals(position.minusX().x, 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct negative y`() {
|
||||
val position = BlockPosition(0xF, -1000, 0xF)
|
||||
assertEquals(position.y, -1000)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct positive y`() {
|
||||
val position = BlockPosition(0xF, 1000, 0xF)
|
||||
assertEquals(position.y, 1000)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus y`() {
|
||||
val position = BlockPosition(0xF, 2, 0xF)
|
||||
assertEquals(position.plusY().y, 3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus 2 y`() {
|
||||
val position = BlockPosition(0xF, 2, 0xF)
|
||||
assertEquals(position.plusY(2).y, 4)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct minus y`() {
|
||||
val position = BlockPosition(0xF, 2, 0xF)
|
||||
assertEquals(position.minusY().y, 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct positive z`() {
|
||||
val position = BlockPosition(0xF, 0xF, 4)
|
||||
assertEquals(position.z, 4)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct negative z`() {
|
||||
val position = BlockPosition(0xF, 0xF, -4)
|
||||
assertEquals(position.z, -4)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus z`() {
|
||||
val position = BlockPosition(0xF, 0xF, 2)
|
||||
assertEquals(position.plusZ().z, 3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus 2 z`() {
|
||||
val position = BlockPosition(0xF, 0xF, 2)
|
||||
assertEquals(position.plusZ(2).z, 4)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct minus z`() {
|
||||
val position = BlockPosition(0xF, 0xF, 2)
|
||||
assertEquals(position.minusZ().z, 1)
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2025 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.data.world.positions
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ChunkPositionTest {
|
||||
|
||||
@Test
|
||||
fun `init correct min`() {
|
||||
val position = ChunkPosition(-1875000, -1875000)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `init correct max`() {
|
||||
val position = ChunkPosition(1875000, 1875000)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `init badly`() {
|
||||
assertThrows<AssertionError> { ChunkPosition(-40_000_000, -40_000_000) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct positive x`() {
|
||||
val position = ChunkPosition(2, 0xF)
|
||||
assertEquals(position.x, 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct negative x`() {
|
||||
val position = ChunkPosition(-2, 0xF)
|
||||
assertEquals(position.x, -2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus x`() {
|
||||
val position = ChunkPosition(2, 0xF)
|
||||
assertEquals(position.plusX().x, 3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus 2 x`() {
|
||||
val position = ChunkPosition(2, 0xF)
|
||||
assertEquals(position.plusX(2).x, 4)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct minus x`() {
|
||||
val position = ChunkPosition(2, 0xF)
|
||||
assertEquals(position.minusX().x, 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct positive z`() {
|
||||
val position = ChunkPosition(0xF, 4)
|
||||
assertEquals(position.z, 4)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct negative z`() {
|
||||
val position = ChunkPosition(0xF, -4)
|
||||
assertEquals(position.z, -4)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus z`() {
|
||||
val position = ChunkPosition(0xF, 2)
|
||||
assertEquals(position.plusZ().z, 3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus 2 z`() {
|
||||
val position = ChunkPosition(0xF, 2)
|
||||
assertEquals(position.plusZ(2).z, 4)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct minus z`() {
|
||||
val position = ChunkPosition(0xF, 2)
|
||||
assertEquals(position.minusZ().z, 1)
|
||||
}
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2025 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.data.world.positions
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class InChunkPositionTest {
|
||||
|
||||
|
||||
@Test
|
||||
fun `init correct min`() {
|
||||
val position = InSectionPosition(0, -2048, 0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `init correct max`() {
|
||||
val position = InSectionPosition(15, 2047, 15)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `init badly`() {
|
||||
assertThrows<AssertionError> { InSectionPosition(-1, -5000, -1) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct x`() {
|
||||
val position = InSectionPosition(2, 0xF, 0xF)
|
||||
assertEquals(position.x, 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus x`() {
|
||||
val position = InSectionPosition(2, 0xF, 0xF)
|
||||
assertEquals(position.plusX().x, 3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus 2 x`() {
|
||||
val position = InSectionPosition(2, 0xF, 0xF)
|
||||
assertEquals(position.plusX(2).x, 4)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct minus x`() {
|
||||
val position = InSectionPosition(2, 0xF, 0xF)
|
||||
assertEquals(position.minusX().x, 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct y`() {
|
||||
val position = InSectionPosition(0xF, 3, 0xF)
|
||||
assertEquals(position.y, 3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct negative y`() {
|
||||
val position = InSectionPosition(0xF, -1000, 0xF)
|
||||
assertEquals(position.y, -1000)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct positive y`() {
|
||||
val position = InSectionPosition(0xF, 1000, 0xF)
|
||||
assertEquals(position.y, 1000)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus y`() {
|
||||
val position = InSectionPosition(0xF, 2, 0xF)
|
||||
assertEquals(position.plusY().y, 3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus 2 y`() {
|
||||
val position = InSectionPosition(0xF, 2, 0xF)
|
||||
assertEquals(position.plusY(2).y, 4)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct minus y`() {
|
||||
val position = InSectionPosition(0xF, 2, 0xF)
|
||||
assertEquals(position.minusY().y, 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct z`() {
|
||||
val position = InSectionPosition(0xF, 0xF, 4)
|
||||
assertEquals(position.z, 4)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus z`() {
|
||||
val position = InSectionPosition(0xF, 0xF, 2)
|
||||
assertEquals(position.plusZ().z, 3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus 2 z`() {
|
||||
val position = InSectionPosition(0xF, 0xF, 2)
|
||||
assertEquals(position.plusZ(2).z, 4)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct minus z`() {
|
||||
val position = InSectionPosition(0xF, 0xF, 2)
|
||||
assertEquals(position.minusZ().z, 1)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user