render distance, remove particles when out of render distance

This commit is contained in:
Bixilon 2021-11-13 23:41:29 +01:00
parent 168d607c47
commit 20ca5c1199
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
10 changed files with 46 additions and 14 deletions

View File

@ -16,7 +16,7 @@ package de.bixilon.minosoft.config.config.game
import com.squareup.moshi.Json import com.squareup.moshi.Json
data class CameraGameConfig( data class CameraGameConfig(
@Json(name = "render_distance") var renderDistance: Int = 10, @Json(name = "view_distance") var viewDistance: Int = 10,
var fov: Double = 60.0, var fov: Double = 60.0,
@Json(name = "dynamic_fov") var dynamicFov: Boolean = true, @Json(name = "dynamic_fov") var dynamicFov: Boolean = true,
@Json(name = "no_clip_movement") var noCipMovement: Boolean = false, @Json(name = "no_clip_movement") var noCipMovement: Boolean = false,

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.gui.rendering.block 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.AssetsUtil
import de.bixilon.minosoft.data.assets.Resources import de.bixilon.minosoft.data.assets.Resources
import de.bixilon.minosoft.data.registries.ResourceLocation 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.system.base.phases.TransparentDrawable
import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition 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.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.gui.rendering.util.vec.vec3.Vec3iUtil.EMPTY
import de.bixilon.minosoft.modding.event.events.* import de.bixilon.minosoft.modding.event.events.*
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker 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 { 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 // ToDo: Cave culling, frustum clipping, improve performance
return frustum.containsChunk(chunkPosition, sectionHeight, minPosition, maxPosition) return frustum.containsChunk(chunkPosition, sectionHeight, minPosition, maxPosition)
} }

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 = Minosoft.config.config.game.camera.viewDistance * ProtocolDefinition.SECTION_WIDTH_X.toFloat() // ToDo
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"))
@ -137,8 +137,7 @@ class Camera(
fogStart = if (connection.player.submergedFluid?.resourceLocation == DefaultFluids.WATER) { fogStart = if (connection.player.submergedFluid?.resourceLocation == DefaultFluids.WATER) {
10.0f 10.0f
} else { } else {
val renderDistance = 10 // ToDo: Calculate correct, get real render distance Minosoft.config.config.game.camera.viewDistance * ProtocolDefinition.SECTION_WIDTH_X.toFloat() // ToDO
(renderDistance * ProtocolDefinition.SECTION_WIDTH_X).toFloat()
} }
} }
@ -304,7 +303,7 @@ class Camera(
} }
private fun calculateProjectionMatrix(screenDimensions: Vec2): Mat4d { 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 { private fun calculateViewMatrix(): Mat4d {

View File

@ -69,6 +69,8 @@ class ModelLoader(
} }
private fun cleanup() { private fun cleanup() {
unbakedBlockModels.clear()
unbakedBlockStateModels.clear()
modelJsons.clear() modelJsons.clear()
blockStateJsons.clear() blockStateJsons.clear()
} }

View File

@ -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.block.mesh.ChunkSectionMeshes
import de.bixilon.minosoft.gui.rendering.models.CullUtil.canCull import de.bixilon.minosoft.gui.rendering.models.CullUtil.canCull
import de.bixilon.minosoft.gui.rendering.models.FaceProperties 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 de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.toVec3
import glm_.vec3.Vec3i import glm_.vec3.Vec3i
import java.util.* import java.util.*
@ -36,7 +38,11 @@ class BakedBlockStateModel(
} }
override fun singleRender(position: Vec3i, mesh: ChunkSectionMeshes, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, light: Int, ambientLight: FloatArray): Boolean { override fun singleRender(position: Vec3i, mesh: ChunkSectionMeshes, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, 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 var rendered = false
for ((index, faces) in faces.withIndex()) { for ((index, faces) in faces.withIndex()) {
val direction = Directions.VALUES[index] val direction = Directions.VALUES[index]
@ -44,14 +50,14 @@ class BakedBlockStateModel(
val neighboursModel = neighbour?.model val neighboursModel = neighbour?.model
var neighbourProperties: Array<FaceProperties>? = null var neighbourProperties: Array<FaceProperties>? = null
if (neighboursModel != 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) neighbourProperties = neighboursModel.getTouchingFaceProperties(random, direction.inverted)
} }
for (face in faces) { for (face in faces) {
if (face.touching && neighbourProperties != null && neighbourProperties.isNotEmpty() && neighbourProperties.canCull(face, blockState == neighbour)) { if (face.touching && neighbourProperties != null && neighbourProperties.isNotEmpty() && neighbourProperties.canCull(face, blockState == neighbour)) {
continue continue
} }
face.singleRender(floatPosition, mesh, light, ambientLight) face.singleRender(positionArray, mesh, light, ambientLight)
if (!rendered) { if (!rendered) {
rendered = true rendered = true
} }

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.gui.rendering.particle package de.bixilon.minosoft.gui.rendering.particle
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.gui.rendering.RenderConstants import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.RenderWindow import de.bixilon.minosoft.gui.rendering.RenderWindow
@ -101,8 +102,12 @@ class ParticleRenderer(
connection.world.particleRenderer = this connection.world.particleRenderer = this
particleTask = TimeWorker.addTask(TimeWorkerTask(ProtocolDefinition.TICK_TIME, maxDelayTime = ProtocolDefinition.TICK_TIME / 2) { particleTask = TimeWorker.addTask(TimeWorkerTask(ProtocolDefinition.TICK_TIME, maxDelayTime = ProtocolDefinition.TICK_TIME / 2) {
val cameraLength = connection.player.position.length()
synchronized(particles) { synchronized(particles) {
for (particle in 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() 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}" } Log.log(LogMessageType.RENDERING_GENERAL, LogLevels.WARN) { "Can not add particle: Limit reached (${particleCount} > ${RenderConstants.MAXIMUM_PARTICLE_AMOUNT}" }
return 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) { synchronized(particleQueue) {
particleQueue += particle particleQueue += particle
} }

View File

@ -135,12 +135,12 @@ abstract class Particle(
} }
fun tryTick() { fun tryTick() {
val currentTime = System.currentTimeMillis()
if (dead) { if (dead) {
return return
} }
val currentTime = System.currentTimeMillis()
if (lastTickTime == -1L) { if (lastTickTime == -1L) {
lastTickTime = System.currentTimeMillis() lastTickTime = System.currentTimeMillis()
return return

View File

@ -63,6 +63,9 @@ object Vec2iUtil {
val Vec2i.rad: Vec2 val Vec2i.rad: Vec2
get() = Vec2(x.rad, y.rad) 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 { operator fun Vec2i.get(axis: Axes): Int {
return when (axis) { return when (axis) {
Axes.X -> x Axes.X -> x

View File

@ -25,7 +25,7 @@ import de.bixilon.minosoft.util.logging.LogMessageType
class ClientSettingsC2SP( class ClientSettingsC2SP(
val locale: String = "en_us", val locale: String = "en_us",
val renderDistance: Int = 10, val viewDistance: Int = 10,
val chatMode: ChatModes = ChatModes.EVERYTHING, val chatMode: ChatModes = ChatModes.EVERYTHING,
val skinParts: Set<SkinParts> = setOf(*SkinParts.VALUES), val skinParts: Set<SkinParts> = setOf(*SkinParts.VALUES),
val mainHand: Hands = Hands.MAIN, val mainHand: Hands = Hands.MAIN,
@ -34,7 +34,7 @@ class ClientSettingsC2SP(
override fun write(buffer: PlayOutByteBuffer) { override fun write(buffer: PlayOutByteBuffer) {
buffer.writeString(locale) // locale buffer.writeString(locale) // locale
buffer.writeByte(renderDistance) // render Distance buffer.writeByte(viewDistance) // render Distance
buffer.writeByte(chatMode.ordinal) // chat settings buffer.writeByte(chatMode.ordinal) // chat settings
buffer.writeBoolean(true) // chat colors buffer.writeBoolean(true) // chat colors
if (buffer.versionId < ProtocolVersions.V_14W03B) { if (buffer.versionId < ProtocolVersions.V_14W03B) {
@ -56,7 +56,7 @@ class ClientSettingsC2SP(
} }
override fun log() { 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 { enum class SkinParts {

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.protocol.packets.s2c.play package de.bixilon.minosoft.protocol.packets.s2c.play
import com.google.common.collect.HashBiMap import com.google.common.collect.HashBiMap
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.Difficulties import de.bixilon.minosoft.data.Difficulties
import de.bixilon.minosoft.data.abilities.Gamemodes import de.bixilon.minosoft.data.abilities.Gamemodes
import de.bixilon.minosoft.data.registries.DefaultRegistries import de.bixilon.minosoft.data.registries.DefaultRegistries
@ -168,7 +169,7 @@ class JoinGameS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
NoiseBiomeAccessor(connection.world) NoiseBiomeAccessor(connection.world)
} }
TimeWorker.addTask(TimeWorkerTask(150, true) { // ToDo: Temp workaround 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 brandName = DefaultRegistries.DEFAULT_PLUGIN_CHANNELS_REGISTRY.forVersion(connection.version)[DefaultPluginChannels.BRAND]!!.resourceLocation
val buffer = PlayOutByteBuffer(connection) val buffer = PlayOutByteBuffer(connection)