diff --git a/src/main/java/de/bixilon/minosoft/data/world/BlockPosition.kt b/src/main/java/de/bixilon/minosoft/data/world/BlockPosition.kt index 8f1292795..f16a19a3f 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/BlockPosition.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/BlockPosition.kt @@ -57,8 +57,7 @@ data class BlockPosition(val x: Int, val y: Int, val z: Int) { } fun getInChunkSectionPosition(): InChunkSectionPosition { - val location = getInChunkPosition() - return InChunkSectionPosition(location.x, getSectionHeight(), location.z) + return getInChunkPosition().getInChunkSectionLocation() } fun getSectionHeight(): Int { diff --git a/src/main/java/de/bixilon/minosoft/data/world/light/ChunkLightAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/light/ChunkLightAccessor.kt index cf7669fa1..e77eff35d 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/light/ChunkLightAccessor.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/light/ChunkLightAccessor.kt @@ -14,18 +14,33 @@ package de.bixilon.minosoft.data.world.light import de.bixilon.minosoft.data.world.BlockPosition -import de.bixilon.minosoft.data.world.InChunkPosition +import de.bixilon.minosoft.data.world.InChunkSectionPosition +import unsigned.toUInt class ChunkLightAccessor( - private val blockLightLevel: MutableMap> = mutableMapOf(), - private val skyLightLevel: MutableMap> = mutableMapOf(), + private val blockLightLevel: MutableMap = mutableMapOf(), + private val skyLightLevel: MutableMap = mutableMapOf(), ) : LightAccessor { - override fun getSkyLight(blockPosition: BlockPosition): Byte { - return skyLightLevel[blockPosition.getSectionHeight()]?.get(blockPosition.getInChunkPosition()) ?: 0 + override fun getSkyLight(blockPosition: BlockPosition): Int { + return get(skyLightLevel, blockPosition) } - override fun getBlockLight(blockPosition: BlockPosition): Byte { - return blockLightLevel[blockPosition.getSectionHeight()]?.get(blockPosition.getInChunkPosition()) ?: 0 + override fun getBlockLight(blockPosition: BlockPosition): Int { + return get(blockLightLevel, blockPosition) + } + + private fun get(data: MutableMap, blockPosition: BlockPosition): Int { + val index = getIndex(blockPosition.getInChunkSectionPosition()) + val byte = data[blockPosition.getSectionHeight()]?.get(index ushr 1)?.toUInt() ?: 0xFF + return if (index and 0x01 == 0) { // first nibble + byte and 0x0F + } else { + ((byte) shr 4) and 0x0F + } + } + + private fun getIndex(inChunkSectionPosition: InChunkSectionPosition): Int { + return inChunkSectionPosition.y shl 8 or (inChunkSectionPosition.z shl 4) or inChunkSectionPosition.x } fun merge(chunkLightAccessor: ChunkLightAccessor) { diff --git a/src/main/java/de/bixilon/minosoft/data/world/light/DummyLightAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/light/DummyLightAccessor.kt index cce59c31b..a750fefc9 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/light/DummyLightAccessor.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/light/DummyLightAccessor.kt @@ -16,11 +16,11 @@ package de.bixilon.minosoft.data.world.light import de.bixilon.minosoft.data.world.BlockPosition object DummyLightAccessor : LightAccessor { - override fun getSkyLight(blockPosition: BlockPosition): Byte { + override fun getSkyLight(blockPosition: BlockPosition): Int { return 15 } - override fun getBlockLight(blockPosition: BlockPosition): Byte { + override fun getBlockLight(blockPosition: BlockPosition): Int { return 15 } diff --git a/src/main/java/de/bixilon/minosoft/data/world/light/LightAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/light/LightAccessor.kt index 40ac49d3c..de7a78abe 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/light/LightAccessor.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/light/LightAccessor.kt @@ -17,11 +17,11 @@ import de.bixilon.minosoft.data.world.BlockPosition interface LightAccessor { - fun getSkyLight(blockPosition: BlockPosition): Byte + fun getSkyLight(blockPosition: BlockPosition): Int - fun getBlockLight(blockPosition: BlockPosition): Byte + fun getBlockLight(blockPosition: BlockPosition): Int - fun getLightLevel(blockPosition: BlockPosition): Byte { + fun getLightLevel(blockPosition: BlockPosition): Int { val blockLight = getBlockLight(blockPosition) val skyLight = getSkyLight(blockPosition) if (blockLight > skyLight) { diff --git a/src/main/java/de/bixilon/minosoft/data/world/light/WorldLightAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/light/WorldLightAccessor.kt index 5074acf7f..a084344cb 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/light/WorldLightAccessor.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/light/WorldLightAccessor.kt @@ -19,11 +19,11 @@ import de.bixilon.minosoft.data.world.World class WorldLightAccessor( private val world: World, ) : LightAccessor { - override fun getSkyLight(blockPosition: BlockPosition): Byte { + override fun getSkyLight(blockPosition: BlockPosition): Int { return world.chunks[blockPosition.getChunkPosition()]?.lightAccessor?.getSkyLight(blockPosition) ?: 0 } - override fun getBlockLight(blockPosition: BlockPosition): Byte { + override fun getBlockLight(blockPosition: BlockPosition): Int { return world.chunks[blockPosition.getChunkPosition()]?.lightAccessor?.getBlockLight(blockPosition) ?: 0 } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkMesh.kt index ec23a9f62..072635a0b 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkMesh.kt @@ -25,7 +25,7 @@ import org.lwjgl.opengl.GL20.glVertexAttribPointer class ChunkMesh : Mesh() { - fun addVertex(position: Vec3, textureCoordinates: Vec2, texture: Texture, tintColor: RGBColor?, lightLevel: Byte = 14) { + fun addVertex(position: Vec3, textureCoordinates: Vec2, texture: Texture, tintColor: RGBColor?, lightLevel: Int = 14) { data.add(position.x) data.add(position.y) data.add(position.z) @@ -44,7 +44,12 @@ class ChunkMesh : Mesh() { data.add(Float.fromBits(tintColor.color)) } - data.add(lightLevel / MAX_LIGHT_LEVEL) + val rightLightLevel = if (lightLevel == 0) { + 1 + } else { + lightLevel + 1 + } + data.add(rightLightLevel / MAX_LIGHT_LEVEL) } override fun load() { @@ -75,6 +80,6 @@ class ChunkMesh : Mesh() { companion object { private const val FLOATS_PER_VERTEX = 11 - private const val MAX_LIGHT_LEVEL = 15f + private const val MAX_LIGHT_LEVEL = 17f // Level 0 and 15 kind of does not exist here. } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/ElementRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/ElementRenderer.kt index 95fc5b999..f2c5ec556 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/ElementRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/ElementRenderer.kt @@ -62,7 +62,7 @@ class ElementRenderer(element: BlockModelElement, rotation: Vec3, uvLock: Boolea // if (texture.isTransparent) { // return // ToDo: force render transparent faces // } - val lightLevel = lightAccessor.getLightLevel(position + face.cullFace) // ToDo: rotate cullface + val lightLevel = lightAccessor.getLightLevel(position + directionMapping[face.cullFace]) // ToDo: rotate cullface val drawPositions = arrayOf(positions[positionTemplate[0]], positions[positionTemplate[1]], positions[positionTemplate[2]], positions[positionTemplate[3]]) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDDebugScreenElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDDebugScreenElement.kt index 3ec640a2c..7f43c033f 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDDebugScreenElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDDebugScreenElement.kt @@ -170,7 +170,7 @@ class HUDDebugScreenElement(private val hudTextElement: HUDTextElement) : HUDTex val yaw = hudTextElement.renderWindow.camera.yaw val pitch = hudTextElement.renderWindow.camera.pitch val direction = Directions.byDirection(camera.cameraFront) - return "${Directions.byDirection(camera.cameraFront).name.toLowerCase()} (${direction.directionVector} (${formatRotation(yaw)} / ${formatRotation(pitch)})" + return "${Directions.byDirection(camera.cameraFront).name.toLowerCase()} ${direction.directionVector} (${formatRotation(yaw)} / ${formatRotation(pitch)})" } diff --git a/src/main/java/de/bixilon/minosoft/util/chunk/LightUtil.kt b/src/main/java/de/bixilon/minosoft/util/chunk/LightUtil.kt index 758e99962..09121a405 100644 --- a/src/main/java/de/bixilon/minosoft/util/chunk/LightUtil.kt +++ b/src/main/java/de/bixilon/minosoft/util/chunk/LightUtil.kt @@ -14,7 +14,6 @@ package de.bixilon.minosoft.util.chunk import de.bixilon.minosoft.data.mappings.Dimension -import de.bixilon.minosoft.data.world.InChunkPosition import de.bixilon.minosoft.data.world.light.ChunkLightAccessor import de.bixilon.minosoft.data.world.light.LightAccessor import de.bixilon.minosoft.protocol.protocol.InByteBuffer @@ -34,7 +33,7 @@ object LightUtil { return ChunkLightAccessor(blockLight, skyLight) } - private fun readLightArray(buffer: InByteBuffer, lightMask: BitSet, dimension: Dimension): MutableMap> { + private fun readLightArray(buffer: InByteBuffer, lightMask: BitSet, dimension: Dimension): MutableMap { var highestSectionIndex = dimension.highestSection + 1 val lowesSectionIndex = dimension.lowestSection - 1 if (buffer.versionId >= ProtocolVersions.V_20W49A) { @@ -42,26 +41,14 @@ object LightUtil { highestSectionIndex = lightMask.length() } - val lightLevels: MutableMap> = mutableMapOf() + val lightLevels: MutableMap = mutableMapOf() for ((arrayIndex, sectionHeight) in (lowesSectionIndex until highestSectionIndex).withIndex()) { // light sections - val currentSectionLightLevel: MutableMap = mutableMapOf() if (!lightMask[arrayIndex]) { continue } - val lightArray = buffer.readBytes(buffer.readVarInt()) - var index = 0 - for (y in 0 until 16) { - for (z in 0 until 16) { - for (x in 0 until 16 step 2) { - currentSectionLightLevel[InChunkPosition(x, y + sectionHeight * 16, z)] = (lightArray[index].toInt() and 0x0F).toByte() - currentSectionLightLevel[InChunkPosition(x + 1, y + sectionHeight * 16, z)] = ((lightArray[index].toInt() ushr 4) and 0x0F).toByte() - index++ - } - } - } - lightLevels[sectionHeight] = currentSectionLightLevel + lightLevels[sectionHeight] = buffer.readBytes(buffer.readVarInt()) } return lightLevels }