mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 02:15:34 -04:00
prevent crash when entity position is out of bounds (of block position)
This is not done well, clamping the position will introduce weird bugs in full height dimensions, because minosoft assumes that the position is still in the world.
This commit is contained in:
parent
f96047dbfe
commit
941b8c9f9c
@ -90,9 +90,9 @@ enum class Directions(
|
||||
@Deprecated("outsource")
|
||||
fun byDirection(direction: Vec3): Directions {
|
||||
var minDirection = VALUES[0]
|
||||
var minError = 2.0f
|
||||
var minError = 2.0f * 2.0f
|
||||
for (testDirection in VALUES) {
|
||||
val error = (testDirection.vectorf - direction).length()
|
||||
val error = (testDirection.vectorf - direction).length2()
|
||||
if (error < MIN_ERROR) {
|
||||
return testDirection
|
||||
} else if (error < minError) {
|
||||
|
@ -204,8 +204,6 @@ abstract class Entity(
|
||||
preTick()
|
||||
tick()
|
||||
postTick()
|
||||
} catch (error: Throwable) {
|
||||
error.printStackTrace()
|
||||
} finally {
|
||||
lastTickTime = time
|
||||
lock.unlock()
|
||||
|
@ -28,6 +28,7 @@ import de.bixilon.minosoft.data.world.positions.InSectionPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.ONE
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.toVec3
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.clampBlockPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.get
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.max
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.min
|
||||
@ -100,7 +101,7 @@ class AABB {
|
||||
}
|
||||
|
||||
fun positions(order: AABBIterator.IterationOrder = AABBIterator.IterationOrder.OPTIMIZED): AABBIterator {
|
||||
return AABBIterator(this, order)
|
||||
return AABBIterator(min.clampBlockPosition(), max.clampBlockPosition(), order)
|
||||
}
|
||||
|
||||
fun extend(vec3: Vec3d): AABB {
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
package de.bixilon.minosoft.data.registries.shapes.aabb
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3d
|
||||
import de.bixilon.minosoft.data.world.World
|
||||
import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
|
||||
import de.bixilon.minosoft.data.world.iterator.WorldIterator
|
||||
@ -30,8 +31,7 @@ class AABBIterator(
|
||||
|
||||
val size = maxOf(0, max.x - min.x + 1) * maxOf(0, max.y - min.y + 1) * maxOf(0, max.z - min.z + 1)
|
||||
|
||||
constructor(aabb: AABB) : this(aabb.min.floor, aabb.max.ceil - 1)
|
||||
constructor(aabb: AABB, order: IterationOrder) : this(aabb.min.floor, aabb.max.ceil - 1, order)
|
||||
constructor(min: Vec3d, max: Vec3d, order: IterationOrder) : this(min.floor, max.ceil - 1, order)
|
||||
constructor(minX: Int, minY: Int, minZ: Int, maxX: Int, maxY: Int, maxZ: Int) : this(BlockPosition(minX, minY, minZ), BlockPosition(maxX, maxY, maxZ))
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
|
@ -16,12 +16,13 @@ package de.bixilon.minosoft.data.world.vec
|
||||
import de.bixilon.minosoft.data.Axes
|
||||
import de.bixilon.minosoft.data.direction.DirectionVector
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.text.BaseComponent
|
||||
import de.bixilon.minosoft.data.text.formatting.TextFormattable
|
||||
import de.bixilon.minosoft.data.world.vec.VecUtil.assertVec
|
||||
import de.bixilon.minosoft.util.KUtil.format
|
||||
|
||||
@JvmInline
|
||||
value class SVec3(val raw: Int) {
|
||||
|
||||
value class SVec3(val raw: Int) : TextFormattable {
|
||||
|
||||
constructor() : this(0, 0, 0)
|
||||
constructor(x: Int, y: Int, z: Int) : this(((y and MASK_Y) shl SHIFT_Y) or ((z and MASK_Z) shl SHIFT_Z) or ((x and MASK_X) shl SHIFT_X)) {
|
||||
@ -103,7 +104,16 @@ value class SVec3(val raw: Int) {
|
||||
Axes.Z -> z
|
||||
}
|
||||
|
||||
override fun toString() = "(${this.x.format()} ${this.y.format()} ${this.z.format()})"
|
||||
override fun toString() = "(${this.x} ${this.y} ${this.z})"
|
||||
override fun toText() = BaseComponent().apply {
|
||||
this += "("
|
||||
this += x.format()
|
||||
this += " "
|
||||
this += y.format()
|
||||
this += " "
|
||||
this += z.format()
|
||||
this += ")"
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
|
@ -47,7 +47,11 @@ class Camera(
|
||||
|
||||
fun draw() {
|
||||
val entity = context.session.camera.entity
|
||||
(entity.attachment.getRootVehicle() ?: entity).tryTick() // TODO
|
||||
try {
|
||||
(entity.attachment.getRootVehicle() ?: entity).tryTick() // TODO
|
||||
} catch (error: Throwable) {
|
||||
error.printStackTrace()
|
||||
}
|
||||
if (entity is LocalPlayerEntity) {
|
||||
entity._draw(millis())
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.util.vec.vec3
|
||||
|
||||
import de.bixilon.kotlinglm.func.common.clamp
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.kotlinglm.vec3.Vec3d
|
||||
import de.bixilon.kotlinglm.vec3.Vec3i
|
||||
@ -59,6 +60,19 @@ object Vec3dUtil {
|
||||
return Vec3(floatArrayOf(array[0].toFloat(), array[1].toFloat(), array[2].toFloat()))
|
||||
}
|
||||
|
||||
private fun Double.clamp(min: Int, max: Int) = clamp(min.toDouble(), max.toDouble())
|
||||
|
||||
fun Vec3d.clampBlockPosition(): Vec3d { // TODO: remove +1/-1. AABBIterator otherwise crashes when subtracting one
|
||||
val x = x.clamp(-BlockPosition.MAX_X + 1, BlockPosition.MAX_X - 1)
|
||||
val y = y.clamp(+BlockPosition.MIN_Y + 1, BlockPosition.MAX_Y - 1)
|
||||
val z = z.clamp(-BlockPosition.MAX_Z + 1, BlockPosition.MAX_Z - 1)
|
||||
|
||||
if (x != this.x || y != this.y || this.z != z) {
|
||||
return Vec3d(x, y, z)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
fun interpolateLinear(delta: Double, start: Vec3d, end: Vec3d): Vec3d {
|
||||
if (delta <= 0.0) {
|
||||
|
@ -14,6 +14,7 @@
|
||||
package de.bixilon.minosoft.physics.entities
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3d
|
||||
import de.bixilon.kutil.math.simple.IntMath.clamp
|
||||
import de.bixilon.kutil.primitive.DoubleUtil
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.entities.EntityRotation
|
||||
@ -104,10 +105,10 @@ open class EntityPhysics<E : Entity>(val entity: E) : BasicPhysicsEntity(), Abst
|
||||
|
||||
fun getLandingPosition(): BlockPosition {
|
||||
val info = this.positionInfo
|
||||
val position = BlockPosition(info.position.x, (position.y - 0.2).toInt(), info.position.z) // TODO: can y get below 0?
|
||||
val position = BlockPosition(info.position.x, (position.y - 0.2).toInt().clamp(BlockPosition.MIN_Y, BlockPosition.MAX_Y), info.position.z) // TODO: can y get below 0?
|
||||
val inChunk = position.inChunkPosition
|
||||
val state = positionInfo.chunk?.get(inChunk)
|
||||
if (state == null) {
|
||||
if (state == null && inChunk.y > BlockPosition.MIN_Y) {
|
||||
val down = positionInfo.chunk?.get(inChunk + Directions.DOWN)
|
||||
// TODO: check if block is fence, fence gate or wall
|
||||
// return down
|
||||
|
@ -16,11 +16,11 @@ package de.bixilon.minosoft.physics.parts
|
||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
||||
import de.bixilon.kotlinglm.vec3.Vec3d
|
||||
import de.bixilon.kutil.math.simple.DoubleMath.floor
|
||||
import de.bixilon.kutil.math.simple.IntMath.clamp
|
||||
import de.bixilon.minosoft.data.Axes
|
||||
import de.bixilon.minosoft.data.abilities.Gamemodes
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.world.positions.BlockPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.get
|
||||
import de.bixilon.minosoft.physics.entities.living.player.local.LocalPlayerPhysics
|
||||
|
||||
object OutOfBlockPusher {
|
||||
@ -31,7 +31,7 @@ object OutOfBlockPusher {
|
||||
}
|
||||
|
||||
private fun LocalPlayerPhysics.pushOutOfBlocks(x: Double, z: Double) {
|
||||
val position = BlockPosition(x.floor, this.position.y.floor, z.floor)
|
||||
val position = BlockPosition(x.floor, this.position.y.floor.clamp(BlockPosition.MIN_Y, BlockPosition.MAX_Y), z.floor)
|
||||
if (!wouldCollidePushable(position)) {
|
||||
return
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
package de.bixilon.minosoft.physics.submersion
|
||||
|
||||
import de.bixilon.kotlinglm.func.common.clamp
|
||||
import de.bixilon.kotlinglm.vec3.Vec3d
|
||||
import de.bixilon.kutil.math.simple.DoubleMath.floor
|
||||
import de.bixilon.minosoft.data.Tickable
|
||||
@ -67,7 +68,7 @@ class SubmersionState(private val physics: EntityPhysics<*>) : Tickable {
|
||||
val totalVelocity = Vec3d.EMPTY
|
||||
var count = 0
|
||||
|
||||
for ((position, state, chunk) in WorldIterator(aabb.positions(), world, physics.positionInfo.chunk)) {
|
||||
for ((position, state, chunk) in WorldIterator(aabb, world, physics.positionInfo.chunk)) {
|
||||
if (!fluid.matches(state)) continue // TODO: tags?
|
||||
|
||||
val height = position.y + if (fluid.matches(chunk[position.inChunkPosition + Directions.UP])) 1.0f else fluid.getHeight(state)
|
||||
@ -147,7 +148,7 @@ class SubmersionState(private val physics: EntityPhysics<*>) : Tickable {
|
||||
// TODO
|
||||
}
|
||||
val position = physics.position
|
||||
val eyePosition = BlockPosition(position.x.floor, eyeHeight.floor, position.z.floor)
|
||||
val eyePosition = BlockPosition(position.x.floor, eyeHeight.floor.clamp(BlockPosition.MIN_Y, BlockPosition.MAX_Y), position.z.floor)
|
||||
|
||||
val block = physics.positionInfo.chunk?.get(eyePosition.inChunkPosition) ?: return
|
||||
if (block.block !is FluidHolder) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user