improve entity hit box rendering

This commit is contained in:
Bixilon 2021-06-27 17:19:12 +02:00
parent bd160145ec
commit a9280eef30
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
10 changed files with 64 additions and 21 deletions

View File

@ -19,6 +19,7 @@ import de.bixilon.minosoft.data.text.RGBColor
data class EntityHitBoxConfig(
@Json(name = "enabled") val enabled: Boolean = true,
@Json(name = "own_hit_box") val ownHitBox: Boolean = false,
@Json(name = "disable_z_buffer") val disableZBuffer: Boolean = false,
@Json(name = "hit_box_color") val hitBoxColor: RGBColor = ChatColors.WHITE,
@Json(name = "eye_height_color") val eyeHeightColor: RGBColor = ChatColors.DARK_RED,

View File

@ -40,6 +40,7 @@ import de.bixilon.minosoft.gui.rendering.util.VecUtil.empty
import de.bixilon.minosoft.gui.rendering.util.VecUtil.floor
import de.bixilon.minosoft.gui.rendering.util.VecUtil.horizontal
import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkPosition
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3d
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
@ -103,19 +104,20 @@ abstract class Entity(
get() = dimensions.y * 0.85f
private var lastFakeTickTime = -1L
var previousPosition: Vec3d = Vec3d(position)
private var previousPosition: Vec3d = Vec3d(position)
override var position: Vec3d = position
set(value) {
previousPosition = field
field = value
positionInfo.update()
}
open val positionInfo = EntityPositionInfo(connection, this)
val eyePosition: Vec3d
get() = realPosition + Vec3(0.0f, eyeHeight, 0.0f)
get() = cameraPosition + Vec3(0.0f, eyeHeight, 0.0f)
val realPosition: Vec3d
get() = VecUtil.lerp((System.currentTimeMillis() - lastTickTime) / ProtocolDefinition.TICK_TIMEd, previousPosition, position)
var cameraPosition: Vec3d = position.toVec3d
private set
open val spawnSprintingParticles: Boolean
get() = isSprinting && !isSneaking // ToDo: Touching fluids
@ -123,7 +125,6 @@ abstract class Entity(
protected var lastTickTime = -1L
fun forceMove(deltaPosition: Vec3d) {
previousPosition = Vec3d(position)
position = position + deltaPosition
}
@ -301,6 +302,10 @@ abstract class Entity(
get() = defaultAABB + position
val cameraAABB: AABB
get() = defaultAABB + cameraPosition
@Synchronized
fun tick() {
val currentTime = System.currentTimeMillis()
@ -318,9 +323,11 @@ abstract class Entity(
realTick()
lastTickTime = currentTime
}
cameraPosition = VecUtil.lerp((currentTime - lastTickTime) / ProtocolDefinition.TICK_TIMEd, previousPosition, position)
}
open fun realTick() {
previousPosition = position
if (spawnSprintingParticles) {
spawnSprintingParticles()
}

View File

@ -195,6 +195,28 @@ class AABB(
val center: Vec3d
get() = Vec3d((min.x + max.x) / 2.0, (min.y + max.y) / 2.0, (min.z + max.z) / 2.0)
override fun hashCode(): Int {
return min.hashCode() + max.hashCode()
}
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (this.hashCode() != other?.hashCode()) {
return false
}
if (other !is AABB) {
return false
}
return min == other.min && max == other.max
}
override fun toString(): String {
return "AABB[$min;$max]"
}
companion object {
val EMPTY: AABB
get() = AABB(Vec3.EMPTY, Vec3.EMPTY)

View File

@ -17,28 +17,26 @@ import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.chunk.models.AABB
import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY
import de.bixilon.minosoft.gui.rendering.util.mesh.LineMesh
import glm_.vec3.Vec3
import glm_.vec3.Vec3d
class EntityHitBoxMesh(
val entity: Entity,
val aabb: AABB,
) : LineMesh() {
var needsUpdate = true
var visible = false
val aabb = entity.aabb
init {
val hitBoxColor = when {
entity.isInvisible -> Minosoft.config.config.game.entities.hitBox.invisibleEntitiesColor
else -> Minosoft.config.config.game.entities.hitBox.hitBoxColor
}
drawAABB(entity.aabb, Vec3d.EMPTY, RenderConstants.DEFAULT_LINE_WIDTH, hitBoxColor)
drawAABB(aabb, RenderConstants.DEFAULT_LINE_WIDTH, hitBoxColor)
val halfWidth = entity.dimensions.x / 2
val eyeAABB = AABB(Vec3(-halfWidth, entity.eyeHeight - RenderConstants.DEFAULT_LINE_WIDTH, -halfWidth), Vec3(halfWidth, entity.eyeHeight - RenderConstants.DEFAULT_LINE_WIDTH, halfWidth)).hShrink(RenderConstants.DEFAULT_LINE_WIDTH)
drawAABB(eyeAABB, entity.position, RenderConstants.DEFAULT_LINE_WIDTH, Minosoft.config.config.game.entities.hitBox.eyeHeightColor)
val eyeHeight = aabb.min.y + entity.eyeHeight
val eyeAABB = AABB(Vec3(aabb.min.x, eyeHeight, aabb.min.z), Vec3(aabb.max.x, eyeHeight, aabb.max.z)).hShrink(RenderConstants.DEFAULT_LINE_WIDTH)
drawAABB(eyeAABB, RenderConstants.DEFAULT_LINE_WIDTH, Minosoft.config.config.game.entities.hitBox.eyeHeightColor)
}
}

View File

@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.entities
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.data.player.LocalPlayerEntity
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.Renderer
@ -30,6 +31,9 @@ import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
import de.bixilon.minosoft.util.KUtil.toSynchronizedMap
import de.bixilon.minosoft.util.collections.SynchronizedMap
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType
class EntityHitBoxRenderer(
val connection: PlayConnection,
@ -39,7 +43,8 @@ class EntityHitBoxRenderer(
private fun updateMesh(entity: Entity, mesh: EntityHitBoxMesh? = meshes[entity]): EntityHitBoxMesh? {
val aabb = entity.aabb
entity.tick() // ToDo: Remove
val aabb = entity.cameraAABB
val visible = renderWindow.inputHandler.camera.frustum.containsAABB(aabb)
if (!visible) {
@ -58,11 +63,11 @@ class EntityHitBoxRenderer(
return nextMesh
}
private fun createMesh(entity: Entity, aabb: AABB = entity.aabb, visible: Boolean = renderWindow.inputHandler.camera.frustum.containsAABB(aabb)): EntityHitBoxMesh? {
private fun createMesh(entity: Entity, aabb: AABB = entity.cameraAABB, visible: Boolean = renderWindow.inputHandler.camera.frustum.containsAABB(aabb)): EntityHitBoxMesh? {
if (entity.isInvisible && !Minosoft.config.config.game.entities.hitBox.renderInvisibleEntities) {
return null
}
val mesh = EntityHitBoxMesh(entity)
val mesh = EntityHitBoxMesh(entity, aabb)
if (visible) {
mesh.load()
@ -95,6 +100,10 @@ class EntityHitBoxRenderer(
mesh.visible = renderWindow.inputHandler.camera.frustum.containsAABB(mesh.aabb)
}
})
if (Minosoft.config.config.game.entities.hitBox.ownHitBox) {
createMesh(connection.player)
}
}
override fun draw() {

View File

@ -185,8 +185,8 @@ class Camera(
}
private fun calculateViewMatrix(): Mat4d {
val cameraPosition = entity.eyePosition
return glm.lookAt(cameraPosition, cameraPosition + cameraFront, CAMERA_UP_VEC3)
val eyePosition = entity.eyePosition
return glm.lookAt(eyePosition, eyePosition + cameraFront, CAMERA_UP_VEC3)
}
private fun setRotation(yaw: Double, pitch: Double) {

View File

@ -423,6 +423,10 @@ object VecUtil {
}
fun lerp(delta: Double, start: Vec3d, end: Vec3d): Vec3d {
when {
delta <= 0.0 -> return start
delta >= 1.0 -> return end
}
return Vec3d(
lerp(delta, start.x, end.x),
lerp(delta, start.y, end.y),

View File

@ -55,8 +55,12 @@ open class LineMesh : GenericColorMesh() {
}
fun drawAABB(aabb: AABB, position: Vec3d, lineWidth: Float, color: RGBColor, margin: Float = 0.0f) {
val min = position + aabb.min - margin
val max = position + aabb.max + margin
drawAABB(aabb + position, lineWidth, color, margin)
}
fun drawAABB(aabb: AABB, lineWidth: Float, color: RGBColor, margin: Float = 0.0f) {
val min = aabb.min - margin
val max = aabb.max + margin
fun drawSideQuad(x: Double) {
drawLine(Vec3(x, min.y, min.z), Vec3(x, max.y, min.z), lineWidth, color)

View File

@ -40,7 +40,6 @@ class EntityTeleportS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
override fun handle(connection: PlayConnection) {
val entity = connection.world.entities[entityId] ?: return
entity.position = position
entity.previousPosition = position
entity.setRotation(yaw, pitch)
}

View File

@ -73,7 +73,6 @@ class PositionAndRotationS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
}
entity.position = position
entity.previousPosition = position
entity.rotation = rotation
if (connection.version.versionId >= ProtocolVersions.V_15W42A) {