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
get() = isSneaking // ToDo: Or should leave swimming pose
override val hasCollisions: Boolean
get() = gamemode != Gamemodes.SPECTATOR
var isUsingItem = false
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<MassBlockSetEvent> {
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 sectionHeights: MutableSet<Int> = mutableSetOf()
for (blockPosition in it.blocks.keys) {
sectionHeights += blockPosition.sectionHeight
}
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) })
@ -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
* 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
}
val neighbourPositions = getChunkNeighbourPositions(chunkPosition)
val neighbours = getChunkNeighbours(neighbourPositions)
var neighboursLoaded = true
for (neighbour in neighbours) {
if (neighbour?.isFullyLoaded != true) {
neighboursLoaded = false
}
}
val neighbourChunks = getChunkNeighbours(neighbourPositions)
if (checkQueue) {
for ((index, neighbourPosition) in neighbourPositions.withIndex()) {
if (neighbourPosition !in incomplete) {
continue
}
val neighbourChunk = neighbours[index] ?: continue
val neighbourChunk = neighbourChunks[index] ?: continue
updateChunk(neighbourPosition, neighbourChunk, false)
}
}
if (!neighboursLoaded) {
if (!neighbourChunks.fullyLoaded) {
incomplete += chunkPosition
return
}
@ -219,18 +229,18 @@ class WorldRenderer(
val meshes = this.meshes.getOrPut(chunkPosition) { synchronizedMapOf() }
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) {
updateSectionSync(chunkPosition, sectionHeight, chunk, meshes)
updateSectionSync(chunkPosition, sectionHeight, chunk, neighbourChunks, meshes)
}
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) {
// chunk not loaded and/or neighbours also not fully loaded
return
@ -257,7 +267,7 @@ class WorldRenderer(
queue.remove(chunkPosition)
}
}
val neighbours = getSectionNeighbours(getChunkNeighbours(getChunkNeighbourPositions(chunkPosition)).unsafeCast(), chunk, sectionHeight)
val neighbours = getSectionNeighbours(neighbourChunks, chunk, sectionHeight)
prepareSection(chunkPosition, sectionHeight, section, neighbours, meshes)
} else {
queue.getOrPut(chunkPosition) { synchronizedSetOf() } += sectionHeight
@ -343,9 +353,10 @@ class WorldRenderer(
this.queue.remove(chunkPosition)
continue
}
val neighbours = getChunkNeighbours(getChunkNeighbourPositions(chunkPosition))
val meshes = this.meshes.getOrPut(chunkPosition) { synchronizedMapOf() }
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)]
}
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 {
blocks[ChunkSection.getIndex(x, y, z + 1)]
}
@ -62,7 +62,7 @@ class CullSectionPreparer(
blocks[ChunkSection.getIndex(x - 1, y, z)]
}
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 {
blocks[ChunkSection.getIndex(x + 1, y, z)]
}

View File

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

View File

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