entities: collect visible renderers, sort them

This commit is contained in:
Moritz Zwerger 2023-10-24 10:11:55 +02:00
parent 98efcc22fa
commit 725d569016
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
5 changed files with 52 additions and 9 deletions

View File

@ -64,3 +64,8 @@ Entities are always designed without any rotation (i.e. `yaw`=`0`)
- Store offset and rotation as uniform
- Make hitbox a default feature of entity renderer
- draw as opaque
## Tests
- hitbox (data, loading, unloading)
- collect visible meshes (with sorting, priority type and distance)

View File

@ -61,6 +61,7 @@ class EntitiesRenderer(
if (reset) it.reset()
visibility.update(it)
it.update(millis)
visibility.collect(it)
}
this.reset = false
this.visibility.finish()

View File

@ -15,9 +15,10 @@ package de.bixilon.minosoft.gui.rendering.entities.feature
import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer
abstract class EntityRenderFeature(val renderer: EntityRenderer<*>) {
abstract class EntityRenderFeature(val renderer: EntityRenderer<*>) : Comparable<EntityRenderFeature> {
var enabled = true
open val priority: Int get() = 0
val sort = this::class.java.hashCode()
open fun updateVisibility(occluded: Boolean, visible: Boolean): Boolean {
val enabled = !occluded && visible
@ -26,8 +27,20 @@ abstract class EntityRenderFeature(val renderer: EntityRenderer<*>) {
return true
}
open fun reset() = Unit
open fun update(millis: Long) = Unit
open fun unload() = Unit
abstract fun draw()
open fun compareByDistance(other: EntityRenderFeature): Int = 0
override fun compareTo(other: EntityRenderFeature): Int {
var compare = priority.compareTo(other.priority)
if (compare != 0) return compare
compare = sort.compareTo(other.sort) // dirty sort by type (that makes using of shaders, etc way "faster")
if (compare != 0) return compare
return compareByDistance(other)
}
}

View File

@ -15,23 +15,34 @@ package de.bixilon.minosoft.gui.rendering.entities.feature
import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer
class FeatureManager(val renderer: EntityRenderer<*>) {
class FeatureManager(val renderer: EntityRenderer<*>) : Iterable<EntityRenderFeature> {
private val features: ArrayList<EntityRenderFeature> = ArrayList(10)
operator fun plusAssign(feature: EntityRenderFeature) = register(feature)
fun register(feature: EntityRenderFeature) {
TODO()
this.features += feature
}
fun update(millis: Long) {
TODO()
for (feature in features) {
feature.update(millis)
}
}
fun unload() {
TODO()
for (feature in features) {
feature.unload()
}
}
fun reset() {
TODO()
for (feature in features) {
feature.reset()
}
}
override fun iterator(): Iterator<EntityRenderFeature> {
return features.iterator()
}
}

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.gui.rendering.entities.visibility
import de.bixilon.kutil.concurrent.lock.simple.SimpleLock
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
@ -26,28 +27,40 @@ class VisibilityManager(val renderer: EntitiesRenderer) : Iterable<EntityRenderF
private set
private val count = AtomicInteger()
private val visible: ArrayList<EntityRenderFeature> = ArrayList(1000)
private val lock = SimpleLock()
fun init() {
renderer.connection.events.listen<VisibilityGraphChangeEvent> { update = true }
}
fun reset() {
this.visible.clear()
count.set(0)
}
fun update(renderer: EntityRenderer<*>) {
renderer.visibility.update(this.update)
if (renderer.visibility.visible) {
count.incrementAndGet()
}
fun collect(renderer: EntityRenderer<*>) {
if (!renderer.visibility.visible) return
count.incrementAndGet()
lock.lock()
for (feature in renderer.features) {
if (!feature.enabled) continue
this.visible += feature
}
lock.unlock()
}
fun finish() {
this.visible.sort() // TODO: Optimize it (pre create array, just work with array?)
this.update = false
size = count.get()
}
override fun iterator(): Iterator<EntityRenderFeature> {
TODO()
return this.visible.iterator()
}
}