mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 10:25:06 -04:00
performance: improve light storage a lot
This commit is contained in:
parent
9b7f70366b
commit
6dd2d3c5d3
@ -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 {
|
||||
|
@ -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<Int, MutableMap<InChunkPosition, Byte>> = mutableMapOf(),
|
||||
private val skyLightLevel: MutableMap<Int, MutableMap<InChunkPosition, Byte>> = mutableMapOf(),
|
||||
private val blockLightLevel: MutableMap<Int, ByteArray> = mutableMapOf(),
|
||||
private val skyLightLevel: MutableMap<Int, ByteArray> = 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<Int, ByteArray>, 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) {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
}
|
||||
}
|
||||
|
@ -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]])
|
||||
|
||||
|
@ -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)})"
|
||||
}
|
||||
|
||||
|
||||
|
@ -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<Int, MutableMap<InChunkPosition, Byte>> {
|
||||
private fun readLightArray(buffer: InByteBuffer, lightMask: BitSet, dimension: Dimension): MutableMap<Int, ByteArray> {
|
||||
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<Int, MutableMap<InChunkPosition, Byte>> = mutableMapOf()
|
||||
val lightLevels: MutableMap<Int, ByteArray> = mutableMapOf()
|
||||
|
||||
|
||||
for ((arrayIndex, sectionHeight) in (lowesSectionIndex until highestSectionIndex).withIndex()) { // light sections
|
||||
val currentSectionLightLevel: MutableMap<InChunkPosition, Byte> = 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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user