block pushing

This commit is contained in:
Bixilon 2021-06-13 19:35:41 +02:00 committed by Lukas
parent f7e4212878
commit 1ca20c243b
6 changed files with 86 additions and 36 deletions

View File

@ -25,6 +25,34 @@ enum class Axes {
Z, 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<Axes>, BlockPropertiesSerializer { companion object : ValuesEnum<Axes>, BlockPropertiesSerializer {
override val VALUES: Array<Axes> = values() override val VALUES: Array<Axes> = values()
override val NAME_MAP: Map<String, Axes> = KUtil.getEnumValues(VALUES) override val NAME_MAP: Map<String, Axes> = 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 { override fun deserialize(value: Any): Axes {
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value") return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
} }

View File

@ -110,6 +110,7 @@ enum class Directions(val horizontalId: Int, val vector: Vec3i) {
override val VALUES = values() override val VALUES = values()
override val NAME_MAP: Map<String, Directions> = KUtil.getEnumValues(VALUES) override val NAME_MAP: Map<String, Directions> = KUtil.getEnumValues(VALUES)
val SIDES = arrayOf(NORTH, SOUTH, WEST, EAST) val SIDES = arrayOf(NORTH, SOUTH, WEST, EAST)
val PRIORITY_SIDES = arrayOf(WEST, EAST, NORTH, SOUTH)
private val HORIZONTAL = arrayOf(SOUTH, WEST, NORTH, EAST) private val HORIZONTAL = arrayOf(SOUTH, WEST, NORTH, EAST)
override fun deserialize(value: Any): Directions { override fun deserialize(value: Any): Directions {

View File

@ -26,6 +26,7 @@ import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import glm_.vec3.Vec3 import glm_.vec3.Vec3
import glm_.vec3.Vec3bool import glm_.vec3.Vec3bool
import glm_.vec3.Vec3d import glm_.vec3.Vec3d
import glm_.vec3.Vec3i
import kotlin.math.abs import kotlin.math.abs
class CollisionDetector(val connection: PlayConnection) { class CollisionDetector(val connection: PlayConnection) {
@ -36,7 +37,8 @@ class CollisionDetector(val connection: PlayConnection) {
// check if already in block // check if already in block
if (!connection.world.isSpaceEmpty(aabb)) { 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() val result = VoxelShape()
@ -54,7 +56,7 @@ class CollisionDetector(val connection: PlayConnection) {
} }
fun sneak(entity: LocalPlayerEntity, deltaPosition: Vec3d): Vec3d { 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 return deltaPosition
} }

View File

@ -13,6 +13,8 @@
package de.bixilon.minosoft.data.player package de.bixilon.minosoft.data.player
import de.bixilon.minosoft.Minosoft 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.Gamemodes
import de.bixilon.minosoft.data.abilities.ItemCooldown import de.bixilon.minosoft.data.abilities.ItemCooldown
import de.bixilon.minosoft.data.accounts.Account 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.registries.other.containers.PlayerInventory
import de.bixilon.minosoft.data.tags.DefaultBlockTags import de.bixilon.minosoft.data.tags.DefaultBlockTags
import de.bixilon.minosoft.data.tags.Tag 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.input.camera.MovementInput
import de.bixilon.minosoft.gui.rendering.util.VecUtil 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.EMPTY
import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition 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.clearZero
import de.bixilon.minosoft.gui.rendering.util.VecUtil.empty 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.network.connection.PlayConnection
import de.bixilon.minosoft.protocol.packets.c2s.play.* import de.bixilon.minosoft.protocol.packets.c2s.play.*
import de.bixilon.minosoft.protocol.packets.s2c.play.TagsS2CP 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.cos
import glm_.func.rad import glm_.func.rad
import glm_.func.sin import glm_.func.sin
import glm_.vec2.Vec2
import glm_.vec3.Vec3 import glm_.vec3.Vec3
import glm_.vec3.Vec3d import glm_.vec3.Vec3d
import glm_.vec3.Vec3i import glm_.vec3.Vec3i
@ -460,7 +466,13 @@ class LocalPlayerEntity(
movementSideways *= 0.2f 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 // ToDo
@ -544,10 +556,45 @@ class LocalPlayerEntity(
dirtyVelocity = true dirtyVelocity = true
} }
fun canSneak(): Boolean { private fun pushOutOfBlocks(x: Double, z: Double) {
return (onGround && fallDistance < PhysicsConstants.STEP_HEIGHT) && !connection.world.isSpaceEmpty(aabb + Vec3(0.0f, fallDistance - PhysicsConstants.STEP_HEIGHT, 0.0f)) 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() { override fun realTick() {
if (connection.world[positionInfo.blockPosition.chunkPosition] == null) { if (connection.world[positionInfo.blockPosition.chunkPosition] == null) {
// chunk not loaded, so we don't tick? // chunk not loaded, so we don't tick?

View File

@ -69,11 +69,11 @@ class AABB(
} }
private fun min(axis: Axes): Double { private fun min(axis: Axes): Double {
return Axes.choose(axis, min) return axis.choose(min)
} }
private fun max(axis: Axes): Double { private fun max(axis: Axes): Double {
return Axes.choose(axis, max) return axis.choose(max)
} }
infix fun extend(vec3: Vec3d): AABB { infix fun extend(vec3: Vec3d): AABB {

View File

@ -58,7 +58,7 @@ class ElementRenderer(
if (uvLock) { if (uvLock) {
for (direction in Directions.VALUES) { for (direction in Directions.VALUES) {
val axis = Axes.byDirection(direction) 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) faces[direction]?.rotate(-angle)
} }
} }