From 20ca5c1199056e82b2623afb214cc06f9504f600 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Sat, 13 Nov 2021 23:41:29 +0100 Subject: [PATCH] render distance, remove particles when out of render distance --- .../minosoft/config/config/game/CameraGameConfig.kt | 2 +- .../minosoft/gui/rendering/block/WorldRenderer.kt | 9 +++++++++ .../minosoft/gui/rendering/input/camera/Camera.kt | 7 +++---- .../minosoft/gui/rendering/models/ModelLoader.kt | 2 ++ .../models/baked/block/BakedBlockStateModel.kt | 12 +++++++++--- .../gui/rendering/particle/ParticleRenderer.kt | 12 ++++++++++++ .../gui/rendering/particle/types/Particle.kt | 4 ++-- .../gui/rendering/util/vec/vec2/Vec2iUtil.kt | 3 +++ .../protocol/packets/c2s/play/ClientSettingsC2SP.kt | 6 +++--- .../protocol/packets/s2c/play/JoinGameS2CP.kt | 3 ++- 10 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/config/config/game/CameraGameConfig.kt b/src/main/java/de/bixilon/minosoft/config/config/game/CameraGameConfig.kt index fdd48bbce..ec954b2cd 100644 --- a/src/main/java/de/bixilon/minosoft/config/config/game/CameraGameConfig.kt +++ b/src/main/java/de/bixilon/minosoft/config/config/game/CameraGameConfig.kt @@ -16,7 +16,7 @@ package de.bixilon.minosoft.config.config.game import com.squareup.moshi.Json data class CameraGameConfig( - @Json(name = "render_distance") var renderDistance: Int = 10, + @Json(name = "view_distance") var viewDistance: Int = 10, var fov: Double = 60.0, @Json(name = "dynamic_fov") var dynamicFov: Boolean = true, @Json(name = "no_clip_movement") var noCipMovement: Boolean = false, diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt index 5240da12b..f6328bf20 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt @@ -13,6 +13,7 @@ package de.bixilon.minosoft.gui.rendering.block +import de.bixilon.minosoft.Minosoft import de.bixilon.minosoft.data.assets.AssetsUtil import de.bixilon.minosoft.data.assets.Resources import de.bixilon.minosoft.data.registries.ResourceLocation @@ -34,6 +35,7 @@ import de.bixilon.minosoft.gui.rendering.system.base.phases.TranslucentDrawable import de.bixilon.minosoft.gui.rendering.system.base.phases.TransparentDrawable import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight +import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.abs import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.EMPTY import de.bixilon.minosoft.modding.event.events.* import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker @@ -377,6 +379,13 @@ class WorldRenderer( } private fun isChunkVisible(chunkPosition: Vec2i, sectionHeight: Int, minPosition: Vec3i, maxPosition: Vec3i): Boolean { + val viewDistance = Minosoft.config.config.game.camera.viewDistance + val cameraChunkPosition = renderWindow.connection.player.positionInfo.chunkPosition + val delta = (chunkPosition - cameraChunkPosition).abs + + if (delta.x >= viewDistance || delta.y >= viewDistance) { + return false + } // ToDo: Cave culling, frustum clipping, improve performance return frustum.containsChunk(chunkPosition, sectionHeight, minPosition, maxPosition) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/input/camera/Camera.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/input/camera/Camera.kt index d3598260c..df0766a1a 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/input/camera/Camera.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/input/camera/Camera.kt @@ -59,7 +59,7 @@ class Camera( val renderWindow: RenderWindow, ) { var fogColor = Previous(ChatColors.GREEN) - var fogStart = 100.0f + var fogStart = Minosoft.config.config.game.camera.viewDistance * ProtocolDefinition.SECTION_WIDTH_X.toFloat() // ToDo private var mouseSensitivity = Minosoft.config.config.game.controls.moseSensitivity @Deprecated("", ReplaceWith("connection.player")) @@ -137,8 +137,7 @@ class Camera( fogStart = if (connection.player.submergedFluid?.resourceLocation == DefaultFluids.WATER) { 10.0f } else { - val renderDistance = 10 // ToDo: Calculate correct, get real render distance - (renderDistance * ProtocolDefinition.SECTION_WIDTH_X).toFloat() + Minosoft.config.config.game.camera.viewDistance * ProtocolDefinition.SECTION_WIDTH_X.toFloat() // ToDO } } @@ -304,7 +303,7 @@ class Camera( } private fun calculateProjectionMatrix(screenDimensions: Vec2): Mat4d { - return glm.perspective(fov.rad, screenDimensions.x.toDouble() / screenDimensions.y, 0.1, 1000.0) + return glm.perspective(fov.rad, screenDimensions.x.toDouble() / screenDimensions.y, 0.01, 10000.0) } private fun calculateViewMatrix(): Mat4d { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/ModelLoader.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/ModelLoader.kt index 1ee60adb3..ca26308a4 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/ModelLoader.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/ModelLoader.kt @@ -69,6 +69,8 @@ class ModelLoader( } private fun cleanup() { + unbakedBlockModels.clear() + unbakedBlockStateModels.clear() modelJsons.clear() blockStateJsons.clear() } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/BakedBlockStateModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/BakedBlockStateModel.kt index 6ab643b0a..3114cfa7e 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/BakedBlockStateModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/BakedBlockStateModel.kt @@ -20,6 +20,8 @@ import de.bixilon.minosoft.gui.rendering.block.mesh.ChunkSectionMesh import de.bixilon.minosoft.gui.rendering.block.mesh.ChunkSectionMeshes import de.bixilon.minosoft.gui.rendering.models.CullUtil.canCull import de.bixilon.minosoft.gui.rendering.models.FaceProperties +import de.bixilon.minosoft.gui.rendering.util.VecUtil +import de.bixilon.minosoft.gui.rendering.util.VecUtil.getWorldOffset import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.toVec3 import glm_.vec3.Vec3i import java.util.* @@ -36,7 +38,11 @@ class BakedBlockStateModel( } override fun singleRender(position: Vec3i, mesh: ChunkSectionMeshes, random: Random, blockState: BlockState, neighbours: Array, light: Int, ambientLight: FloatArray): Boolean { - val floatPosition = position.toVec3().array + val floatPosition = position.toVec3() + blockState.block.randomOffsetType?.let { + floatPosition += position.getWorldOffset(blockState.block) + } + val positionArray = floatPosition.array var rendered = false for ((index, faces) in faces.withIndex()) { val direction = Directions.VALUES[index] @@ -44,14 +50,14 @@ class BakedBlockStateModel( val neighboursModel = neighbour?.model var neighbourProperties: Array? = null if (neighboursModel != null) { - random.setSeed(0L) // ToDo + random.setSeed(VecUtil.generatePositionHash(position.x + direction.vector.x, position.y + direction.vector.y, position.z + direction.vector.z)) neighbourProperties = neighboursModel.getTouchingFaceProperties(random, direction.inverted) } for (face in faces) { if (face.touching && neighbourProperties != null && neighbourProperties.isNotEmpty() && neighbourProperties.canCull(face, blockState == neighbour)) { continue } - face.singleRender(floatPosition, mesh, light, ambientLight) + face.singleRender(positionArray, mesh, light, ambientLight) if (!rendered) { rendered = true } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt index c7aad869a..356640b72 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt @@ -13,6 +13,7 @@ package de.bixilon.minosoft.gui.rendering.particle +import de.bixilon.minosoft.Minosoft import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.gui.rendering.RenderConstants import de.bixilon.minosoft.gui.rendering.RenderWindow @@ -101,8 +102,12 @@ class ParticleRenderer( connection.world.particleRenderer = this particleTask = TimeWorker.addTask(TimeWorkerTask(ProtocolDefinition.TICK_TIME, maxDelayTime = ProtocolDefinition.TICK_TIME / 2) { + val cameraLength = connection.player.position.length() synchronized(particles) { for (particle in particles) { + if (particle.position.length() - cameraLength >= Minosoft.config.config.game.camera.viewDistance * ProtocolDefinition.SECTION_WIDTH_X) { + particle.dead = true + } particle.tryTick() } } @@ -122,6 +127,13 @@ class ParticleRenderer( Log.log(LogMessageType.RENDERING_GENERAL, LogLevels.WARN) { "Can not add particle: Limit reached (${particleCount} > ${RenderConstants.MAXIMUM_PARTICLE_AMOUNT}" } return } + val cameraLength = connection.player.position.length() + + if (particle.position.length() - cameraLength >= Minosoft.config.config.game.camera.viewDistance * ProtocolDefinition.SECTION_WIDTH_X) { + particle.dead = true + return + } + synchronized(particleQueue) { particleQueue += particle } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt index 0034d1529..660772790 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt @@ -135,12 +135,12 @@ abstract class Particle( } fun tryTick() { - val currentTime = System.currentTimeMillis() - if (dead) { return } + val currentTime = System.currentTimeMillis() + if (lastTickTime == -1L) { lastTickTime = System.currentTimeMillis() return diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/util/vec/vec2/Vec2iUtil.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/util/vec/vec2/Vec2iUtil.kt index 49936cebb..3e75aba4e 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/util/vec/vec2/Vec2iUtil.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/util/vec/vec2/Vec2iUtil.kt @@ -63,6 +63,9 @@ object Vec2iUtil { val Vec2i.rad: Vec2 get() = Vec2(x.rad, y.rad) + val Vec2i.abs: Vec2i + get() = Vec2i(kotlin.math.abs(x), kotlin.math.abs(y)) + operator fun Vec2i.get(axis: Axes): Int { return when (axis) { Axes.X -> x diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/c2s/play/ClientSettingsC2SP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/c2s/play/ClientSettingsC2SP.kt index 39308b558..e1aa696ce 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/c2s/play/ClientSettingsC2SP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/c2s/play/ClientSettingsC2SP.kt @@ -25,7 +25,7 @@ import de.bixilon.minosoft.util.logging.LogMessageType class ClientSettingsC2SP( val locale: String = "en_us", - val renderDistance: Int = 10, + val viewDistance: Int = 10, val chatMode: ChatModes = ChatModes.EVERYTHING, val skinParts: Set = setOf(*SkinParts.VALUES), val mainHand: Hands = Hands.MAIN, @@ -34,7 +34,7 @@ class ClientSettingsC2SP( override fun write(buffer: PlayOutByteBuffer) { buffer.writeString(locale) // locale - buffer.writeByte(renderDistance) // render Distance + buffer.writeByte(viewDistance) // render Distance buffer.writeByte(chatMode.ordinal) // chat settings buffer.writeBoolean(true) // chat colors if (buffer.versionId < ProtocolVersions.V_14W03B) { @@ -56,7 +56,7 @@ class ClientSettingsC2SP( } override fun log() { - Log.log(LogMessageType.NETWORK_PACKETS_OUT, LogLevels.VERBOSE) { "Client settings (locale=$locale, renderDistance=$renderDistance)" } + Log.log(LogMessageType.NETWORK_PACKETS_OUT, LogLevels.VERBOSE) { "Client settings (locale=$locale, renderDistance=$viewDistance)" } } enum class SkinParts { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/JoinGameS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/JoinGameS2CP.kt index c7990c92f..3a4e84d32 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/JoinGameS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/JoinGameS2CP.kt @@ -13,6 +13,7 @@ package de.bixilon.minosoft.protocol.packets.s2c.play import com.google.common.collect.HashBiMap +import de.bixilon.minosoft.Minosoft import de.bixilon.minosoft.data.Difficulties import de.bixilon.minosoft.data.abilities.Gamemodes import de.bixilon.minosoft.data.registries.DefaultRegistries @@ -168,7 +169,7 @@ class JoinGameS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() { NoiseBiomeAccessor(connection.world) } TimeWorker.addTask(TimeWorkerTask(150, true) { // ToDo: Temp workaround - connection.sendPacket(ClientSettingsC2SP()) + connection.sendPacket(ClientSettingsC2SP(viewDistance = Minosoft.config.config.game.camera.viewDistance)) val brandName = DefaultRegistries.DEFAULT_PLUGIN_CHANNELS_REGISTRY.forVersion(connection.version)[DefaultPluginChannels.BRAND]!!.resourceLocation val buffer = PlayOutByteBuffer(connection)