From a9280eef30283c301b9bb4cfb130b33e1a563f79 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Sun, 27 Jun 2021 17:19:12 +0200 Subject: [PATCH] improve entity hit box rendering --- .../game/entities/EntityHitBoxConfig.kt | 1 + .../minosoft/data/entities/entities/Entity.kt | 17 +++++++++----- .../gui/rendering/chunk/models/AABB.kt | 22 +++++++++++++++++++ .../rendering/entities/EntityHitBoxMesh.kt | 12 +++++----- .../entities/EntityHitBoxRenderer.kt | 15 ++++++++++--- .../gui/rendering/input/camera/Camera.kt | 4 ++-- .../minosoft/gui/rendering/util/VecUtil.kt | 4 ++++ .../gui/rendering/util/mesh/LineMesh.kt | 8 +++++-- .../packets/s2c/play/EntityTeleportS2CP.kt | 1 - .../s2c/play/PositionAndRotationS2CP.kt | 1 - 10 files changed, 64 insertions(+), 21 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/config/config/game/entities/EntityHitBoxConfig.kt b/src/main/java/de/bixilon/minosoft/config/config/game/entities/EntityHitBoxConfig.kt index 92cc5dc5d..290b9a110 100644 --- a/src/main/java/de/bixilon/minosoft/config/config/game/entities/EntityHitBoxConfig.kt +++ b/src/main/java/de/bixilon/minosoft/config/config/game/entities/EntityHitBoxConfig.kt @@ -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, diff --git a/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt b/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt index e9bed62c0..60d61c6d7 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt @@ -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() } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/AABB.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/AABB.kt index e90feabd9..d54647362 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/AABB.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/AABB.kt @@ -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) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/EntityHitBoxMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/EntityHitBoxMesh.kt index 3f9b5e2f3..e6c94edb6 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/EntityHitBoxMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/EntityHitBoxMesh.kt @@ -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) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/EntityHitBoxRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/EntityHitBoxRenderer.kt index 3e267ce9d..2c8156bfb 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/EntityHitBoxRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/EntityHitBoxRenderer.kt @@ -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() { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/input/camera/Camera.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/input/camera/Camera.kt index 2c053cf8f..6f4f856ff 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/input/camera/Camera.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/input/camera/Camera.kt @@ -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) { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/util/VecUtil.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/util/VecUtil.kt index 484f37270..7d87dd5a0 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/util/VecUtil.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/util/VecUtil.kt @@ -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), diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/LineMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/LineMesh.kt index 9d5ae6112..9d5275587 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/LineMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/LineMesh.kt @@ -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) diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/EntityTeleportS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/EntityTeleportS2CP.kt index 9a25013fa..62d36183e 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/EntityTeleportS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/EntityTeleportS2CP.kt @@ -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) } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/PositionAndRotationS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/PositionAndRotationS2CP.kt index c8652aaa5..0b721f3b5 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/PositionAndRotationS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/PositionAndRotationS2CP.kt @@ -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) {