fix spectator collisions, fix some mass block changing bugs, fix culling bugs

This commit is contained in:
Bixilon 2021-11-13 17:22:25 +01:00
parent 4db63f37f5
commit dcb058c960
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
5 changed files with 34 additions and 21 deletions

View File

@ -122,6 +122,9 @@ class LocalPlayerEntity(
private val slowMovement: Boolean private val slowMovement: Boolean
get() = isSneaking // ToDo: Or should leave swimming pose get() = isSneaking // ToDo: Or should leave swimming pose
override val hasCollisions: Boolean
get() = gamemode != Gamemodes.SPECTATOR
var isUsingItem = false var isUsingItem = false
override var activeHand: Hands? = null override var activeHand: Hands? = null

View File

@ -108,13 +108,20 @@ class WorldRenderer(
connection.registerEvent(CallbackEventInvoker.of<BlockSetEvent> { updateSection(it.blockPosition.chunkPosition, it.blockPosition.sectionHeight) }) connection.registerEvent(CallbackEventInvoker.of<BlockSetEvent> { updateSection(it.blockPosition.chunkPosition, it.blockPosition.sectionHeight) })
connection.registerEvent(CallbackEventInvoker.of<MassBlockSetEvent> { connection.registerEvent(CallbackEventInvoker.of<MassBlockSetEvent> {
val chunk = world[it.chunkPosition] ?: return@of val chunk = world[it.chunkPosition] ?: return@of
if (!chunk.isFullyLoaded || it.chunkPosition in incomplete) {
return@of
}
val neighbourChunks = getChunkNeighbours(getChunkNeighbourPositions(it.chunkPosition))
if (!neighbourChunks.fullyLoaded) {
return@of
}
val meshes = meshes.getOrPut(it.chunkPosition) { synchronizedMapOf() } val meshes = meshes.getOrPut(it.chunkPosition) { synchronizedMapOf() }
val sectionHeights: MutableSet<Int> = mutableSetOf() val sectionHeights: MutableSet<Int> = mutableSetOf()
for (blockPosition in it.blocks.keys) { for (blockPosition in it.blocks.keys) {
sectionHeights += blockPosition.sectionHeight sectionHeights += blockPosition.sectionHeight
} }
for (sectionHeight in sectionHeights) { for (sectionHeight in sectionHeights) {
updateSection(it.chunkPosition, sectionHeight, chunk, meshes) updateSection(it.chunkPosition, sectionHeight, chunk, neighbourChunks.unsafeCast(), meshes)
} }
}) })
connection.registerEvent(CallbackEventInvoker.of<ChunkUnloadEvent> { unloadChunk(it.chunkPosition) }) connection.registerEvent(CallbackEventInvoker.of<ChunkUnloadEvent> { unloadChunk(it.chunkPosition) })
@ -183,6 +190,16 @@ class WorldRenderer(
) )
} }
private val Array<Chunk?>.fullyLoaded: Boolean
get() {
for (neighbour in this) {
if (neighbour?.isFullyLoaded != true) {
return false
}
}
return true
}
/** /**
* Called when chunk data changes * Called when chunk data changes
* Checks if the chunk is visible and if so, updates the mesh. If not visible, unloads the current mesh and queues it for loading * Checks if the chunk is visible and if so, updates the mesh. If not visible, unloads the current mesh and queues it for loading
@ -192,26 +209,19 @@ class WorldRenderer(
return return
} }
val neighbourPositions = getChunkNeighbourPositions(chunkPosition) val neighbourPositions = getChunkNeighbourPositions(chunkPosition)
val neighbours = getChunkNeighbours(neighbourPositions) val neighbourChunks = getChunkNeighbours(neighbourPositions)
var neighboursLoaded = true
for (neighbour in neighbours) {
if (neighbour?.isFullyLoaded != true) {
neighboursLoaded = false
}
}
if (checkQueue) { if (checkQueue) {
for ((index, neighbourPosition) in neighbourPositions.withIndex()) { for ((index, neighbourPosition) in neighbourPositions.withIndex()) {
if (neighbourPosition !in incomplete) { if (neighbourPosition !in incomplete) {
continue continue
} }
val neighbourChunk = neighbours[index] ?: continue val neighbourChunk = neighbourChunks[index] ?: continue
updateChunk(neighbourPosition, neighbourChunk, false) updateChunk(neighbourPosition, neighbourChunk, false)
} }
} }
if (!neighboursLoaded) { if (!neighbourChunks.fullyLoaded) {
incomplete += chunkPosition incomplete += chunkPosition
return return
} }
@ -219,18 +229,18 @@ class WorldRenderer(
val meshes = this.meshes.getOrPut(chunkPosition) { synchronizedMapOf() } val meshes = this.meshes.getOrPut(chunkPosition) { synchronizedMapOf() }
for ((sectionHeight, section) in chunk.sections!!) { for ((sectionHeight, section) in chunk.sections!!) {
updateSection(chunkPosition, sectionHeight, chunk, meshes) updateSection(chunkPosition, sectionHeight, chunk, neighbourChunks.unsafeCast(), meshes)
} }
} }
private fun updateSection(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk = world[chunkPosition]!!, meshes: SynchronizedMap<Int, ChunkSectionMeshes> = this.meshes.getOrPut(chunkPosition) { synchronizedMapOf() }) { private fun updateSection(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk = world[chunkPosition]!!, neighbourChunks: Array<Chunk> = getChunkNeighbours(getChunkNeighbourPositions(chunkPosition)).unsafeCast(), meshes: SynchronizedMap<Int, ChunkSectionMeshes> = this.meshes.getOrPut(chunkPosition) { synchronizedMapOf() }) {
val task = ThreadPoolRunnable(priority = LOW) { val task = ThreadPoolRunnable(priority = LOW) {
updateSectionSync(chunkPosition, sectionHeight, chunk, meshes) updateSectionSync(chunkPosition, sectionHeight, chunk, neighbourChunks, meshes)
} }
DefaultThreadPool += task DefaultThreadPool += task
} }
private fun updateSectionSync(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk, meshes: SynchronizedMap<Int, ChunkSectionMeshes>) { private fun updateSectionSync(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk, neighbourChunks: Array<Chunk>, meshes: SynchronizedMap<Int, ChunkSectionMeshes>) {
if (!chunk.isFullyLoaded || chunkPosition in incomplete) { if (!chunk.isFullyLoaded || chunkPosition in incomplete) {
// chunk not loaded and/or neighbours also not fully loaded // chunk not loaded and/or neighbours also not fully loaded
return return
@ -257,7 +267,7 @@ class WorldRenderer(
queue.remove(chunkPosition) queue.remove(chunkPosition)
} }
} }
val neighbours = getSectionNeighbours(getChunkNeighbours(getChunkNeighbourPositions(chunkPosition)).unsafeCast(), chunk, sectionHeight) val neighbours = getSectionNeighbours(neighbourChunks, chunk, sectionHeight)
prepareSection(chunkPosition, sectionHeight, section, neighbours, meshes) prepareSection(chunkPosition, sectionHeight, section, neighbours, meshes)
} else { } else {
queue.getOrPut(chunkPosition) { synchronizedSetOf() } += sectionHeight queue.getOrPut(chunkPosition) { synchronizedSetOf() } += sectionHeight
@ -343,9 +353,10 @@ class WorldRenderer(
this.queue.remove(chunkPosition) this.queue.remove(chunkPosition)
continue continue
} }
val neighbours = getChunkNeighbours(getChunkNeighbourPositions(chunkPosition))
val meshes = this.meshes.getOrPut(chunkPosition) { synchronizedMapOf() } val meshes = this.meshes.getOrPut(chunkPosition) { synchronizedMapOf() }
for (sectionHeight in sectionHeights) { for (sectionHeight in sectionHeights) {
updateSection(chunkPosition, sectionHeight, chunk, meshes) updateSection(chunkPosition, sectionHeight, chunk, neighbours.unsafeCast(), meshes)
} }
} }

View File

@ -51,7 +51,7 @@ class CullSectionPreparer(
blocks[ChunkSection.getIndex(x, y, z - 1)] blocks[ChunkSection.getIndex(x, y, z - 1)]
} }
neighbourBlocks[Directions.SOUTH.ordinal] = if (z == ProtocolDefinition.SECTION_MAX_Z) { neighbourBlocks[Directions.SOUTH.ordinal] = if (z == ProtocolDefinition.SECTION_MAX_Z) {
neighbours[Directions.NORTH.ordinal]?.blocks?.get(ChunkSection.getIndex(x, y, 0)) neighbours[Directions.SOUTH.ordinal]?.blocks?.get(ChunkSection.getIndex(x, y, 0))
} else { } else {
blocks[ChunkSection.getIndex(x, y, z + 1)] blocks[ChunkSection.getIndex(x, y, z + 1)]
} }
@ -62,7 +62,7 @@ class CullSectionPreparer(
blocks[ChunkSection.getIndex(x - 1, y, z)] blocks[ChunkSection.getIndex(x - 1, y, z)]
} }
neighbourBlocks[Directions.EAST.ordinal] = if (x == ProtocolDefinition.SECTION_MAX_X) { neighbourBlocks[Directions.EAST.ordinal] = if (x == ProtocolDefinition.SECTION_MAX_X) {
neighbours[Directions.WEST.ordinal]?.blocks?.get(ChunkSection.getIndex(0, y, z)) neighbours[Directions.EAST.ordinal]?.blocks?.get(ChunkSection.getIndex(0, y, z))
} else { } else {
blocks[ChunkSection.getIndex(x + 1, y, z)] blocks[ChunkSection.getIndex(x + 1, y, z)]
} }

View File

@ -59,7 +59,7 @@ class Camera(
val renderWindow: RenderWindow, val renderWindow: RenderWindow,
) { ) {
var fogColor = Previous(ChatColors.GREEN) var fogColor = Previous(ChatColors.GREEN)
var fogStart = 100.0f var fogStart = 1000.0f
private var mouseSensitivity = Minosoft.config.config.game.controls.moseSensitivity private var mouseSensitivity = Minosoft.config.config.game.controls.moseSensitivity
@Deprecated("", ReplaceWith("connection.player")) @Deprecated("", ReplaceWith("connection.player"))

View File

@ -147,7 +147,6 @@ class JoinGameS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
} }
override fun handle(connection: PlayConnection) { override fun handle(connection: PlayConnection) {
val gamemode = Gamemodes.SPECTATOR
val playerEntity = connection.player val playerEntity = connection.player
val previousGamemode = playerEntity.tabListItem.gamemode val previousGamemode = playerEntity.tabListItem.gamemode