mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-19 04:15:14 -04:00
occlusion: handle section updates, clamp biome y position at dimension height
In GH-4 I realized that the biome of the chunk (or extreme position) should be used as default biome and not null. This has nothing todo with the issue itself.
This commit is contained in:
parent
d6cd333ed4
commit
cbb2dfe241
@ -32,29 +32,29 @@ data class DimensionProperties(
|
||||
val bedWorks: Boolean = true,
|
||||
val skyProperties: ResourceLocation = ResourceLocation("overworld"),
|
||||
val hasRaids: Boolean = true,
|
||||
val logicalHeight: Int = 256,
|
||||
val logicalHeight: Int = DEFAULT_MAX_Y,
|
||||
val coordinateScale: Double = 0.0,
|
||||
val minY: Int = 0,
|
||||
val hasCeiling: Boolean = false,
|
||||
val ultraWarm: Boolean = false,
|
||||
@Deprecated("Height does not differ from logical height in 1.18")
|
||||
val dataHeight: Int = 256,
|
||||
val dataHeight: Int = DEFAULT_MAX_Y,
|
||||
val supports3DBiomes: Boolean = true,
|
||||
) {
|
||||
val height = logicalHeight + minY
|
||||
val lowestSection = if (minY < 0) {
|
||||
val maxY = logicalHeight + minY
|
||||
val minSection = if (minY < 0) {
|
||||
(minY + 1) / ProtocolDefinition.SECTION_HEIGHT_Y - 1
|
||||
} else {
|
||||
minY / ProtocolDefinition.SECTION_HEIGHT_Y
|
||||
}
|
||||
val highestSection = if (height < 0) {
|
||||
(height + 1) / ProtocolDefinition.SECTION_HEIGHT_Y - 1
|
||||
val maxSection = if (maxY < 0) {
|
||||
(maxY + 1) / ProtocolDefinition.SECTION_HEIGHT_Y - 1
|
||||
} else {
|
||||
height / ProtocolDefinition.SECTION_HEIGHT_Y
|
||||
maxY / ProtocolDefinition.SECTION_HEIGHT_Y
|
||||
}
|
||||
|
||||
val lightLevels = FloatArray(16)
|
||||
val sections = highestSection - lowestSection
|
||||
val sections = maxSection - minSection
|
||||
|
||||
init {
|
||||
val ambientLight = 0.0f // ToDo: 0.1 in nether
|
||||
@ -68,6 +68,8 @@ data class DimensionProperties(
|
||||
|
||||
|
||||
companion object {
|
||||
const val DEFAULT_MAX_Y = 256
|
||||
|
||||
fun deserialize(data: Map<String, Any>): DimensionProperties {
|
||||
return DimensionProperties(
|
||||
piglinSafe = data["piglin_safe"]?.toBoolean() ?: false,
|
||||
|
@ -22,6 +22,7 @@ import de.bixilon.minosoft.data.registries.blocks.types.entity.BlockWithEntity
|
||||
import de.bixilon.minosoft.data.world.ChunkSection.Companion.index
|
||||
import de.bixilon.minosoft.data.world.biome.accessor.BiomeAccessor
|
||||
import de.bixilon.minosoft.data.world.biome.source.BiomeSource
|
||||
import de.bixilon.minosoft.data.world.container.BlockSectionDataProvider
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkSectionPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.inSectionHeight
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight
|
||||
@ -41,8 +42,8 @@ class Chunk(
|
||||
private val world = connection.world
|
||||
var bottomLight: ByteArray? = null
|
||||
var topLight: ByteArray? = null
|
||||
val lowestSection = world.dimension!!.lowestSection
|
||||
val highestSection = world.dimension!!.highestSection
|
||||
val lowestSection = world.dimension!!.minSection
|
||||
val highestSection = world.dimension!!.maxSection
|
||||
val cacheBiomes = world.cacheBiomeAccessor != null
|
||||
|
||||
var blocksInitialized = false // All block data was received
|
||||
@ -179,7 +180,7 @@ class Chunk(
|
||||
|
||||
var section = sections[sectionIndex]
|
||||
if (section == null) {
|
||||
section = ChunkSection()
|
||||
section = ChunkSection(BlockSectionDataProvider(occlusionUpdateCallback = world.occlusionUpdateCallback))
|
||||
val neighbours: Array<Chunk> = world.getChunkNeighbours(chunkPosition).unsafeCast()
|
||||
val cacheBiomeAccessor = world.cacheBiomeAccessor
|
||||
if (cacheBiomeAccessor != null && biomesInitialized && neighboursLoaded) {
|
||||
|
@ -28,7 +28,7 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
* Collection of 16x16x16 blocks
|
||||
*/
|
||||
class ChunkSection(
|
||||
var blocks: BlockSectionDataProvider = BlockSectionDataProvider(),
|
||||
var blocks: BlockSectionDataProvider,
|
||||
var biomes: SectionDataProvider<Biome> = SectionDataProvider(checkSize = false),
|
||||
var blockEntities: SectionDataProvider<BlockEntity?> = SectionDataProvider(checkSize = false),
|
||||
var light: ByteArray = ByteArray(ProtocolDefinition.BLOCKS_PER_SECTION), // packed (skyLight: 0xF0, blockLight: 0x0F)
|
||||
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
interface OcclusionUpdateCallback {
|
||||
|
||||
fun onOcclusionChange()
|
||||
}
|
@ -76,6 +76,7 @@ class World(
|
||||
|
||||
override var audioPlayer: AbstractAudioPlayer? = null
|
||||
override var particleRenderer: AbstractParticleRenderer? = null
|
||||
var occlusionUpdateCallback: OcclusionUpdateCallback? = null
|
||||
|
||||
operator fun get(blockPosition: Vec3i): BlockState? {
|
||||
return chunks[blockPosition.chunkPosition]?.get(blockPosition.inChunkPosition)
|
||||
@ -125,7 +126,7 @@ class World(
|
||||
return false
|
||||
}
|
||||
val dimension = connection.world.dimension!!
|
||||
return (blockPosition.y >= dimension.minY || blockPosition.y < dimension.height)
|
||||
return (blockPosition.y >= dimension.minY || blockPosition.y < dimension.maxY)
|
||||
}
|
||||
|
||||
fun forceSetBlockState(blockPosition: Vec3i, blockState: BlockState?, check: Boolean = false) {
|
||||
@ -167,7 +168,16 @@ class World(
|
||||
}
|
||||
|
||||
override fun getBiome(blockPosition: Vec3i): Biome? {
|
||||
return this[blockPosition.chunkPosition]?.getBiome(blockPosition.inChunkPosition)
|
||||
val inChunkPosition = blockPosition.inChunkPosition
|
||||
val minY = dimension?.minY ?: 0
|
||||
if (inChunkPosition.y < minY) {
|
||||
inChunkPosition.y = minY
|
||||
}
|
||||
val maxY = dimension?.maxY ?: DimensionProperties.DEFAULT_MAX_Y
|
||||
if (inChunkPosition.y > maxY) {
|
||||
inChunkPosition.y = maxY
|
||||
}
|
||||
return this[blockPosition.chunkPosition]?.getBiome(inChunkPosition)
|
||||
}
|
||||
|
||||
override fun getBiome(x: Int, y: Int, z: Int): Biome? {
|
||||
|
@ -19,11 +19,13 @@ import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
||||
import de.bixilon.minosoft.data.registries.blocks.types.FluidBlock
|
||||
import de.bixilon.minosoft.data.registries.blocks.types.FluidFillable
|
||||
import de.bixilon.minosoft.data.world.OcclusionUpdateCallback
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet
|
||||
|
||||
class BlockSectionDataProvider(
|
||||
data: Array<BlockState?>? = null,
|
||||
val occlusionUpdateCallback: OcclusionUpdateCallback?,
|
||||
) : SectionDataProvider<BlockState?>(data, true, false) {
|
||||
var fluidCount = 0
|
||||
private set
|
||||
@ -264,7 +266,7 @@ class BlockSectionDataProvider(
|
||||
|
||||
if (!this.occlusion.contentEquals(occlusion)) {
|
||||
this.occlusion = occlusion
|
||||
// ToDo: Recalculate visibility graph
|
||||
occlusionUpdateCallback?.onOcclusionChange()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ class Camera(
|
||||
fun draw() {
|
||||
matrixHandler.entity.tick()
|
||||
matrixHandler.draw()
|
||||
visibilityGraph.draw()
|
||||
targetHandler.raycast()
|
||||
fogManager.draw()
|
||||
}
|
||||
|
@ -24,8 +24,8 @@ import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.camera.frustum.Frustum
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.CameraMatrixChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.CameraPositionChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.VisibilityGraphChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.blockPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight
|
||||
@ -151,7 +151,7 @@ class MatrixHandler(
|
||||
|
||||
private fun updateFrustum() {
|
||||
frustum.recalculate()
|
||||
connection.fireEvent(FrustumChangeEvent(renderWindow, frustum))
|
||||
connection.fireEvent(VisibilityGraphChangeEvent(renderWindow))
|
||||
}
|
||||
|
||||
private fun updateRotation(rotation: EntityRotation = entity.rotation) {
|
||||
|
@ -26,7 +26,7 @@ import de.bixilon.minosoft.data.entities.entities.Entity
|
||||
import de.bixilon.minosoft.data.player.LocalPlayerEntity
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.VisibilityGraphChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.renderer.Renderer
|
||||
import de.bixilon.minosoft.gui.rendering.renderer.RendererBuilder
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.DepthFunctions
|
||||
@ -71,7 +71,7 @@ class EntityHitboxRenderer(
|
||||
}
|
||||
toUnload += meshes.remove(it.entity) ?: return@of
|
||||
})
|
||||
connection.registerEvent(CallbackEventInvoker.of<FrustumChangeEvent> {
|
||||
connection.registerEvent(CallbackEventInvoker.of<VisibilityGraphChangeEvent> {
|
||||
if (!enabled) {
|
||||
return@of
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
@ -15,9 +15,7 @@ package de.bixilon.minosoft.gui.rendering.modding.events
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.Rendering
|
||||
import de.bixilon.minosoft.gui.rendering.camera.frustum.Frustum
|
||||
|
||||
class FrustumChangeEvent(
|
||||
class VisibilityGraphChangeEvent(
|
||||
renderWindow: RenderWindow = Rendering.currentContext!!,
|
||||
val frustum: Frustum,
|
||||
) : RenderEvent(renderWindow)
|
@ -40,8 +40,8 @@ import de.bixilon.minosoft.data.world.World
|
||||
import de.bixilon.minosoft.data.world.view.ViewDistanceChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.RenderingStates
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.RenderingStateChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.VisibilityGraphChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.renderer.Renderer
|
||||
import de.bixilon.minosoft.gui.rendering.renderer.RendererBuilder
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.DepthFunctions
|
||||
@ -160,7 +160,7 @@ class WorldRenderer(
|
||||
loadWorldShader(this.textShader, false)
|
||||
|
||||
|
||||
connection.registerEvent(CallbackEventInvoker.of<FrustumChangeEvent> { onFrustumChange() })
|
||||
connection.registerEvent(CallbackEventInvoker.of<VisibilityGraphChangeEvent> { onFrustumChange() })
|
||||
|
||||
connection.registerEvent(CallbackEventInvoker.of<RespawnEvent> { unloadWorld() })
|
||||
connection.registerEvent(CallbackEventInvoker.of<ChunkDataChangeEvent> { queueChunk(it.chunkPosition, it.chunk) })
|
||||
@ -715,7 +715,7 @@ class WorldRenderer(
|
||||
|
||||
val cameraSectionHeight = cameraPosition.blockPosition.sectionHeight
|
||||
val minSectionHeight = connection.world.dimension?.minY?.sectionHeight ?: 0
|
||||
val maxSectionHeight = connection.world.dimension?.height?.sectionHeight ?: 16
|
||||
val maxSectionHeight = connection.world.dimension?.maxY?.sectionHeight ?: 16
|
||||
|
||||
|
||||
val visible = VisibleMeshes(cameraPosition)
|
||||
|
@ -83,8 +83,8 @@ class ChunkBorderRenderer(
|
||||
else -> ChatColors.YELLOW
|
||||
}
|
||||
|
||||
mesh.drawLine(Vec3(basePosition.x + x, dimension.minY, basePosition.y), Vec3(basePosition.x + x, dimension.height, basePosition.y), RenderConstants.DEFAULT_LINE_WIDTH * 5, color)
|
||||
mesh.drawLine(Vec3(basePosition.x + x, dimension.minY, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), Vec3(basePosition.x + x, dimension.height, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), RenderConstants.DEFAULT_LINE_WIDTH * 5, color)
|
||||
mesh.drawLine(Vec3(basePosition.x + x, dimension.minY, basePosition.y), Vec3(basePosition.x + x, dimension.maxY, basePosition.y), RenderConstants.DEFAULT_LINE_WIDTH * 5, color)
|
||||
mesh.drawLine(Vec3(basePosition.x + x, dimension.minY, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), Vec3(basePosition.x + x, dimension.maxY, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), RenderConstants.DEFAULT_LINE_WIDTH * 5, color)
|
||||
}
|
||||
|
||||
for (z in 0..ProtocolDefinition.SECTION_WIDTH_Z) {
|
||||
@ -94,12 +94,12 @@ class ChunkBorderRenderer(
|
||||
else -> ChatColors.YELLOW
|
||||
}
|
||||
|
||||
mesh.drawLine(Vec3(basePosition.x, dimension.minY, basePosition.y + z), Vec3(basePosition.x, dimension.height, basePosition.y + z), RenderConstants.DEFAULT_LINE_WIDTH * 5, color)
|
||||
mesh.drawLine(Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, dimension.minY, basePosition.y + z), Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, dimension.height, basePosition.y + z), RenderConstants.DEFAULT_LINE_WIDTH * 5, color)
|
||||
mesh.drawLine(Vec3(basePosition.x, dimension.minY, basePosition.y + z), Vec3(basePosition.x, dimension.maxY, basePosition.y + z), RenderConstants.DEFAULT_LINE_WIDTH * 5, color)
|
||||
mesh.drawLine(Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, dimension.minY, basePosition.y + z), Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, dimension.maxY, basePosition.y + z), RenderConstants.DEFAULT_LINE_WIDTH * 5, color)
|
||||
}
|
||||
|
||||
// horizontal lines
|
||||
for (y in dimension.minY..dimension.height) {
|
||||
for (y in dimension.minY..dimension.maxY) {
|
||||
val borderColor = when {
|
||||
y % ProtocolDefinition.SECTION_HEIGHT_Y == 0 -> ChatColors.BLUE
|
||||
y % 2 == 0 -> ChatColors.GREEN
|
||||
|
@ -21,9 +21,11 @@ import de.bixilon.kutil.time.TimeUtil
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.AABB
|
||||
import de.bixilon.minosoft.data.world.Chunk
|
||||
import de.bixilon.minosoft.data.world.OcclusionUpdateCallback
|
||||
import de.bixilon.minosoft.data.world.container.BlockSectionDataProvider
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.camera.Camera
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.VisibilityGraphChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight
|
||||
@ -38,8 +40,8 @@ import it.unimi.dsi.fastutil.ints.IntOpenHashSet
|
||||
|
||||
class WorldVisibilityGraph(
|
||||
private val renderWindow: RenderWindow,
|
||||
private val camera: Camera,
|
||||
) {
|
||||
camera: Camera,
|
||||
) : OcclusionUpdateCallback {
|
||||
private val connection = renderWindow.connection
|
||||
private val frustum = camera.matrixHandler.frustum
|
||||
private var cameraChunkPosition = Vec2i.EMPTY
|
||||
@ -47,6 +49,8 @@ class WorldVisibilityGraph(
|
||||
private var viewDistance = connection.world.view.viewDistance
|
||||
private val chunks = connection.world.chunks.original
|
||||
|
||||
private var recalculateNextFrame = false
|
||||
|
||||
var minSection = 0
|
||||
var maxSection = 16
|
||||
var maxIndex = 15
|
||||
@ -67,6 +71,7 @@ class WorldVisibilityGraph(
|
||||
|
||||
init {
|
||||
calculateGraph()
|
||||
connection.world.occlusionUpdateCallback = this
|
||||
}
|
||||
|
||||
fun isInViewDistance(chunkPosition: Vec2i): Boolean {
|
||||
@ -140,8 +145,8 @@ class WorldVisibilityGraph(
|
||||
}
|
||||
this.cameraChunkPosition = chunkPosition
|
||||
this.cameraSectionHeight = sectionHeight
|
||||
this.minSection = connection.world.dimension?.lowestSection ?: 0
|
||||
this.maxSection = connection.world.dimension?.highestSection ?: 16
|
||||
this.minSection = connection.world.dimension?.minSection ?: 0
|
||||
this.maxSection = connection.world.dimension?.maxSection ?: 16
|
||||
this.sections = maxSection - minSection
|
||||
this.maxIndex = sections - 1
|
||||
calculateGraph()
|
||||
@ -250,6 +255,7 @@ class WorldVisibilityGraph(
|
||||
|
||||
private fun calculateGraph() {
|
||||
connection.world.chunks.lock.acquire()
|
||||
recalculateNextFrame = false
|
||||
val start = TimeUtil.nanos
|
||||
println("Calculating graph...")
|
||||
|
||||
@ -276,10 +282,11 @@ class WorldVisibilityGraph(
|
||||
updateVisibilityGraph(graph)
|
||||
|
||||
|
||||
|
||||
println("Done in ${(TimeUtil.nanos - start) / 1000}")
|
||||
|
||||
connection.world.chunks.lock.release()
|
||||
|
||||
connection.fireEvent(VisibilityGraphChangeEvent(renderWindow))
|
||||
}
|
||||
|
||||
private fun createVisibilityArray(): Array<BooleanArray> {
|
||||
@ -314,10 +321,14 @@ class WorldVisibilityGraph(
|
||||
visibilityLock.unlock()
|
||||
}
|
||||
|
||||
private fun createVisibilityStatus(sectionIndex: Int, `in`: Directions, out: Directions): Int {
|
||||
val preferIn = `in`.ordinal < out.ordinal
|
||||
override fun onOcclusionChange() {
|
||||
recalculateNextFrame = true
|
||||
}
|
||||
|
||||
return (sectionIndex and 0xFFFF shl 6) or ((if (preferIn) `in` else `out`).ordinal shl 3) or (if (preferIn) out else `in`).ordinal
|
||||
fun draw() {
|
||||
if (recalculateNextFrame) {
|
||||
calculateGraph()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -107,7 +107,7 @@ class ChunkS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
|
||||
}
|
||||
buffer.versionId < V_21W37A -> {
|
||||
val blockEntities: MutableMap<Vec3i, BlockEntity> = mutableMapOf()
|
||||
val positionOffset = Vec3i.of(chunkPosition, dimension.lowestSection, Vec3i.EMPTY)
|
||||
val positionOffset = Vec3i.of(chunkPosition, dimension.minSection, Vec3i.EMPTY)
|
||||
for (i in 0 until buffer.readVarInt()) {
|
||||
val nbt = buffer.readNBT().asJsonObject()
|
||||
val position = Vec3i(nbt["x"]?.toInt() ?: continue, nbt["y"]?.toInt() ?: continue, nbt["z"]?.toInt() ?: continue) - positionOffset
|
||||
|
@ -72,7 +72,7 @@ object ChunkUtil {
|
||||
// parse data
|
||||
var arrayPosition = 0
|
||||
val sectionBlocks: Array<BlockSectionDataProvider?> = arrayOfNulls(dimension.sections)
|
||||
for ((sectionIndex, sectionHeight) in (dimension.lowestSection until dimension.highestSection).withIndex()) {
|
||||
for ((sectionIndex, sectionHeight) in (dimension.minSection until dimension.maxSection).withIndex()) {
|
||||
if (!sectionBitMask[sectionIndex]) {
|
||||
continue
|
||||
}
|
||||
@ -103,7 +103,7 @@ object ChunkUtil {
|
||||
|
||||
blocks[blockNumber] = buffer.connection.registries.blockStateRegistry[blockId] ?: continue
|
||||
}
|
||||
sectionBlocks[sectionHeight] = BlockSectionDataProvider(blocks)
|
||||
sectionBlocks[sectionHeight] = BlockSectionDataProvider(blocks, buffer.connection.world.occlusionUpdateCallback)
|
||||
}
|
||||
chunkData.blocks = sectionBlocks
|
||||
return chunkData
|
||||
@ -138,7 +138,7 @@ object ChunkUtil {
|
||||
|
||||
var arrayPos = 0
|
||||
val sectionBlocks: Array<BlockSectionDataProvider?> = arrayOfNulls(dimension.sections)
|
||||
for ((sectionIndex, sectionHeight) in (dimension.lowestSection until dimension.highestSection).withIndex()) { // max sections per chunks in chunk column
|
||||
for ((sectionIndex, sectionHeight) in (dimension.minSection until dimension.maxSection).withIndex()) { // max sections per chunks in chunk column
|
||||
if (!sectionBitMask[sectionIndex]) {
|
||||
continue
|
||||
}
|
||||
@ -148,7 +148,7 @@ object ChunkUtil {
|
||||
val block = buffer.connection.registries.blockStateRegistry[blockId] ?: continue
|
||||
blocks[blockNumber] = block
|
||||
}
|
||||
sectionBlocks[sectionHeight] = BlockSectionDataProvider(blocks)
|
||||
sectionBlocks[sectionHeight] = BlockSectionDataProvider(blocks, buffer.connection.world.occlusionUpdateCallback)
|
||||
}
|
||||
chunkData.blocks = sectionBlocks
|
||||
return chunkData
|
||||
@ -161,7 +161,7 @@ object ChunkUtil {
|
||||
var lightReceived = 0
|
||||
val biomes: Array<Array<Biome>?> = arrayOfNulls(dimension.sections)
|
||||
|
||||
for ((sectionIndex, sectionHeight) in (dimension.lowestSection until (sectionBitMask?.length() ?: dimension.highestSection)).withIndex()) { // max sections per chunks in chunk column
|
||||
for ((sectionIndex, sectionHeight) in (dimension.minSection until (sectionBitMask?.length() ?: dimension.maxSection)).withIndex()) { // max sections per chunks in chunk column
|
||||
if (sectionBitMask?.get(sectionIndex) == false) {
|
||||
continue
|
||||
}
|
||||
@ -173,11 +173,11 @@ object ChunkUtil {
|
||||
val blockContainer: PalettedContainer<BlockState?> = PalettedContainerReader.read(buffer, buffer.connection.registries.blockStateRegistry, paletteFactory = BlockStatePaletteFactory)
|
||||
|
||||
if (blockContainer.palette !is SingularPalette<*> || blockContainer.palette.item != null) {
|
||||
sectionBlocks[sectionHeight - dimension.lowestSection] = BlockSectionDataProvider(blockContainer.unpack())
|
||||
sectionBlocks[sectionHeight - dimension.minSection] = BlockSectionDataProvider(blockContainer.unpack(), buffer.connection.world.occlusionUpdateCallback)
|
||||
}
|
||||
if (buffer.versionId >= V_21W37A) {
|
||||
val biomeContainer: PalettedContainer<Biome> = PalettedContainerReader.read(buffer, buffer.connection.registries.biomeRegistry, paletteFactory = BiomePaletteFactory)
|
||||
biomes[sectionHeight - dimension.lowestSection] = biomeContainer.unpack()
|
||||
biomes[sectionHeight - dimension.minSection] = biomeContainer.unpack()
|
||||
}
|
||||
|
||||
|
||||
@ -187,7 +187,7 @@ object ChunkUtil {
|
||||
if (containsSkyLight) {
|
||||
skyLight = buffer.readByteArray(ProtocolDefinition.BLOCKS_PER_SECTION / 2)
|
||||
}
|
||||
light[sectionHeight - dimension.lowestSection] = LightUtil.mergeLight(blockLight, skyLight ?: LightUtil.EMPTY_LIGHT_ARRAY)
|
||||
light[sectionHeight - dimension.minSection] = LightUtil.mergeLight(blockLight, skyLight ?: LightUtil.EMPTY_LIGHT_ARRAY)
|
||||
lightReceived++
|
||||
}
|
||||
}
|
||||
@ -197,7 +197,7 @@ object ChunkUtil {
|
||||
chunkData.light = light
|
||||
}
|
||||
if (buffer.versionId >= V_21W37A) {
|
||||
chunkData.biomeSource = PalettedBiomeArray(biomes, dimension.lowestSection, BiomePaletteFactory.edgeBits)
|
||||
chunkData.biomeSource = PalettedBiomeArray(biomes, dimension.minSection, BiomePaletteFactory.edgeBits)
|
||||
} else if (buffer.versionId < V_19W36A && isFullChunk) {
|
||||
chunkData.biomeSource = readLegacyBiomeArray(buffer)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user