clear chunk cache on minimize, rotate cull face correct, chunk clear key combination

This commit is contained in:
Bixilon 2021-11-17 22:36:33 +01:00
parent fc2b5a8502
commit 4720dbba37
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
8 changed files with 50 additions and 12 deletions

View File

@ -45,6 +45,5 @@
- ToDo: - ToDo:
- Build biome cache only in render distance - Build biome cache only in render distance
- Update neighbour chunks if needed - Update neighbour chunks if needed
- Reduce memory usage
- Unload on minimize - Unload on minimize
- Biomes: Check if chunk is single biome - Biomes: Check if chunk is single biome

View File

@ -37,13 +37,14 @@ import de.bixilon.minosoft.modding.event.events.ChunkDataChangeEvent
import de.bixilon.minosoft.modding.event.events.ChunkUnloadEvent import de.bixilon.minosoft.modding.event.events.ChunkUnloadEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.KUtil.synchronizedMapOf import de.bixilon.minosoft.util.KUtil.lockMapOf
import de.bixilon.minosoft.util.KUtil.toSynchronizedMap import de.bixilon.minosoft.util.KUtil.toSynchronizedMap
import de.bixilon.minosoft.util.MMath import de.bixilon.minosoft.util.MMath
import de.bixilon.minosoft.util.ReadWriteLock
import de.bixilon.minosoft.util.chunk.ChunkUtil.canBuildBiomeCache import de.bixilon.minosoft.util.chunk.ChunkUtil.canBuildBiomeCache
import de.bixilon.minosoft.util.chunk.ChunkUtil.getChunkNeighbourPositions import de.bixilon.minosoft.util.chunk.ChunkUtil.getChunkNeighbourPositions
import de.bixilon.minosoft.util.chunk.ChunkUtil.received import de.bixilon.minosoft.util.chunk.ChunkUtil.received
import de.bixilon.minosoft.util.collections.SynchronizedMap import de.bixilon.minosoft.util.collections.LockMap
import glm_.func.common.clamp import glm_.func.common.clamp
import glm_.vec2.Vec2i import glm_.vec2.Vec2i
import glm_.vec3.Vec3 import glm_.vec3.Vec3
@ -59,8 +60,9 @@ import kotlin.random.Random
class World( class World(
val connection: PlayConnection, val connection: PlayConnection,
) : BiomeAccessor { ) : BiomeAccessor {
val lock = ReadWriteLock()
var cacheBiomeAccessor: NoiseBiomeAccessor? = null var cacheBiomeAccessor: NoiseBiomeAccessor? = null
val chunks: SynchronizedMap<Vec2i, Chunk> = synchronizedMapOf() val chunks: LockMap<Vec2i, Chunk> = lockMapOf()
val entities = WorldEntities() val entities = WorldEntities()
var hardcore = false var hardcore = false
var dimension: DimensionProperties? = null var dimension: DimensionProperties? = null

View File

@ -23,7 +23,7 @@ class RegistrySectionDataProvider<T>(
) : SectionDataProvider<T>(data, checkSize = checkSize) { ) : SectionDataProvider<T>(data, checkSize = checkSize) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
fun setIdData(ids: Array<Int>) { fun setIdData(ids: IntArray) {
val data: Array<Any?> = arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION) val data: Array<Any?> = arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION)
for ((index, id) in ids.withIndex()) { for ((index, id) in ids.withIndex()) {

View File

@ -83,8 +83,8 @@ class RenderWindow(
private var lastFrame = 0.0 private var lastFrame = 0.0
private val latch = CountUpAndDownLatch(1) private val latch = CountUpAndDownLatch(1)
private var renderingState = RenderingStates.RUNNING var renderingState = RenderingStates.RUNNING
set(value) { private set(value) {
if (field == value) { if (field == value) {
return return
} }

View File

@ -13,6 +13,9 @@
package de.bixilon.minosoft.gui.rendering.block package de.bixilon.minosoft.gui.rendering.block
import de.bixilon.minosoft.config.key.KeyAction
import de.bixilon.minosoft.config.key.KeyBinding
import de.bixilon.minosoft.config.key.KeyCodes
import de.bixilon.minosoft.data.assets.AssetsUtil import de.bixilon.minosoft.data.assets.AssetsUtil
import de.bixilon.minosoft.data.assets.Resources import de.bixilon.minosoft.data.assets.Resources
import de.bixilon.minosoft.data.direction.Directions import de.bixilon.minosoft.data.direction.Directions
@ -23,11 +26,13 @@ import de.bixilon.minosoft.data.world.World
import de.bixilon.minosoft.gui.rendering.RenderWindow import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.Renderer import de.bixilon.minosoft.gui.rendering.Renderer
import de.bixilon.minosoft.gui.rendering.RendererBuilder import de.bixilon.minosoft.gui.rendering.RendererBuilder
import de.bixilon.minosoft.gui.rendering.RenderingStates
import de.bixilon.minosoft.gui.rendering.block.mesh.ChunkSectionMesh import de.bixilon.minosoft.gui.rendering.block.mesh.ChunkSectionMesh
import de.bixilon.minosoft.gui.rendering.block.mesh.ChunkSectionMeshes import de.bixilon.minosoft.gui.rendering.block.mesh.ChunkSectionMeshes
import de.bixilon.minosoft.gui.rendering.block.preparer.AbstractSectionPreparer import de.bixilon.minosoft.gui.rendering.block.preparer.AbstractSectionPreparer
import de.bixilon.minosoft.gui.rendering.block.preparer.CullSectionPreparer import de.bixilon.minosoft.gui.rendering.block.preparer.CullSectionPreparer
import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent
import de.bixilon.minosoft.gui.rendering.modding.events.RenderingStateChangeEvent
import de.bixilon.minosoft.gui.rendering.models.ModelLoader import de.bixilon.minosoft.gui.rendering.models.ModelLoader
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
import de.bixilon.minosoft.gui.rendering.system.base.phases.OpaqueDrawable import de.bixilon.minosoft.gui.rendering.system.base.phases.OpaqueDrawable
@ -222,6 +227,31 @@ class WorldRenderer(
connection.registerEvent(CallbackEventInvoker.of<ChunkUnloadEvent> { unloadChunk(it.chunkPosition) }) connection.registerEvent(CallbackEventInvoker.of<ChunkUnloadEvent> { unloadChunk(it.chunkPosition) })
connection.registerEvent(CallbackEventInvoker.of<PlayConnectionStateChangeEvent> { if (it.state == PlayConnectionStates.DISCONNECTED) unloadWorld() }) connection.registerEvent(CallbackEventInvoker.of<PlayConnectionStateChangeEvent> { if (it.state == PlayConnectionStates.DISCONNECTED) unloadWorld() })
connection.registerEvent(CallbackEventInvoker.of<RenderingStateChangeEvent> {
if (it.state == RenderingStates.PAUSED) {
unloadWorld()
} else if (it.previousState == RenderingStates.PAUSED) {
prepareWorld()
}
})
renderWindow.inputHandler.registerKeyCallback("minosoft:clear_chunk_cache".toResourceLocation(), KeyBinding(
mutableMapOf(
KeyAction.MODIFIER to mutableSetOf(KeyCodes.KEY_F3),
KeyAction.PRESS to mutableSetOf(KeyCodes.KEY_A),
),
)) {
unloadWorld()
prepareWorld()
}
}
private fun prepareWorld() {
world.lock.acquire()
for ((chunkPosition, chunk) in world.chunks) {
queueChunk(chunkPosition, chunk)
}
world.lock.release()
} }
private fun unloadWorld() { private fun unloadWorld() {
@ -402,7 +432,7 @@ class WorldRenderer(
} }
private fun queueSection(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk? = world.chunks[chunkPosition], section: ChunkSection? = chunk?.get(sectionHeight), ignoreFrustum: Boolean = false) { private fun queueSection(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk? = world.chunks[chunkPosition], section: ChunkSection? = chunk?.get(sectionHeight), ignoreFrustum: Boolean = false) {
if (chunk == null || section == null) { if (chunk == null || section == null || renderWindow.renderingState == RenderingStates.PAUSED) {
return return
} }
val queued = internalQueueSection(chunkPosition, sectionHeight, chunk, section, ignoreFrustum) val queued = internalQueueSection(chunkPosition, sectionHeight, chunk, section, ignoreFrustum)
@ -414,7 +444,7 @@ class WorldRenderer(
} }
private fun queueChunk(chunkPosition: Vec2i, chunk: Chunk = world.chunks[chunkPosition]!!) { private fun queueChunk(chunkPosition: Vec2i, chunk: Chunk = world.chunks[chunkPosition]!!) {
if (!chunk.isFullyLoaded) { if (!chunk.isFullyLoaded || renderWindow.renderingState == RenderingStates.PAUSED) {
return return
} }

View File

@ -99,10 +99,13 @@ data class UnbakedBlockStateModel(
} }
var direction = face.direction var direction = face.direction
var cullFace = face.cullFace
rotation?.let { rotation?.let {
val rad = it.rad val rad = it.rad
direction = Directions.byDirection(Vec3(face.direction.vectorf).apply { rotateAssign(rad) }) direction = Directions.byDirection(Vec3(face.direction.vectorf).apply { rotateAssign(rad) })
cullFace = face.cullFace?.vectorf?.let { cullFace -> Directions.byDirection(Vec3(cullFace).apply { rotateAssign(rad) }) }
for ((index, position) in positions.withIndex()) { for ((index, position) in positions.withIndex()) {
positions[index] = Vec3(position).apply { rotateAssign(rad, true) } positions[index] = Vec3(position).apply { rotateAssign(rad, true) }
} }
@ -147,7 +150,7 @@ data class UnbakedBlockStateModel(
uv = texturePositions, uv = texturePositions,
shade = shade, shade = shade,
tintIndex = face.tintIndex, tintIndex = face.tintIndex,
cullFace = face.cullFace, cullFace = cullFace,
texture = texture, texture = texture,
touching = touching, touching = touching,
) )

View File

@ -25,10 +25,10 @@ abstract class TextureParticle(connection: PlayConnection, position: Vec3d, velo
abstract val texture: AbstractTexture? abstract val texture: AbstractTexture?
override fun addVertex(transparentMesh: ParticleMesh, translucentMesh: ParticleMesh, time:Long) { override fun addVertex(transparentMesh: ParticleMesh, particleMesh: ParticleMesh, time: Long) {
val texture = texture ?: return val texture = texture ?: return
when { when {
texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> translucentMesh texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> particleMesh
else -> transparentMesh else -> transparentMesh
}.addVertex(getCameraPosition(time), scale, texture, color) }.addVertex(getCameraPosition(time), scale, texture, color)
} }

View File

@ -85,6 +85,10 @@ object KUtil {
} }
} }
fun <K, V> lockMapOf(vararg pairs: Pair<K, V>): LockMap<K, V> {
return LockMap(mutableMapOf(*pairs))
}
fun <K, V> synchronizedMapOf(vararg pairs: Pair<K, V>): SynchronizedMap<K, V> { fun <K, V> synchronizedMapOf(vararg pairs: Pair<K, V>): SynchronizedMap<K, V> {
return SynchronizedMap(mutableMapOf(*pairs)) return SynchronizedMap(mutableMapOf(*pairs))
} }