From 1ca20c243b88c22ee0e9346c339f6d26a41a6acb Mon Sep 17 00:00:00 2001 From: Bixilon Date: Sun, 13 Jun 2021 19:35:41 +0200 Subject: [PATCH] block pushing --- .../java/de/bixilon/minosoft/data/Axes.kt | 56 +++++++++---------- .../de/bixilon/minosoft/data/Directions.kt | 1 + .../data/physics/CollisionDetector.kt | 6 +- .../minosoft/data/player/LocalPlayerEntity.kt | 53 +++++++++++++++++- .../gui/rendering/chunk/models/AABB.kt | 4 +- .../models/renderable/ElementRenderer.kt | 2 +- 6 files changed, 86 insertions(+), 36 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/data/Axes.kt b/src/main/java/de/bixilon/minosoft/data/Axes.kt index 479ad6b7b..61915118d 100644 --- a/src/main/java/de/bixilon/minosoft/data/Axes.kt +++ b/src/main/java/de/bixilon/minosoft/data/Axes.kt @@ -25,6 +25,34 @@ enum class Axes { Z, ; + fun choose(vec3: Vec3): Float { + return choose(vec3.x, vec3.y, vec3.z) + } + + fun choose(vec3: Vec3d): Double { + return choose(vec3.x, vec3.y, vec3.z) + } + + fun choose(vec3i: Vec3i): Int { + return choose(Vec3(vec3i)).toInt() + } + + private fun choose(x: Float, y: Float, z: Float): Float { + return when (this) { + X -> x + Y -> y + Z -> z + } + } + + private fun choose(x: Double, y: Double, z: Double): Double { + return when (this) { + X -> x + Y -> y + Z -> z + } + } + companion object : ValuesEnum, BlockPropertiesSerializer { override val VALUES: Array = values() override val NAME_MAP: Map = KUtil.getEnumValues(VALUES) @@ -37,34 +65,6 @@ enum class Axes { } } - fun choose(axis: Axes, vec3: Vec3): Float { - return choose(axis, vec3.x, vec3.y, vec3.z) - } - - fun choose(axis: Axes, vec3: Vec3d): Double { - return choose(axis, vec3.x, vec3.y, vec3.z) - } - - fun choose(axis: Axes, vec3i: Vec3i): Int { - return choose(axis, Vec3(vec3i)).toInt() - } - - private fun choose(axis: Axes, x: Float, y: Float, z: Float): Float { - return when (axis) { - X -> x - Y -> y - Z -> z - } - } - - private fun choose(axis: Axes, x: Double, y: Double, z: Double): Double { - return when (axis) { - X -> x - Y -> y - Z -> z - } - } - override fun deserialize(value: Any): Axes { return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value") } diff --git a/src/main/java/de/bixilon/minosoft/data/Directions.kt b/src/main/java/de/bixilon/minosoft/data/Directions.kt index c8ce494ba..32b0d3104 100644 --- a/src/main/java/de/bixilon/minosoft/data/Directions.kt +++ b/src/main/java/de/bixilon/minosoft/data/Directions.kt @@ -110,6 +110,7 @@ enum class Directions(val horizontalId: Int, val vector: Vec3i) { override val VALUES = values() override val NAME_MAP: Map = KUtil.getEnumValues(VALUES) val SIDES = arrayOf(NORTH, SOUTH, WEST, EAST) + val PRIORITY_SIDES = arrayOf(WEST, EAST, NORTH, SOUTH) private val HORIZONTAL = arrayOf(SOUTH, WEST, NORTH, EAST) override fun deserialize(value: Any): Directions { diff --git a/src/main/java/de/bixilon/minosoft/data/physics/CollisionDetector.kt b/src/main/java/de/bixilon/minosoft/data/physics/CollisionDetector.kt index 5cf5a42cb..aceaaa0dc 100644 --- a/src/main/java/de/bixilon/minosoft/data/physics/CollisionDetector.kt +++ b/src/main/java/de/bixilon/minosoft/data/physics/CollisionDetector.kt @@ -26,6 +26,7 @@ import de.bixilon.minosoft.protocol.network.connection.PlayConnection import glm_.vec3.Vec3 import glm_.vec3.Vec3bool import glm_.vec3.Vec3d +import glm_.vec3.Vec3i import kotlin.math.abs class CollisionDetector(val connection: PlayConnection) { @@ -36,7 +37,8 @@ class CollisionDetector(val connection: PlayConnection) { // check if already in block if (!connection.world.isSpaceEmpty(aabb)) { - blockPositions.remove(aabb.min.floor) + val center = aabb.center.floor + blockPositions.remove(Vec3i(center.x, aabb.min.y, center.z)) } val result = VoxelShape() @@ -54,7 +56,7 @@ class CollisionDetector(val connection: PlayConnection) { } fun sneak(entity: LocalPlayerEntity, deltaPosition: Vec3d): Vec3d { - if (entity.baseAbilities.isFlying || !entity.isSneaking || !entity.canSneak()) { + if (entity.baseAbilities.isFlying || !entity.isSneaking || !entity.canSneak) { return deltaPosition } diff --git a/src/main/java/de/bixilon/minosoft/data/player/LocalPlayerEntity.kt b/src/main/java/de/bixilon/minosoft/data/player/LocalPlayerEntity.kt index f20d3f4ed..4c1d56bc9 100644 --- a/src/main/java/de/bixilon/minosoft/data/player/LocalPlayerEntity.kt +++ b/src/main/java/de/bixilon/minosoft/data/player/LocalPlayerEntity.kt @@ -13,6 +13,8 @@ package de.bixilon.minosoft.data.player import de.bixilon.minosoft.Minosoft +import de.bixilon.minosoft.data.Axes +import de.bixilon.minosoft.data.Directions import de.bixilon.minosoft.data.abilities.Gamemodes import de.bixilon.minosoft.data.abilities.ItemCooldown import de.bixilon.minosoft.data.accounts.Account @@ -34,12 +36,15 @@ import de.bixilon.minosoft.data.registries.other.containers.Container import de.bixilon.minosoft.data.registries.other.containers.PlayerInventory import de.bixilon.minosoft.data.tags.DefaultBlockTags import de.bixilon.minosoft.data.tags.Tag +import de.bixilon.minosoft.gui.rendering.chunk.models.AABB import de.bixilon.minosoft.gui.rendering.input.camera.MovementInput import de.bixilon.minosoft.gui.rendering.util.VecUtil import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition import de.bixilon.minosoft.gui.rendering.util.VecUtil.clearZero import de.bixilon.minosoft.gui.rendering.util.VecUtil.empty +import de.bixilon.minosoft.gui.rendering.util.VecUtil.get +import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.protocol.packets.c2s.play.* import de.bixilon.minosoft.protocol.packets.s2c.play.TagsS2CP @@ -52,6 +57,7 @@ import de.bixilon.minosoft.util.MMath import glm_.func.cos import glm_.func.rad import glm_.func.sin +import glm_.vec2.Vec2 import glm_.vec3.Vec3 import glm_.vec3.Vec3d import glm_.vec3.Vec3i @@ -460,7 +466,13 @@ class LocalPlayerEntity( movementSideways *= 0.2f } - // ToDo: Push out of blocks + if (gamemode != Gamemodes.SPECTATOR) { + // ToDo: Push out of blocks + // pushOutOfBlocks(position.x - dimensions.x * 0.35, position.z + dimensions.x * 0.35) + // pushOutOfBlocks(position.x - dimensions.x * 0.35, position.z - dimensions.x * 0.35) + // pushOutOfBlocks(position.x + dimensions.x * 0.35, position.z - dimensions.x * 0.35) + // pushOutOfBlocks(position.x + dimensions.x * 0.35, position.z + dimensions.x * 0.35) + } // ToDo @@ -544,10 +556,45 @@ class LocalPlayerEntity( dirtyVelocity = true } - fun canSneak(): Boolean { - return (onGround && fallDistance < PhysicsConstants.STEP_HEIGHT) && !connection.world.isSpaceEmpty(aabb + Vec3(0.0f, fallDistance - PhysicsConstants.STEP_HEIGHT, 0.0f)) + private fun pushOutOfBlocks(x: Double, z: Double) { + val blockPosition = Vec3i(x, position.y, z) + if (!collidesAt(blockPosition)) { + return + } + + val decimal = Vec2(x - blockPosition.x, z - blockPosition.z) + + var pushDirection: Directions? = null + var minimumDistance = Float.MAX_VALUE + + for (direction in Directions.PRIORITY_SIDES) { + val nearestAxisValue = direction.axis.choose(Vec3(decimal.x, 0.0, decimal.y)) + val movement = (direction.vector[direction.axis] > 0.0).decide(1.0f - nearestAxisValue, nearestAxisValue) + if (movement < minimumDistance && !collidesAt(blockPosition + direction)) { + minimumDistance = movement + pushDirection = direction + } + } + + pushDirection ?: return + + if (pushDirection.axis == Axes.X) { + velocity.x = 0.1 * pushDirection.vectord.x + } else { + velocity.z = 0.1 * pushDirection.vectord.z + } } + private fun collidesAt(position: Vec3i): Boolean { + val aabb = aabb + val nextAABB = AABB(Vec3(position.x, aabb.min.y, position.z), Vec3(position.x + 1.0, aabb.max.y, position.z + 1.0)).shrink(1.0E-7) + + return !connection.world.isSpaceEmpty(nextAABB) + } + + val canSneak: Boolean + get() = (onGround && fallDistance < PhysicsConstants.STEP_HEIGHT) && !connection.world.isSpaceEmpty(aabb + Vec3(0.0f, fallDistance - PhysicsConstants.STEP_HEIGHT, 0.0f)) + override fun realTick() { if (connection.world[positionInfo.blockPosition.chunkPosition] == null) { // chunk not loaded, so we don't tick? 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 972969926..cf3d9735d 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 @@ -69,11 +69,11 @@ class AABB( } private fun min(axis: Axes): Double { - return Axes.choose(axis, min) + return axis.choose(min) } private fun max(axis: Axes): Double { - return Axes.choose(axis, max) + return axis.choose(max) } infix fun extend(vec3: Vec3d): AABB { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/ElementRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/ElementRenderer.kt index 421fd079a..e0314be10 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/ElementRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/ElementRenderer.kt @@ -58,7 +58,7 @@ class ElementRenderer( if (uvLock) { for (direction in Directions.VALUES) { val axis = Axes.byDirection(direction) - val angle = Axes.choose(axis, rotation) * Axes.choose(axis, direction.vector) + val angle = axis.choose(rotation) * axis.choose(direction.vector) faces[direction]?.rotate(-angle) } }