mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-16 10:55:01 -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")
|
@Deprecated("outsource")
|
||||||
fun byDirection(direction: Vec3): Directions {
|
fun byDirection(direction: Vec3): Directions {
|
||||||
var minDirection = VALUES[0]
|
var minDirection = VALUES[0]
|
||||||
var minError = 2.0f
|
var minError = 2.0f * 2.0f
|
||||||
for (testDirection in VALUES) {
|
for (testDirection in VALUES) {
|
||||||
val error = (testDirection.vectorf - direction).length()
|
val error = (testDirection.vectorf - direction).length2()
|
||||||
if (error < MIN_ERROR) {
|
if (error < MIN_ERROR) {
|
||||||
return testDirection
|
return testDirection
|
||||||
} else if (error < minError) {
|
} else if (error < minError) {
|
||||||
|
@ -204,8 +204,6 @@ abstract class Entity(
|
|||||||
preTick()
|
preTick()
|
||||||
tick()
|
tick()
|
||||||
postTick()
|
postTick()
|
||||||
} catch (error: Throwable) {
|
|
||||||
error.printStackTrace()
|
|
||||||
} finally {
|
} finally {
|
||||||
lastTickTime = time
|
lastTickTime = time
|
||||||
lock.unlock()
|
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.EMPTY
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.ONE
|
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.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.get
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.max
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.max
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.min
|
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 {
|
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 {
|
fun extend(vec3: Vec3d): AABB {
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.data.registries.shapes.aabb
|
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.World
|
||||||
import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
|
import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
|
||||||
import de.bixilon.minosoft.data.world.iterator.WorldIterator
|
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)
|
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(min: Vec3d, max: Vec3d, order: IterationOrder) : this(min.floor, max.ceil - 1, order)
|
||||||
constructor(aabb: AABB, order: IterationOrder) : this(aabb.min.floor, aabb.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))
|
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 {
|
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.Axes
|
||||||
import de.bixilon.minosoft.data.direction.DirectionVector
|
import de.bixilon.minosoft.data.direction.DirectionVector
|
||||||
import de.bixilon.minosoft.data.direction.Directions
|
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.data.world.vec.VecUtil.assertVec
|
||||||
import de.bixilon.minosoft.util.KUtil.format
|
import de.bixilon.minosoft.util.KUtil.format
|
||||||
|
|
||||||
@JvmInline
|
@JvmInline
|
||||||
value class SVec3(val raw: Int) {
|
value class SVec3(val raw: Int) : TextFormattable {
|
||||||
|
|
||||||
|
|
||||||
constructor() : this(0, 0, 0)
|
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)) {
|
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
|
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 {
|
companion object {
|
||||||
|
@ -47,7 +47,11 @@ class Camera(
|
|||||||
|
|
||||||
fun draw() {
|
fun draw() {
|
||||||
val entity = context.session.camera.entity
|
val entity = context.session.camera.entity
|
||||||
|
try {
|
||||||
(entity.attachment.getRootVehicle() ?: entity).tryTick() // TODO
|
(entity.attachment.getRootVehicle() ?: entity).tryTick() // TODO
|
||||||
|
} catch (error: Throwable) {
|
||||||
|
error.printStackTrace()
|
||||||
|
}
|
||||||
if (entity is LocalPlayerEntity) {
|
if (entity is LocalPlayerEntity) {
|
||||||
entity._draw(millis())
|
entity._draw(millis())
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.util.vec.vec3
|
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.Vec3
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3d
|
import de.bixilon.kotlinglm.vec3.Vec3d
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3i
|
import de.bixilon.kotlinglm.vec3.Vec3i
|
||||||
@ -59,6 +60,19 @@ object Vec3dUtil {
|
|||||||
return Vec3(floatArrayOf(array[0].toFloat(), array[1].toFloat(), array[2].toFloat()))
|
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 {
|
fun interpolateLinear(delta: Double, start: Vec3d, end: Vec3d): Vec3d {
|
||||||
if (delta <= 0.0) {
|
if (delta <= 0.0) {
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
package de.bixilon.minosoft.physics.entities
|
package de.bixilon.minosoft.physics.entities
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3d
|
import de.bixilon.kotlinglm.vec3.Vec3d
|
||||||
|
import de.bixilon.kutil.math.simple.IntMath.clamp
|
||||||
import de.bixilon.kutil.primitive.DoubleUtil
|
import de.bixilon.kutil.primitive.DoubleUtil
|
||||||
import de.bixilon.minosoft.data.direction.Directions
|
import de.bixilon.minosoft.data.direction.Directions
|
||||||
import de.bixilon.minosoft.data.entities.EntityRotation
|
import de.bixilon.minosoft.data.entities.EntityRotation
|
||||||
@ -104,10 +105,10 @@ open class EntityPhysics<E : Entity>(val entity: E) : BasicPhysicsEntity(), Abst
|
|||||||
|
|
||||||
fun getLandingPosition(): BlockPosition {
|
fun getLandingPosition(): BlockPosition {
|
||||||
val info = this.positionInfo
|
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 inChunk = position.inChunkPosition
|
||||||
val state = positionInfo.chunk?.get(inChunk)
|
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)
|
val down = positionInfo.chunk?.get(inChunk + Directions.DOWN)
|
||||||
// TODO: check if block is fence, fence gate or wall
|
// TODO: check if block is fence, fence gate or wall
|
||||||
// return down
|
// return down
|
||||||
|
@ -16,11 +16,11 @@ package de.bixilon.minosoft.physics.parts
|
|||||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
import de.bixilon.kotlinglm.vec2.Vec2d
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3d
|
import de.bixilon.kotlinglm.vec3.Vec3d
|
||||||
import de.bixilon.kutil.math.simple.DoubleMath.floor
|
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.Axes
|
||||||
import de.bixilon.minosoft.data.abilities.Gamemodes
|
import de.bixilon.minosoft.data.abilities.Gamemodes
|
||||||
import de.bixilon.minosoft.data.direction.Directions
|
import de.bixilon.minosoft.data.direction.Directions
|
||||||
import de.bixilon.minosoft.data.world.positions.BlockPosition
|
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
|
import de.bixilon.minosoft.physics.entities.living.player.local.LocalPlayerPhysics
|
||||||
|
|
||||||
object OutOfBlockPusher {
|
object OutOfBlockPusher {
|
||||||
@ -31,7 +31,7 @@ object OutOfBlockPusher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun LocalPlayerPhysics.pushOutOfBlocks(x: Double, z: Double) {
|
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)) {
|
if (!wouldCollidePushable(position)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.physics.submersion
|
package de.bixilon.minosoft.physics.submersion
|
||||||
|
|
||||||
|
import de.bixilon.kotlinglm.func.common.clamp
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3d
|
import de.bixilon.kotlinglm.vec3.Vec3d
|
||||||
import de.bixilon.kutil.math.simple.DoubleMath.floor
|
import de.bixilon.kutil.math.simple.DoubleMath.floor
|
||||||
import de.bixilon.minosoft.data.Tickable
|
import de.bixilon.minosoft.data.Tickable
|
||||||
@ -67,7 +68,7 @@ class SubmersionState(private val physics: EntityPhysics<*>) : Tickable {
|
|||||||
val totalVelocity = Vec3d.EMPTY
|
val totalVelocity = Vec3d.EMPTY
|
||||||
var count = 0
|
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?
|
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)
|
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
|
// TODO
|
||||||
}
|
}
|
||||||
val position = physics.position
|
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
|
val block = physics.positionInfo.chunk?.get(eyePosition.inChunkPosition) ?: return
|
||||||
if (block.block !is FluidHolder) {
|
if (block.block !is FluidHolder) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user