physics: fix multithreading issues with entity velocity

This commit is contained in:
Lukas 2021-04-27 18:01:09 +02:00
parent ffc34ed1e5
commit 4e6013ed92
3 changed files with 24 additions and 37 deletions

View File

@ -26,7 +26,6 @@ import de.bixilon.minosoft.data.mappings.entities.EntityType
import de.bixilon.minosoft.data.text.ChatComponent import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.gui.rendering.chunk.VoxelShape import de.bixilon.minosoft.gui.rendering.chunk.VoxelShape
import de.bixilon.minosoft.gui.rendering.chunk.models.AABB import de.bixilon.minosoft.gui.rendering.chunk.models.AABB
import de.bixilon.minosoft.gui.rendering.util.VecUtil
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.inChunkPosition import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkPosition
import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.protocol.network.connection.PlayConnection
@ -51,7 +50,7 @@ abstract class Entity(
var entityMetaData: EntityMetaData = EntityMetaData(connection) var entityMetaData: EntityMetaData = EntityMetaData(connection)
var velocity: Vec3? = null var velocity: Vec3 = Vec3()
protected open val hasCollisions = true protected open val hasCollisions = true
protected open val isFlying = false protected open val isFlying = false
@ -229,9 +228,9 @@ abstract class Entity(
if (delta.y != 0.0f) { if (delta.y != 0.0f) {
delta.y = collisionsToCheck.computeOffset(aabb, deltaPosition.y, Axes.Y) delta.y = collisionsToCheck.computeOffset(aabb, deltaPosition.y, Axes.Y)
aabb.offsetAssign(0f, delta.y, 0f) aabb.offsetAssign(0f, delta.y, 0f)
onGround = false
if (delta.y != deltaPosition.y) { if (delta.y != deltaPosition.y) {
velocity?.y = 0.0f onGround = false
velocity.y = 0.0f
if (deltaPosition.y < 0) { if (deltaPosition.y < 0) {
onGround = true onGround = true
} }
@ -242,56 +241,49 @@ abstract class Entity(
delta.x = collisionsToCheck.computeOffset(aabb, deltaPosition.x, Axes.X) delta.x = collisionsToCheck.computeOffset(aabb, deltaPosition.x, Axes.X)
aabb.offsetAssign(delta.x, 0f, 0f) aabb.offsetAssign(delta.x, 0f, 0f)
if (delta.x != deltaPosition.x) { if (delta.x != deltaPosition.x) {
velocity?.x = 0.0f velocity.x = 0.0f
} }
} }
if (delta.z != 0.0f) { if (delta.z != 0.0f) {
delta.z = collisionsToCheck.computeOffset(aabb, deltaPosition.z, Axes.Z) delta.z = collisionsToCheck.computeOffset(aabb, deltaPosition.z, Axes.Z)
aabb.offsetAssign(0f, 0f, delta.z) aabb.offsetAssign(0f, 0f, delta.z)
if (delta.z != deltaPosition.z) { if (delta.z != deltaPosition.z) {
velocity?.z = 0.0f velocity.z = 0.0f
} }
} }
if (delta.x != 0.0f && !xPriority) { if (delta.x != 0.0f && !xPriority) {
delta.x = collisionsToCheck.computeOffset(aabb, deltaPosition.x, Axes.X) delta.x = collisionsToCheck.computeOffset(aabb, deltaPosition.x, Axes.X)
if (delta.x != deltaPosition.x) { if (delta.x != deltaPosition.x) {
velocity?.x = 0.0f velocity.x = 0.0f
} }
} }
return delta return delta
} }
fun computeTimeStep(deltaMillis: Long) { fun computeTimeStep(deltaMillis: Long) {
val newVelocity = Vec3(velocity)
val oldVelocity = Vec3(velocity)
val deltaTime = deltaMillis.toFloat() / 1000.0f val deltaTime = deltaMillis.toFloat() / 1000.0f
if (!hasNoGravity && !isFlying) { if (!hasNoGravity && !isFlying) {
velocity?.let { newVelocity.y -= ProtocolDefinition.GRAVITY * deltaTime
it.y += deltaTime * ProtocolDefinition.GRAVITY
} ?: let {
velocity = Vec3(0, deltaTime * ProtocolDefinition.GRAVITY, 0)
} }
newVelocity *= 0.25f.pow(deltaTime) // apply
if (newVelocity.length() < 0.05f) {
newVelocity *= 0
} }
if (velocity == null) { if (velocity != oldVelocity) {
// the velocity has changed
computeTimeStep(deltaMillis)
return return
} }
if (velocity == VecUtil.EMPTY_VEC3) { velocity = newVelocity
velocity = null move(velocity * deltaTime)
}
velocity?.timesAssign(0.25f.pow(deltaTime))
velocity?.let {
if (it.length() < 0.05f) {
velocity = null
return
}
}
velocity?.let {
move(it * deltaTime, false)
}
} }
private val aabb: AABB private val aabb: AABB
get() = defaultAABB + position get() = defaultAABB + position
companion object { companion object {
val HITBOX_MARGIN = 1e-5 private const val HITBOX_MARGIN = 1e-5
} }
} }

View File

@ -48,8 +48,8 @@ class Camera(
val renderWindow: RenderWindow, val renderWindow: RenderWindow,
) : ScreenResizeCallback { ) : ScreenResizeCallback {
private var mouseSensitivity = Minosoft.getConfig().config.game.camera.moseSensitivity private var mouseSensitivity = Minosoft.getConfig().config.game.camera.moseSensitivity
private val walkingSpeed get() = connection.player.baseAbilities.walkingSpeed * ProtocolDefinition.TICKS_PER_SECOND private val walkingSpeed get() = connection.player.baseAbilities.walkingSpeed * ProtocolDefinition.TICKS_PER_SECOND * 2
private val flyingSpeed get() = connection.player.baseAbilities.flyingSpeed * ProtocolDefinition.TICKS_PER_SECOND private val flyingSpeed get() = connection.player.baseAbilities.flyingSpeed * ProtocolDefinition.TICKS_PER_SECOND * 2
var cameraPosition = Vec3(0.0f, 0.0f, 0.0f) var cameraPosition = Vec3(0.0f, 0.0f, 0.0f)
private var lastMouseX = 0.0 private var lastMouseX = 0.0
private var lastMouseY = 0.0 private var lastMouseY = 0.0
@ -173,12 +173,8 @@ class Camera(
} }
} else { } else {
if (playerEntity.onGround && renderWindow.inputHandler.isKeyBindingDown(KeyBindingsNames.MOVE_JUMP)) { if (playerEntity.onGround && renderWindow.inputHandler.isKeyBindingDown(KeyBindingsNames.MOVE_JUMP)) {
// TODO: jump delay, correct jump height, direction wrong? // TODO: jump delay, correct jump height
playerEntity.velocity?.let { playerEntity.velocity.y += 0.75f * ProtocolDefinition.GRAVITY
it.y += -0.75f * ProtocolDefinition.GRAVITY
} ?: run {
playerEntity.velocity = Vec3(0, -0.75f * ProtocolDefinition.GRAVITY, 0)
}
playerEntity.onGround = false playerEntity.onGround = false
} }
} }

View File

@ -95,14 +95,13 @@ public final class ProtocolDefinition {
public static final float VELOCITY_CONSTANT = (float) TICKS_PER_SECOND / 80f; public static final float VELOCITY_CONSTANT = (float) TICKS_PER_SECOND / 80f;
public static final float GRAVITY = -10; // TODO: find the correct value public static final float GRAVITY = 32;
public static final boolean FAST_MOVEMENT = true; public static final boolean FAST_MOVEMENT = true;
public static final int SEA_LEVEL_HEIGHT = 62; public static final int SEA_LEVEL_HEIGHT = 62;
public static final float HEIGHT_SEA_LEVEL_MODIFIER = 0.00166667f; public static final float HEIGHT_SEA_LEVEL_MODIFIER = 0.00166667f;
public static final ResourceLocation AIR_RESOURCE_LOCATION = new ResourceLocation("air"); public static final ResourceLocation AIR_RESOURCE_LOCATION = new ResourceLocation("air");
public static final RGBColor DEFAULT_COLOR = ChatColors.WHITE; public static final RGBColor DEFAULT_COLOR = ChatColors.WHITE;