improved hitbox rendering

This commit is contained in:
Moritz Zwerger 2023-10-24 18:13:16 +02:00
parent 0e094609ed
commit 2c732f44d0
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
5 changed files with 102 additions and 20 deletions

View File

@ -52,18 +52,28 @@ Entities are always designed without any rotation (i.e. `yaw`=`0`)
- update visible and not visible
- entity name is also visible through walls, rest not
- also with frustum (no need to update renderers that are out of the frustum)
- -> handle occlusion differently from visibility
- option to turn on/off "features"
- how to register entity models?
- loop over all entity (and block entity) types and register?
- store entities in octree like structure
- ways faster collisions with them -> physics
- way faster getInRadius -> particles, maybe entities in the future
## Hitboxes
- Create line mesh with default aabb
- interpolate aabb if size changes (e.g. changing pose for players)
- how about rendering velocity or view?
- interpolate
- aabb (not at all, taken from renderInfo)
- color: 0.5s
- velocity (ticks)
- direction (taken from renderInfo)
- eye height (taken from renderInfo)
- they must alight with the matrix handler -> mustn't be a frame too late/early
- Store offset and rotation as uniform
- Make hitbox a default feature of entity renderer
- draw as opaque
- highest priority (enables cheap gpu clipping)
- dynamic enabling and disabling (hitbox manager, keybinding)
## Tests

View File

@ -14,13 +14,17 @@
package de.bixilon.minosoft.gui.rendering.entities.hitbox
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.data.registries.shapes.aabb.AABB
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY_INSTANCE
data class HitboxData(
val aabb: AABB,
val color: RGBColor,
val velocity: Vec3?,
val rotation: EntityRotation,
)
var color: RGBColor = ChatColors.WHITE,
var velocity: Vec3 = Vec3.EMPTY_INSTANCE,
) {
fun update(entity: Entity) {
}
}

View File

@ -13,31 +13,98 @@
package de.bixilon.minosoft.gui.rendering.entities.hitbox
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.data.registries.shapes.aabb.AABB
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.gui.rendering.entities.feature.EntityRenderFeature
import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer
import de.bixilon.minosoft.gui.rendering.util.mesh.LineMesh
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
class HitboxFeature(renderer: EntityRenderer<*>) : EntityRenderFeature(renderer) {
private val shader = renderer.renderer.context.shaders.genericColorShader
private val manager = renderer.renderer.hitbox
private var mesh: LineMesh? = null
private var aabb = AABB.EMPTY
private var eyePosition = Vec3.EMPTY
private var rotation = EntityRotation.EMPTY
private val data = HitboxData()
private var data0 = HitboxData()
private var data1 = HitboxData()
override fun reset() {
unload()
}
override fun update(millis: Long) {
if (!manager.enabled) return unload()
val offset = renderer.renderer.context.camera.offset.offset
val update = updateRenderInfo(offset) or interpolate(millis)
if (this.mesh != null && !update) return
updateMesh()
}
private fun updateRenderInfo(offset: Vec3i): Boolean {
var changes = 0
val renderInfo = renderer.entity.renderInfo
val aabb = renderInfo.cameraAABB + -offset
val eyePosition = Vec3(renderInfo.eyePosition - offset)
val rotation = renderInfo.rotation
if (aabb != this.aabb) {
this.aabb = aabb; changes++
}
if (eyePosition != this.eyePosition) {
this.eyePosition = eyePosition; changes++
}
if (rotation != this.rotation) {
this.rotation = rotation; changes++
}
return changes > 0
}
private fun interpolate(millis: Long): Boolean {
// TODO: interpolate color in 5 ticks and velocity per tick
return false
}
private fun updateMesh() {
unload()
val mesh = LineMesh(renderer.renderer.context)
mesh.drawLazyAABB(renderer.entity.renderInfo.cameraAABB, renderer.entity.hitboxColor ?: ChatColors.WHITE)
if (manager.profile.lazy) {
mesh.drawLazyAABB(aabb, data.color)
} else {
mesh.drawAABB(aabb, color = data.color)
}
val center = Vec3(aabb.center)
if (data.velocity.length2() > 0.003f) {
mesh.drawLine(center, center + data.velocity * 15.0f, color = ChatColors.YELLOW)
}
mesh.drawLine(eyePosition, eyePosition + rotation.front * 5.0f, color = ChatColors.BLUE)
this.mesh = mesh
}
override fun draw() {
val mesh = this.mesh ?: return
if (mesh.state != Mesh.MeshStates.LOADED) mesh.load()
shader.use()
manager.shader.use()
mesh.draw()
}

View File

@ -22,7 +22,9 @@ import de.bixilon.minosoft.gui.rendering.entities.EntitiesRenderer
import de.bixilon.minosoft.util.KUtil.format
class HitboxManager(private val renderer: EntitiesRenderer) {
private val profile = renderer.profile.hitbox
val profile = renderer.profile.hitbox
val shader = renderer.context.shaders.genericColorShader
var enabled = profile.enabled

View File

@ -19,6 +19,5 @@ class EntityVisibility(val renderer: EntityRenderer<*>) {
val visible: Boolean = true
fun update(force: Boolean) {
TODO()
}
}