abstract particles and entities in speedables

This commit is contained in:
Bixilon 2021-05-28 14:16:51 +02:00 committed by Lukas
parent e4b18cf250
commit 1f791378ec
4 changed files with 52 additions and 28 deletions

View File

@ -21,8 +21,10 @@ import de.bixilon.minosoft.data.inventory.InventorySlots.EquipmentSlots
import de.bixilon.minosoft.data.inventory.ItemStack
import de.bixilon.minosoft.data.mappings.effects.StatusEffect
import de.bixilon.minosoft.data.mappings.entities.EntityType
import de.bixilon.minosoft.data.physics.Speedable
import de.bixilon.minosoft.data.text.ChatComponent
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.VecUtil.blockPosition
import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
@ -36,9 +38,9 @@ import kotlin.math.pow
abstract class Entity(
protected val connection: PlayConnection,
val entityType: EntityType,
var position: Vec3,
override var position: Vec3,
var rotation: EntityRotation,
) {
) : Speedable {
val equipment: MutableMap<EquipmentSlots, ItemStack> = mutableMapOf()
val activeStatusEffects: MutableMap<StatusEffect, StatusEffectInstance> = synchronizedMapOf()
@ -48,12 +50,12 @@ abstract class Entity(
var entityMetaData: EntityMetaData = EntityMetaData(connection)
var velocity: Vec3 = Vec3()
override var velocity: Vec3 = Vec3.EMPTY
protected open val hasCollisions = true
protected open val isFlying = false
var onGround = false
override var onGround = false
private val defaultAABB = AABB(
Vec3(-(entityType.width / 2 + HITBOX_MARGIN), 0, -(entityType.width / 2 + HITBOX_MARGIN)),

View File

@ -42,21 +42,19 @@ class CollisionDetector(val connection: PlayConnection) {
return result
}
fun collide(entity: Entity?, deltaPosition: Vec3, collisionsToCheck: VoxelShape, aabb: AABB): Vec3 {
fun collide(speedable: Speedable, deltaPosition: Vec3, collisionsToCheck: VoxelShape, aabb: AABB): Vec3 {
val delta = Vec3(deltaPosition)
if (delta.y != 0.0f) {
delta.y = collisionsToCheck.computeOffset(aabb, deltaPosition.y, Axes.Y)
if (delta.y != deltaPosition.y) {
entity?.let {
it.onGround = false
it.velocity.y = 0.0f
if (deltaPosition.y < 0) {
it.onGround = true
}
speedable.onGround = false
speedable.velocity.y = 0.0f
if (deltaPosition.y < 0) {
speedable.onGround = true
}
aabb += Vec3(0f, delta.y, 0f)
} else if (delta.y < 0) {
entity?.let { it.onGround = false }
speedable.onGround = false
}
}
if ((deltaPosition.x != 0f || deltaPosition.z != 0f)) {
@ -74,21 +72,21 @@ class CollisionDetector(val connection: PlayConnection) {
delta.x = collisionsToCheck.computeOffset(aabb, deltaPosition.x, Axes.X)
aabb += Vec3(delta.x, 0f, 0f)
if (delta.x != deltaPosition.x) {
entity?.let { it.velocity.x = 0.0f }
speedable.velocity.x = 0.0f
}
}
if (delta.z != 0.0f) {
delta.z = collisionsToCheck.computeOffset(aabb, deltaPosition.z, Axes.Z)
aabb += Vec3(0f, 0f, delta.z)
if (delta.z != deltaPosition.z) {
entity?.let { it.velocity.z = 0.0f }
speedable.velocity.z = 0.0f
}
}
if (delta.x != 0.0f && !xPriority) {
delta.x = collisionsToCheck.computeOffset(aabb, deltaPosition.x, Axes.X)
// no need to offset the aabb any more, as it won't be used any more
if (delta.x != deltaPosition.x) {
entity?.let { it.velocity.x = 0.0f }
speedable.velocity.x = 0.0f
}
}
if (delta.length() > deltaPosition.length() + Entity.STEP_HEIGHT) {

View File

@ -0,0 +1,23 @@
/*
* Minosoft
* Copyright (C) 2021 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.physics
import glm_.vec3.Vec3
interface Speedable {
val position: Vec3
val velocity: Vec3
var onGround: Boolean
}

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.gui.rendering.particle.types
import de.bixilon.minosoft.data.mappings.particle.data.ParticleData
import de.bixilon.minosoft.data.physics.Speedable
import de.bixilon.minosoft.gui.rendering.chunk.models.AABB
import de.bixilon.minosoft.gui.rendering.particle.ParticleMesh
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
@ -26,16 +27,17 @@ import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.KUtil.millis
import glm_.vec3.Vec3
import kotlin.math.abs
import kotlin.math.sqrt
import kotlin.random.Random
abstract class Particle(
protected val connection: PlayConnection,
protected val particleRenderer: ParticleRenderer,
protected val position: Vec3,
protected val velocity: Vec3 = Vec3.EMPTY,
final override val position: Vec3,
final override val velocity: Vec3 = Vec3.EMPTY,
protected val data: ParticleData,
) {
) : Speedable {
protected val random = Random
var lastTickTime = -1L
@ -53,7 +55,8 @@ abstract class Particle(
var gravityStrength = 0.0f
// collisions
var onGround: Boolean = true
override var onGround: Boolean = true
var alreadyCollided = false
var accelerateIfYBlocked = false
var aabb: AABB = AABB.EMPTY
var spacing: Vec3 = Vec3.EMPTY
@ -86,24 +89,22 @@ abstract class Particle(
}
fun move(velocity: Vec3) {
if (alreadyCollided) {
return
}
var newVelocity = Vec3(velocity)
if (this.physics && newVelocity != Vec3.EMPTY) {
val aabb = aabb + position
val collisions = connection.collisionDetector.getCollisionsToCheck(newVelocity, aabb)
newVelocity = connection.collisionDetector.collide(null, newVelocity, collisions, aabb)
newVelocity = connection.collisionDetector.collide(this, newVelocity, collisions, aabb)
}
if (newVelocity != Vec3.EMPTY) {
position += newVelocity
}
onGround = (newVelocity.y != velocity.y) && velocity.y < 0.0f
if (newVelocity.x != velocity.x) {
this.velocity.x = 0.0f
}
if (newVelocity.z != velocity.z) {
this.velocity.z = 0.0f
if (abs(newVelocity.y) >= Y_VELOCITY_TO_CHECK && abs(velocity.y) < Y_VELOCITY_TO_CHECK) {
this.alreadyCollided = true
}
}
@ -187,8 +188,8 @@ abstract class Particle(
abstract fun addVertex(particleMesh: ParticleMesh)
companion object {
private const val MINIMUM_VELOCITY = 0.01f
private const val MAGIC_VELOCITY_CONSTANT = 0.4000000059604645
private const val MAGIC_VELOCITY_CONSTANTf = MAGIC_VELOCITY_CONSTANT.toFloat()
private const val Y_VELOCITY_TO_CHECK = 9.999999747378752E-6f
}
}