mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-18 03:44:54 -04:00
entity render distance
This commit is contained in:
parent
b0d99a011a
commit
cc92897293
@ -19,6 +19,7 @@ import de.bixilon.minosoft.config.profile.delegate.types.StringDelegate
|
||||
import de.bixilon.minosoft.config.profile.profiles.Profile
|
||||
import de.bixilon.minosoft.config.profile.profiles.entity.EntityProfileManager.latestVersion
|
||||
import de.bixilon.minosoft.config.profile.profiles.entity.features.FeaturesC
|
||||
import de.bixilon.minosoft.config.profile.profiles.entity.general.GeneralC
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
/**
|
||||
@ -37,6 +38,7 @@ class EntityProfile(
|
||||
override var description by StringDelegate(this, description ?: "")
|
||||
|
||||
|
||||
val general = GeneralC(this)
|
||||
val features = FeaturesC(this)
|
||||
|
||||
override fun toString(): String {
|
||||
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.config.profile.profiles.entity.general
|
||||
|
||||
import de.bixilon.minosoft.config.profile.delegate.primitive.BooleanDelegate
|
||||
import de.bixilon.minosoft.config.profile.delegate.primitive.IntDelegate
|
||||
import de.bixilon.minosoft.config.profile.profiles.entity.EntityProfile
|
||||
import de.bixilon.minosoft.data.world.World
|
||||
|
||||
class GeneralC(profile: EntityProfile) {
|
||||
/**
|
||||
* Enables entity rendering
|
||||
*/
|
||||
var enabled by BooleanDelegate(profile, true)
|
||||
|
||||
/**
|
||||
* Entity render distance (x,y,z direction)
|
||||
* May be -1 to use the block render distance
|
||||
*/
|
||||
var renderDistance by IntDelegate(profile, -1, "", ranges = arrayOf(-1..-1, 0..World.MAX_RENDER_DISTANCE))
|
||||
}
|
@ -60,7 +60,8 @@ class EntitiesRenderer(
|
||||
this.visibility.reset()
|
||||
renderers.iterate {
|
||||
if (reset) it.reset()
|
||||
visibility.update(it)
|
||||
visibility.update(it, millis)
|
||||
if (!it.visible) return@iterate
|
||||
it.update(millis)
|
||||
visibility.collect(it)
|
||||
}
|
||||
@ -91,7 +92,8 @@ class EntitiesRenderer(
|
||||
|
||||
companion object : RendererBuilder<EntitiesRenderer> {
|
||||
|
||||
override fun build(connection: PlayConnection, context: RenderContext): EntitiesRenderer {
|
||||
override fun build(connection: PlayConnection, context: RenderContext): EntitiesRenderer? {
|
||||
if (!connection.profiles.entity.general.enabled) return null
|
||||
return EntitiesRenderer(connection, context)
|
||||
}
|
||||
}
|
||||
|
@ -72,12 +72,16 @@ abstract class EntityRenderer<E : Entity>(
|
||||
|
||||
open fun update(millis: Long, delta: Float) {
|
||||
updateLight(delta)
|
||||
entity.draw(millis)
|
||||
this.distance = (entity.renderInfo.eyePosition - renderer.connection.camera.entity.renderInfo.eyePosition).length2()
|
||||
updateRenderInfo(millis)
|
||||
updateMatrix(delta)
|
||||
features.update(millis, delta)
|
||||
}
|
||||
|
||||
open fun updateRenderInfo(millis: Long) {
|
||||
entity.draw(millis)
|
||||
this.distance = (entity.renderInfo.eyePosition - renderer.connection.camera.entity.renderInfo.eyePosition).length2()
|
||||
}
|
||||
|
||||
private fun getCurrentLight(): Int {
|
||||
var light = entity.physics.positionInfo.chunk?.light?.get(entity.physics.positionInfo.inChunkPosition) ?: return 0xFF
|
||||
if (entity.isOnFire) {
|
||||
|
@ -14,37 +14,58 @@
|
||||
package de.bixilon.minosoft.gui.rendering.entities.visibility
|
||||
|
||||
import de.bixilon.kutil.concurrent.lock.simple.SimpleLock
|
||||
import de.bixilon.kutil.observer.DataObserver.Companion.observe
|
||||
import de.bixilon.minosoft.data.world.view.ViewDistanceChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.entities.EntitiesRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.entities.feature.EntityRenderFeature
|
||||
import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.events.VisibilityGraphChangeEvent
|
||||
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
|
||||
class VisibilityManager(val renderer: EntitiesRenderer) {
|
||||
private var update = false
|
||||
var size: Int = 0
|
||||
private set
|
||||
|
||||
private val count = AtomicInteger()
|
||||
val opaque: ArrayList<EntityRenderFeature> = ArrayList(1000)
|
||||
val translucent: ArrayList<EntityRenderFeature> = ArrayList(1000)
|
||||
private val lock = SimpleLock()
|
||||
private val graph = renderer.context.camera.visibilityGraph
|
||||
private val frustum = renderer.context.camera.matrixHandler.frustum
|
||||
private var renderDistance = 0
|
||||
|
||||
fun init() {
|
||||
renderer.connection.events.listen<VisibilityGraphChangeEvent> { update = true }
|
||||
renderer.connection.events.listen<ViewDistanceChangeEvent> { updateViewDistance(server = it.viewDistance) }
|
||||
renderer.profile.general::renderDistance.observe(this, true) { updateViewDistance(entity = it) }
|
||||
}
|
||||
|
||||
private fun updateViewDistance(entity: Int = renderer.profile.general.renderDistance, server: Int = renderer.connection.world.view.serverViewDistance) {
|
||||
var distance = if (entity < 0) (server - 1) else entity
|
||||
distance *= ProtocolDefinition.SECTION_LENGTH
|
||||
this.renderDistance = distance * distance // length^2
|
||||
}
|
||||
|
||||
|
||||
fun reset() {
|
||||
opaque.clear()
|
||||
translucent.clear()
|
||||
count.set(0)
|
||||
size = 0
|
||||
}
|
||||
|
||||
fun update(renderer: EntityRenderer<*>) {
|
||||
// TODO: check render distance (and maybe entity distance)
|
||||
private fun EntityRenderer<*>.isInRenderDistance(): Boolean {
|
||||
return renderDistance < 0 || distance <= renderDistance
|
||||
}
|
||||
|
||||
fun update(renderer: EntityRenderer<*>, millis: Long) {
|
||||
if (!renderer.isInRenderDistance()) {
|
||||
// distance is only updated if the renderer is visible, so force update
|
||||
renderer.updateRenderInfo(millis)
|
||||
}
|
||||
if (!renderer.isInRenderDistance()) {
|
||||
return renderer.updateVisibility(true, true)
|
||||
}
|
||||
val aabb = renderer.entity.renderInfo.cameraAABB
|
||||
val visible = aabb in frustum
|
||||
if (!visible) {
|
||||
@ -57,8 +78,8 @@ class VisibilityManager(val renderer: EntitiesRenderer) {
|
||||
|
||||
fun collect(renderer: EntityRenderer<*>) {
|
||||
if (!renderer.visible) return
|
||||
count.incrementAndGet()
|
||||
lock.lock()
|
||||
size++
|
||||
for (feature in renderer.features) {
|
||||
if (!feature.enabled || !feature.visible) continue
|
||||
feature.collect(this)
|
||||
@ -71,7 +92,6 @@ class VisibilityManager(val renderer: EntitiesRenderer) {
|
||||
this.opaque.sort()
|
||||
this.translucent.sort()
|
||||
this.update = false
|
||||
size = count.get()
|
||||
}
|
||||
|
||||
operator fun get(layer: EntityLayer) = when (layer) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user