diff --git a/src/main/java/de/bixilon/minosoft/data/direction/Directions.kt b/src/main/java/de/bixilon/minosoft/data/direction/Directions.kt index 728120fa8..e9b25239c 100644 --- a/src/main/java/de/bixilon/minosoft/data/direction/Directions.kt +++ b/src/main/java/de/bixilon/minosoft/data/direction/Directions.kt @@ -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) { diff --git a/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt b/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt index ed3fba247..9af34dc63 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt @@ -204,8 +204,6 @@ abstract class Entity( preTick() tick() postTick() - } catch (error: Throwable) { - error.printStackTrace() } finally { lastTickTime = time lock.unlock() diff --git a/src/main/java/de/bixilon/minosoft/data/registries/shapes/aabb/AABB.kt b/src/main/java/de/bixilon/minosoft/data/registries/shapes/aabb/AABB.kt index cff3b76de..82143dcb0 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/shapes/aabb/AABB.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/shapes/aabb/AABB.kt @@ -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 { diff --git a/src/main/java/de/bixilon/minosoft/data/registries/shapes/aabb/AABBIterator.kt b/src/main/java/de/bixilon/minosoft/data/registries/shapes/aabb/AABBIterator.kt index fb6974314..d9c89217d 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/shapes/aabb/AABBIterator.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/shapes/aabb/AABBIterator.kt @@ -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 { diff --git a/src/main/java/de/bixilon/minosoft/data/world/vec/SVec3.kt b/src/main/java/de/bixilon/minosoft/data/world/vec/SVec3.kt index 589bfcb79..55f822a62 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/vec/SVec3.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/vec/SVec3.kt @@ -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 { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/Camera.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/Camera.kt index 97f02a071..217a6a2aa 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/Camera.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/Camera.kt @@ -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()) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/util/vec/vec3/Vec3dUtil.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/util/vec/vec3/Vec3dUtil.kt index 3b13dd4c4..3f2f8f8af 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/util/vec/vec3/Vec3dUtil.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/util/vec/vec3/Vec3dUtil.kt @@ -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) { diff --git a/src/main/java/de/bixilon/minosoft/physics/entities/EntityPhysics.kt b/src/main/java/de/bixilon/minosoft/physics/entities/EntityPhysics.kt index e63cc8ada..0d4abf035 100644 --- a/src/main/java/de/bixilon/minosoft/physics/entities/EntityPhysics.kt +++ b/src/main/java/de/bixilon/minosoft/physics/entities/EntityPhysics.kt @@ -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(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 diff --git a/src/main/java/de/bixilon/minosoft/physics/parts/OutOfBlockPusher.kt b/src/main/java/de/bixilon/minosoft/physics/parts/OutOfBlockPusher.kt index b2e1851fd..115f9673d 100644 --- a/src/main/java/de/bixilon/minosoft/physics/parts/OutOfBlockPusher.kt +++ b/src/main/java/de/bixilon/minosoft/physics/parts/OutOfBlockPusher.kt @@ -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 } diff --git a/src/main/java/de/bixilon/minosoft/physics/submersion/SubmersionState.kt b/src/main/java/de/bixilon/minosoft/physics/submersion/SubmersionState.kt index 6c1448e3c..d5b19609a 100644 --- a/src/main/java/de/bixilon/minosoft/physics/submersion/SubmersionState.kt +++ b/src/main/java/de/bixilon/minosoft/physics/submersion/SubmersionState.kt @@ -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) {