diff --git a/doc/rendering/Entities.md b/doc/rendering/Entities.md index 1e77f46fe..0abb7afe3 100644 --- a/doc/rendering/Entities.md +++ b/doc/rendering/Entities.md @@ -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) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/EntitiesRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/EntitiesRenderer.kt index 798bae6ba..56caae864 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/EntitiesRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/EntitiesRenderer.kt @@ -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() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/EntityRenderFeature.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/EntityRenderFeature.kt index 28b0f1289..ab2514505 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/EntityRenderFeature.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/EntityRenderFeature.kt @@ -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 { 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) + } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/FeatureManager.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/FeatureManager.kt index 734e46e73..b7509051d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/FeatureManager.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/FeatureManager.kt @@ -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 { + private val features: ArrayList = 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 { + return features.iterator() } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/visibility/VisibilityManager.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/visibility/VisibilityManager.kt index 907a25406..36ce0bf5a 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/visibility/VisibilityManager.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/visibility/VisibilityManager.kt @@ -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 = ArrayList(1000) + private val lock = SimpleLock() fun init() { renderer.connection.events.listen { 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 { - TODO() + return this.visible.iterator() } }