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:
- Build biome cache only in render distance
- Update neighbour chunks if needed
- Reduce memory usage
- Unload on minimize
- 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.protocol.network.connection.play.PlayConnection
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.MMath
import de.bixilon.minosoft.util.ReadWriteLock
import de.bixilon.minosoft.util.chunk.ChunkUtil.canBuildBiomeCache
import de.bixilon.minosoft.util.chunk.ChunkUtil.getChunkNeighbourPositions
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_.vec2.Vec2i
import glm_.vec3.Vec3
@ -59,8 +60,9 @@ import kotlin.random.Random
class World(
val connection: PlayConnection,
) : BiomeAccessor {
val lock = ReadWriteLock()
var cacheBiomeAccessor: NoiseBiomeAccessor? = null
val chunks: SynchronizedMap<Vec2i, Chunk> = synchronizedMapOf()
val chunks: LockMap<Vec2i, Chunk> = lockMapOf()
val entities = WorldEntities()
var hardcore = false
var dimension: DimensionProperties? = null

View File

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

View File

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

View File

@ -13,6 +13,9 @@
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.Resources
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.Renderer
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.ChunkSectionMeshes
import de.bixilon.minosoft.gui.rendering.block.preparer.AbstractSectionPreparer
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.RenderingStateChangeEvent
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.phases.OpaqueDrawable
@ -222,6 +227,31 @@ class WorldRenderer(
connection.registerEvent(CallbackEventInvoker.of<ChunkUnloadEvent> { unloadChunk(it.chunkPosition) })
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() {
@ -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) {
if (chunk == null || section == null) {
if (chunk == null || section == null || renderWindow.renderingState == RenderingStates.PAUSED) {
return
}
val queued = internalQueueSection(chunkPosition, sectionHeight, chunk, section, ignoreFrustum)
@ -414,7 +444,7 @@ class WorldRenderer(
}
private fun queueChunk(chunkPosition: Vec2i, chunk: Chunk = world.chunks[chunkPosition]!!) {
if (!chunk.isFullyLoaded) {
if (!chunk.isFullyLoaded || renderWindow.renderingState == RenderingStates.PAUSED) {
return
}

View File

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

View File

@ -25,10 +25,10 @@ abstract class TextureParticle(connection: PlayConnection, position: Vec3d, velo
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
when {
texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> translucentMesh
texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> particleMesh
else -> transparentMesh
}.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> {
return SynchronizedMap(mutableMapOf(*pairs))
}