mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-10 16:01:50 -04:00
cleanup solid mesher a bit, fix light heightmap
Might be a little bit slower now...
This commit is contained in:
parent
8b0ac1944f
commit
d6223cf873
@ -91,6 +91,12 @@ class SectionOcclusionTest {
|
|||||||
assertEquals(occlusion.occlusion, BooleanArray(15) { if (it <= 4) true else false })
|
assertEquals(occlusion.occlusion, BooleanArray(15) { if (it <= 4) true else false })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun `everything except bottom line filled opaque`() {
|
||||||
|
val occlusion = create()
|
||||||
|
occlusion[0, 1, 0, 15, 15, 15] = opaque
|
||||||
|
assertEquals(occlusion.occlusion, booleanArrayOf(true, false, false, false, false, true, true, true, true, false, false, false, false, false, false))
|
||||||
|
}
|
||||||
|
|
||||||
fun `y=1 line filled opaque`() {
|
fun `y=1 line filled opaque`() {
|
||||||
val occlusion = create()
|
val occlusion = create()
|
||||||
occlusion[0, 1, 0, 15, 1, 15] = opaque
|
occlusion[0, 1, 0, 15, 1, 15] = opaque
|
||||||
|
@ -184,14 +184,10 @@ class ChunkRenderer(
|
|||||||
lock.lock()
|
lock.lock()
|
||||||
|
|
||||||
meshingQueue.tasks.interrupt(chunkPosition)
|
meshingQueue.tasks.interrupt(chunkPosition)
|
||||||
|
|
||||||
culledQueue.remove(chunkPosition, false)
|
culledQueue.remove(chunkPosition, false)
|
||||||
|
|
||||||
meshingQueue.remove(chunkPosition)
|
meshingQueue.remove(chunkPosition)
|
||||||
|
|
||||||
loadingQueue.abort(chunkPosition, false)
|
loadingQueue.abort(chunkPosition, false)
|
||||||
|
|
||||||
|
|
||||||
loaded.unload(chunkPosition, false)
|
loaded.unload(chunkPosition, false)
|
||||||
|
|
||||||
lock.unlock()
|
lock.unlock()
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.chunk.mesher
|
package de.bixilon.minosoft.gui.rendering.chunk.mesher
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3
|
|
||||||
import de.bixilon.kutil.cast.CastUtil.nullCast
|
import de.bixilon.kutil.cast.CastUtil.nullCast
|
||||||
import de.bixilon.kutil.observer.DataObserver.Companion.observe
|
import de.bixilon.kutil.observer.DataObserver.Companion.observe
|
||||||
import de.bixilon.minosoft.data.direction.Directions
|
import de.bixilon.minosoft.data.direction.Directions
|
||||||
@ -29,7 +28,7 @@ import de.bixilon.minosoft.data.registries.blocks.types.fluid.FluidBlock
|
|||||||
import de.bixilon.minosoft.data.registries.blocks.types.properties.offset.OffsetBlock
|
import de.bixilon.minosoft.data.registries.blocks.types.properties.offset.OffsetBlock
|
||||||
import de.bixilon.minosoft.data.world.chunk.ChunkSection
|
import de.bixilon.minosoft.data.world.chunk.ChunkSection
|
||||||
import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
|
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.light.SectionLight.Companion.SKY_LIGHT_MASK
|
||||||
import de.bixilon.minosoft.data.world.chunk.neighbours.ChunkNeighbourArray
|
import de.bixilon.minosoft.data.world.chunk.neighbours.ChunkNeighbourArray
|
||||||
import de.bixilon.minosoft.data.world.positions.BlockPosition
|
import de.bixilon.minosoft.data.world.positions.BlockPosition
|
||||||
import de.bixilon.minosoft.data.world.positions.InChunkPosition
|
import de.bixilon.minosoft.data.world.positions.InChunkPosition
|
||||||
@ -69,16 +68,12 @@ class SolidSectionMesher(
|
|||||||
val entities: ArrayList<BlockEntityRenderer<*>> = ArrayList(section.blockEntities.count)
|
val entities: ArrayList<BlockEntityRenderer<*>> = ArrayList(section.blockEntities.count)
|
||||||
|
|
||||||
val tint = IntArray(1)
|
val tint = IntArray(1)
|
||||||
var position = BlockPosition()
|
|
||||||
var inSectionPosition = InSectionPosition(0, 0, 0)
|
|
||||||
val neighbourBlocks: Array<BlockState?> = arrayOfNulls(Directions.SIZE)
|
val neighbourBlocks: Array<BlockState?> = arrayOfNulls(Directions.SIZE)
|
||||||
val light = ByteArray(Directions.SIZE + 1) // last index (6) for the current block
|
val light = ByteArray(Directions.SIZE + 1) // last index (6) for the current block
|
||||||
|
|
||||||
val cameraOffset = context.camera.offset.offset
|
val cameraOffset = context.camera.offset.offset
|
||||||
|
|
||||||
val offsetX = sectionPosition.x * ProtocolDefinition.SECTION_WIDTH_X
|
val offset = BlockPosition.of(sectionPosition)
|
||||||
val offsetY = sectionPosition.y * ProtocolDefinition.SECTION_HEIGHT_Y
|
|
||||||
val offsetZ = sectionPosition.z * ProtocolDefinition.SECTION_WIDTH_Z
|
|
||||||
|
|
||||||
val floatOffset = FloatArray(3)
|
val floatOffset = FloatArray(3)
|
||||||
|
|
||||||
@ -88,55 +83,50 @@ class SolidSectionMesher(
|
|||||||
|
|
||||||
|
|
||||||
for (y in blocks.minPosition.y..blocks.maxPosition.y) {
|
for (y in blocks.minPosition.y..blocks.maxPosition.y) {
|
||||||
inSectionPosition = inSectionPosition.with(y = y)
|
|
||||||
position = position.with(y = offsetY + y)
|
|
||||||
floatOffset[1] = (position.y - cameraOffset.y).toFloat()
|
|
||||||
val fastBedrock = y == 0 && isLowestSection && fastBedrock
|
val fastBedrock = y == 0 && isLowestSection && fastBedrock
|
||||||
for (x in blocks.minPosition.x..blocks.maxPosition.x) {
|
for (x in blocks.minPosition.x..blocks.maxPosition.x) {
|
||||||
inSectionPosition = inSectionPosition.with(x = x)
|
|
||||||
position = position.with(x = offsetX + x)
|
|
||||||
floatOffset[0] = (position.x - cameraOffset.x).toFloat()
|
|
||||||
for (z in blocks.minPosition.z..blocks.maxPosition.z) {
|
for (z in blocks.minPosition.z..blocks.maxPosition.z) {
|
||||||
inSectionPosition = inSectionPosition.with(z = z)
|
val inSection = InSectionPosition(x, y, z)
|
||||||
val state = blocks[inSectionPosition] ?: continue
|
val state = blocks[inSection] ?: continue
|
||||||
if (state.block is FluidBlock) continue // fluids are rendered in a different renderer
|
if (state.block is FluidBlock) continue // fluids are rendered in a different renderer
|
||||||
|
|
||||||
val model = state.block.model ?: state.model
|
val model = state.block.model ?: state.model
|
||||||
val blockEntity = section.blockEntities[inSectionPosition]
|
val blockEntity = section.blockEntities[inSection]
|
||||||
val renderedBlockEntity = blockEntity?.nullCast<RenderedBlockEntity<*>>()
|
val renderedBlockEntity = blockEntity?.nullCast<RenderedBlockEntity<*>>()
|
||||||
if (model == null && renderedBlockEntity == null) continue
|
if (model == null && renderedBlockEntity == null) continue
|
||||||
|
|
||||||
|
val position = offset + inSection
|
||||||
light[SELF_LIGHT_INDEX] = section.light[inSectionPosition]
|
val inChunk = InChunkPosition(inSection.x, position.y, inSection.z)
|
||||||
position = position.with(z = offsetZ + z)
|
floatOffset[0] = (position.x - cameraOffset.x).toFloat()
|
||||||
|
floatOffset[1] = (position.y - cameraOffset.y).toFloat()
|
||||||
floatOffset[2] = (position.z - cameraOffset.z).toFloat()
|
floatOffset[2] = (position.z - cameraOffset.z).toFloat()
|
||||||
|
|
||||||
val maxHeight = chunk.light.heightmap[inSectionPosition.xz]
|
|
||||||
if (position.y >= maxHeight) {
|
checkDown(state, fastBedrock, inSection, isLowestSection, neighbourBlocks, neighbours, light, section, chunk)
|
||||||
light[SELF_LIGHT_INDEX] = (light[SELF_LIGHT_INDEX].toInt() or 0xF0).toByte()
|
checkUp(isHighestSection, inSection, neighbourBlocks, neighbours, light, section, chunk)
|
||||||
|
|
||||||
|
setZ(neighbourBlocks, inChunk, neighbours, light, neighbourChunks, section, chunk)
|
||||||
|
setX(neighbourBlocks, inChunk, neighbours, light, neighbourChunks, section, chunk)
|
||||||
|
|
||||||
|
val maxHeight = chunk.light.heightmap[inSection.xz]
|
||||||
|
light[SELF_LIGHT_INDEX] = section.light[inSection]
|
||||||
|
if (position.y > maxHeight) {
|
||||||
|
light[O_UP] = (light[O_UP].toInt() or SKY_LIGHT_MASK).toByte()
|
||||||
|
}
|
||||||
|
if (position.y >= maxHeight) {
|
||||||
|
light[SELF_LIGHT_INDEX] = (light[SELF_LIGHT_INDEX].toInt() or SKY_LIGHT_MASK).toByte()
|
||||||
|
}
|
||||||
|
if (position.y - 1 >= maxHeight) {
|
||||||
|
light[O_DOWN] = (light[O_DOWN].toInt() or SKY_LIGHT_MASK).toByte()
|
||||||
}
|
}
|
||||||
|
|
||||||
checkDown(state, fastBedrock, inSectionPosition, isLowestSection, neighbourBlocks, neighbours, light, section, chunk)
|
|
||||||
checkUp(isHighestSection, inSectionPosition, neighbourBlocks, neighbours, light, section, chunk)
|
|
||||||
|
|
||||||
setZ(neighbourBlocks, inSectionPosition, neighbours, light, neighbourChunks, section, chunk)
|
|
||||||
setX(neighbourBlocks, inSectionPosition, neighbours, light, neighbourChunks, section, chunk)
|
|
||||||
|
|
||||||
// TODO: cull neighbours
|
// TODO: cull neighbours
|
||||||
|
|
||||||
if (position.y - 1 >= maxHeight) {
|
|
||||||
light[O_UP] = (light[O_UP].toInt() or 0xF0).toByte()
|
|
||||||
light[O_DOWN] = (light[O_DOWN].toInt() or 0xF0).toByte()
|
|
||||||
} else if (position.y + 1 >= maxHeight) {
|
|
||||||
light[O_UP] = (light[O_UP].toInt() or 0xF0).toByte()
|
|
||||||
}
|
|
||||||
|
|
||||||
var offset: Vec3? = null
|
|
||||||
if (state.block is OffsetBlock) {
|
if (state.block is OffsetBlock) {
|
||||||
offset = state.block.offsetModel(position)
|
val randomOffset = state.block.offsetModel(position)
|
||||||
floatOffset[0] += offset.x
|
floatOffset[0] += randomOffset.x
|
||||||
floatOffset[1] += offset.y
|
floatOffset[1] += randomOffset.y
|
||||||
floatOffset[2] += offset.z
|
floatOffset[2] += randomOffset.z
|
||||||
}
|
}
|
||||||
|
|
||||||
ao?.clear()
|
ao?.clear()
|
||||||
@ -148,12 +138,6 @@ class SolidSectionMesher(
|
|||||||
|
|
||||||
renderedBlockEntity?.getRenderer(context, state, position, light[SELF_LIGHT_INDEX].toInt())?.let { rendered = true; entities += it }
|
renderedBlockEntity?.getRenderer(context, state, position, light[SELF_LIGHT_INDEX].toInt())?.let { rendered = true; entities += it }
|
||||||
|
|
||||||
if (offset != null) {
|
|
||||||
floatOffset[0] -= offset.x
|
|
||||||
floatOffset[1] -= offset.y
|
|
||||||
// z is automatically reset
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rendered) {
|
if (rendered) {
|
||||||
mesh.addBlock(x, y, z)
|
mesh.addBlock(x, y, z)
|
||||||
}
|
}
|
||||||
@ -188,7 +172,7 @@ class SolidSectionMesher(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun setZ(neighbourBlocks: Array<BlockState?>, position: InSectionPosition, neighbours: Array<ChunkSection?>, light: ByteArray, neighbourChunks: ChunkNeighbourArray, section: ChunkSection, chunk: Chunk) {
|
private inline fun setZ(neighbourBlocks: Array<BlockState?>, position: InChunkPosition, neighbours: Array<ChunkSection?>, light: ByteArray, neighbourChunks: ChunkNeighbourArray, section: ChunkSection, chunk: Chunk) {
|
||||||
if (position.z == 0) {
|
if (position.z == 0) {
|
||||||
setNeighbour(neighbourBlocks, position.with(z = ProtocolDefinition.SECTION_MAX_Z), light, neighbours[O_NORTH], neighbourChunks[Directions.NORTH], O_NORTH)
|
setNeighbour(neighbourBlocks, position.with(z = ProtocolDefinition.SECTION_MAX_Z), light, neighbours[O_NORTH], neighbourChunks[Directions.NORTH], O_NORTH)
|
||||||
setNeighbour(neighbourBlocks, position.plusZ(), light, section, chunk, O_SOUTH)
|
setNeighbour(neighbourBlocks, position.plusZ(), light, section, chunk, O_SOUTH)
|
||||||
@ -202,7 +186,7 @@ class SolidSectionMesher(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private inline fun setX(neighbourBlocks: Array<BlockState?>, position: InSectionPosition, neighbours: Array<ChunkSection?>, light: ByteArray, neighbourChunks: ChunkNeighbourArray, section: ChunkSection, chunk: Chunk) {
|
private inline fun setX(neighbourBlocks: Array<BlockState?>, position: InChunkPosition, neighbours: Array<ChunkSection?>, light: ByteArray, neighbourChunks: ChunkNeighbourArray, section: ChunkSection, chunk: Chunk) {
|
||||||
if (position.x == 0) {
|
if (position.x == 0) {
|
||||||
setNeighbour(neighbourBlocks, position.with(x = ProtocolDefinition.SECTION_MAX_X), light, neighbours[O_WEST], neighbourChunks[Directions.WEST], O_WEST)
|
setNeighbour(neighbourBlocks, position.with(x = ProtocolDefinition.SECTION_MAX_X), light, neighbours[O_WEST], neighbourChunks[Directions.WEST], O_WEST)
|
||||||
setNeighbour(neighbourBlocks, position.plusX(), light, section, chunk, O_EAST)
|
setNeighbour(neighbourBlocks, position.plusX(), light, section, chunk, O_EAST)
|
||||||
@ -215,11 +199,12 @@ class SolidSectionMesher(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun setNeighbour(blocks: Array<BlockState?>, position: InSectionPosition, light: ByteArray, section: ChunkSection?, chunk: Chunk?, direction: Int) {
|
private inline fun setNeighbour(blocks: Array<BlockState?>, position: InChunkPosition, light: ByteArray, section: ChunkSection?, chunk: Chunk?, direction: Int) {
|
||||||
blocks[direction] = section?.blocks?.let { it[position] }
|
val inSection = position.inSectionPosition
|
||||||
var level = section?.light?.get(position) ?: 0x00
|
blocks[direction] = section?.blocks?.let { it[inSection] }
|
||||||
|
var level = section?.light?.get(inSection) ?: 0x00
|
||||||
if (chunk != null && position.y >= chunk.light.heightmap[position.xz]) {
|
if (chunk != null && position.y >= chunk.light.heightmap[position.xz]) {
|
||||||
level = (level.toInt() or SectionLight.SKY_LIGHT_MASK).toByte() // set sky light to 0x0F
|
level = (level.toInt() or SKY_LIGHT_MASK).toByte() // set sky light to 0x0F
|
||||||
}
|
}
|
||||||
light[direction] = level
|
light[direction] = level
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user