diff --git a/build.gradle.kts b/build.gradle.kts
index 4c6b7bd1f..8d1c526dc 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -52,6 +52,8 @@ val kutilVersion = getProperty("kutil.version")
val os = properties["platform"]?.let { OSTypes[it] } ?: PlatformInfo.OS
val architecture = properties["architecture"]?.let { Architectures[it] } ?: PlatformInfo.ARCHITECTURE
+logger.info("Building for ${os.name.lowercase()}, ${architecture.name.lowercase()}")
+
repositories {
mavenCentral()
maven("https://oss.sonatype.org/content/repositories/snapshots")
diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/camera/target/TargetHandlerTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/camera/target/TargetHandlerTest.kt
index 48313c1e3..32679918e 100644
--- a/src/integration-test/kotlin/de/bixilon/minosoft/camera/target/TargetHandlerTest.kt
+++ b/src/integration-test/kotlin/de/bixilon/minosoft/camera/target/TargetHandlerTest.kt
@@ -13,7 +13,6 @@
package de.bixilon.minosoft.camera.target
-import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.kutil.observer.DataObserver
@@ -24,7 +23,6 @@ import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.data.physics.PhysicsTestUtil.createPlayer
import de.bixilon.minosoft.data.registries.blocks.DirtTest0
import de.bixilon.minosoft.data.registries.blocks.types.stone.StoneTest0
-import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3
import de.bixilon.minosoft.protocol.network.connection.play.ConnectionTestUtil.createConnection
import org.testng.Assert.*
import org.testng.annotations.Test
@@ -44,7 +42,7 @@ class TargetHandlerTest {
connection.world[7, 69, 6] = DirtTest0.state
connection.world[8, 69, 6] = StoneTest0.state
- player.renderInfo::eyePosition.forceSet(player.physics.position.toVec3 + Vec3(0.0, 1.5, 0.0))
+ player.renderInfo::eyePosition.forceSet(player.physics.position + Vec3d(0.0, 1.5, 0.0))
player.renderInfo::rotation.forceSet(player.physics.rotation)
connection.camera.target.update()
@@ -68,7 +66,7 @@ class TargetHandlerTest {
connection.world[8, 70, 2] = StoneTest0.state
- player.renderInfo::eyePosition.forceSet(player.physics.position.toVec3 + Vec3(0.0, 1.5, 0.0))
+ player.renderInfo::eyePosition.forceSet(player.physics.position + Vec3d(0.0, 1.5, 0.0))
player.renderInfo::rotation.forceSet(player.physics.rotation)
connection.camera.target.update()
@@ -92,7 +90,7 @@ class TargetHandlerTest {
connection.world[9, 70, 2] = StoneTest0.state
- player.renderInfo::eyePosition.forceSet(player.physics.position.toVec3 + Vec3(0.0, 1.5, 0.0))
+ player.renderInfo::eyePosition.forceSet(player.physics.position + Vec3d(0.0, 1.5, 0.0))
player.renderInfo::rotation.forceSet(player.physics.rotation)
connection.camera.target.update()
diff --git a/src/main/java/de/bixilon/minosoft/data/entities/EntityRenderInfo.kt b/src/main/java/de/bixilon/minosoft/data/entities/EntityRenderInfo.kt
index be8640a86..852ba9672 100644
--- a/src/main/java/de/bixilon/minosoft/data/entities/EntityRenderInfo.kt
+++ b/src/main/java/de/bixilon/minosoft/data/entities/EntityRenderInfo.kt
@@ -13,23 +13,23 @@
package de.bixilon.minosoft.data.entities
-import de.bixilon.kotlinglm.vec3.Vec3
+import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kutil.math.interpolation.FloatInterpolation.interpolateLinear
import de.bixilon.minosoft.data.Tickable
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.data.registries.shapes.aabb.AABB
import de.bixilon.minosoft.gui.rendering.renderer.drawable.Drawable
-import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util
-import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.blockPosition
+import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil
+import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.blockPosition
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
class EntityRenderInfo(private val entity: Entity) : Drawable, Tickable {
- private var position0 = Vec3(entity.physics.position)
+ private var position0 = Vec3d(entity.physics.position)
private var position1 = position0
- var position: Vec3 = position0
+ var position: Vec3d = position0
private set
- var eyePosition: Vec3 = position
+ var eyePosition: Vec3d = position
private set
var cameraAABB: AABB = AABB.EMPTY
private set
@@ -44,8 +44,8 @@ class EntityRenderInfo(private val entity: Entity) : Drawable, Tickable {
private fun interpolatePosition(delta: Float) {
// TODO: Only interpolate if changed
- position = Vec3Util.interpolateLinear(delta, position0, position1)
- eyePosition = position + Vec3(0.0f, entity.eyeHeight, 0.0f)
+ position = Vec3dUtil.interpolateLinear(delta.toDouble(), position0, position1)
+ eyePosition = position + Vec3d(0.0, entity.eyeHeight, 0.0)
cameraAABB = entity.defaultAABB + position
eyeBlockPosition = position1.blockPosition
}
@@ -62,7 +62,7 @@ class EntityRenderInfo(private val entity: Entity) : Drawable, Tickable {
override fun tick() {
position0 = position1
- position1 = Vec3(entity.physics.position)
+ position1 = Vec3d(entity.physics.position)
rotation0 = rotation1
rotation1 = entity.physics.rotation
diff --git a/src/main/java/de/bixilon/minosoft/data/world/World.kt b/src/main/java/de/bixilon/minosoft/data/world/World.kt
index f6384f338..8e16a1231 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/World.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/World.kt
@@ -239,7 +239,7 @@ class World(
}
companion object {
- const val MAX_SIZE = 29999999
+ const val MAX_SIZE = 30_000_000
const val MAX_SIZEf = MAX_SIZE.toFloat()
const val MAX_SIZEd = MAX_SIZE.toDouble()
const val MAX_RENDER_DISTANCE = 64
diff --git a/src/main/java/de/bixilon/minosoft/data/world/audio/AbstractAudioPlayer.kt b/src/main/java/de/bixilon/minosoft/data/world/audio/AbstractAudioPlayer.kt
index c164467a4..a2073cbf5 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/audio/AbstractAudioPlayer.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/audio/AbstractAudioPlayer.kt
@@ -13,21 +13,21 @@
package de.bixilon.minosoft.data.world.audio
-import de.bixilon.kotlinglm.vec3.Vec3
+import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
-import de.bixilon.minosoft.gui.rendering.util.VecUtil.centerf
+import de.bixilon.minosoft.gui.rendering.util.VecUtil.center
interface AbstractAudioPlayer {
fun playSoundEvent(sound: ResourceLocation, position: Vec3i? = null, volume: Float = 1.0f, pitch: Float = 1.0f) {
- playSound(sound, position?.centerf, volume, pitch)
+ playSound(sound, position?.center, volume, pitch)
}
- fun playSound(sound: ResourceLocation, position: Vec3? = null, volume: Float = 1.0f, pitch: Float = 1.0f)
+ fun playSound(sound: ResourceLocation, position: Vec3d? = null, volume: Float = 1.0f, pitch: Float = 1.0f)
fun play2DSound(sound: ResourceLocation, volume: Float = 1.0f, pitch: Float = 1.0f) {
- playSound(sound, null as Vec3?, volume, pitch)
+ playSound(sound, null as Vec3d?, volume, pitch)
}
fun stopAllSounds()
diff --git a/src/main/java/de/bixilon/minosoft/data/world/audio/WorldAudioPlayer.kt b/src/main/java/de/bixilon/minosoft/data/world/audio/WorldAudioPlayer.kt
index 3cd49f834..0d4d093cd 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/audio/WorldAudioPlayer.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/audio/WorldAudioPlayer.kt
@@ -13,14 +13,14 @@
package de.bixilon.minosoft.data.world.audio
-import de.bixilon.kotlinglm.vec3.Vec3
+import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
@Deprecated("")
interface WorldAudioPlayer : AbstractAudioPlayer {
val audioPlayer: AbstractAudioPlayer?
- override fun playSound(sound: ResourceLocation, position: Vec3?, volume: Float, pitch: Float) {
+ override fun playSound(sound: ResourceLocation, position: Vec3d?, volume: Float, pitch: Float) {
audioPlayer?.playSound(sound, position, volume, pitch)
}
diff --git a/src/main/java/de/bixilon/minosoft/data/world/border/WorldBorder.kt b/src/main/java/de/bixilon/minosoft/data/world/border/WorldBorder.kt
index 15830ac0c..dc94f97b5 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/border/WorldBorder.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/border/WorldBorder.kt
@@ -14,57 +14,42 @@
package de.bixilon.minosoft.data.world.border
import de.bixilon.kotlinglm.vec2.Vec2d
-import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kotlinglm.vec3.Vec3i
-import de.bixilon.kutil.concurrent.lock.simple.SimpleLock
-import de.bixilon.kutil.math.interpolation.DoubleInterpolation.interpolateLinear
-import de.bixilon.kutil.time.TimeUtil
-import de.bixilon.kutil.time.TimeUtil.millis
import de.bixilon.minosoft.data.world.World
+import de.bixilon.minosoft.data.world.border.area.BorderArea
+import de.bixilon.minosoft.data.world.border.area.DynamicBorderArea
+import de.bixilon.minosoft.data.world.border.area.StaticBorderArea
import de.bixilon.minosoft.data.world.positions.BlockPosition
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2dUtil.EMPTY
+import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import kotlin.math.abs
class WorldBorder {
var center = Vec2d.EMPTY
- var diameter = DEFAULT_DIAMETER
var warningTime = 0
var warningBlocks = 0
var portalBound = 0
- var state = WorldBorderState.STATIC
- private set
-
- private var interpolationStart = -1L
- private var interpolationEnd = -1L
- private var oldDiameter = DEFAULT_DIAMETER
- private var newDiameter = DEFAULT_DIAMETER
-
- val lock = SimpleLock()
+ var area: BorderArea = StaticBorderArea(MAX_RADIUS)
fun isOutside(blockPosition: Vec3i): Boolean {
return isOutside(blockPosition.x.toDouble(), blockPosition.z.toDouble()) && isOutside(blockPosition.x + 1.0, blockPosition.z + 1.0)
}
- fun isOutside(position: Vec3): Boolean {
- return isOutside(position.x.toDouble(), position.z.toDouble())
- }
-
fun isOutside(position: Vec3d): Boolean {
return isOutside(position.x, position.z)
}
fun isOutside(x: Double, z: Double): Boolean {
- lock.acquire()
- val radius = diameter / 2
- val inside = x in (center.x - radius)..(radius + center.x) && z in (center.y - radius)..(radius + center.y)
- lock.release()
+ val center = center
+ val radius = area.radius
+ val inside = x in maxOf(-MAX_RADIUS, center.x - radius)..minOf(MAX_RADIUS, center.x + radius) && z in maxOf(-MAX_RADIUS, center.y - radius)..minOf(MAX_RADIUS, center.y + radius)
return !inside
}
- operator fun contains(position:BlockPosition) = !isOutside(position)
+ operator fun contains(position: BlockPosition) = !isOutside(position)
operator fun contains(position: Vec3d) = !isOutside(position)
@@ -73,76 +58,32 @@ class WorldBorder {
}
fun getDistanceTo(x: Double, z: Double): Double {
- lock.acquire()
- val radius = diameter / 2
+ val center = center
+ val radius = area.radius
- val closestDistance = minOf(
- radius - abs(x) - abs(center.x),
- radius - abs(z) - abs(center.y),
+ return minOf(
+ minOf(MAX_RADIUS, radius - abs(center.x)) - abs(x),
+ minOf(MAX_RADIUS, radius - abs(center.y)) - abs(z),
)
- lock.release()
- return closestDistance
}
- fun stopInterpolating() {
- lock.lock()
- interpolationStart = -1L
- lock.unlock()
- }
-
- fun interpolate(oldDiameter: Double, newDiameter: Double, millis: Long) {
- if (millis == 0L) {
- stopInterpolating()
- diameter = newDiameter
+ fun interpolate(oldRadius: Double, newRadius: Double, millis: Long) {
+ if (millis <= 0L || oldRadius == newRadius) {
+ area = StaticBorderArea(newRadius)
+ return
}
- lock.lock()
- val time = millis()
- interpolationStart = time
- interpolationEnd = time + millis
- this.oldDiameter = oldDiameter
- this.newDiameter = newDiameter
- lock.unlock()
+ area = DynamicBorderArea(this, oldRadius, newRadius, millis)
}
fun tick() {
- lock.lock()
- if (interpolationStart < 0L) {
- lock.unlock()
- return
- }
- val time = millis()
- if (interpolationEnd <= time) {
- state = WorldBorderState.STATIC
- interpolationStart = -1L
- lock.unlock()
- return
- }
- val oldDiameter = diameter
-
- val remaining = interpolationEnd - time
- val totalTime = (interpolationEnd - interpolationStart)
- val diameter = interpolateLinear(remaining.toDouble() / totalTime.toDouble(), this.newDiameter, this.oldDiameter)
- this.diameter = diameter
-
- state = if (oldDiameter > diameter) {
- WorldBorderState.SHRINKING
- } else if (oldDiameter < diameter) {
- WorldBorderState.GROWING
- } else {
- interpolationStart = -1L
- WorldBorderState.STATIC
- }
- lock.unlock()
+ area.tick()
}
fun reset() {
- lock.lock()
- diameter = DEFAULT_DIAMETER
- interpolationStart = -1L
- lock.unlock()
+ area = StaticBorderArea(MAX_RADIUS)
}
companion object {
- const val DEFAULT_DIAMETER = World.MAX_SIZE.toDouble() * 2
+ const val MAX_RADIUS = (World.MAX_SIZE - ProtocolDefinition.SECTION_WIDTH_X).toDouble()
}
}
diff --git a/src/main/java/de/bixilon/minosoft/data/world/border/area/BorderArea.kt b/src/main/java/de/bixilon/minosoft/data/world/border/area/BorderArea.kt
new file mode 100644
index 000000000..c7e692ae4
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/data/world/border/area/BorderArea.kt
@@ -0,0 +1,27 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020-2023 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 .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.data.world.border.area
+
+import de.bixilon.kutil.time.TimeUtil.millis
+import de.bixilon.minosoft.data.Tickable
+import de.bixilon.minosoft.data.world.border.WorldBorderState
+
+interface BorderArea : Tickable {
+ val radius: Double
+
+ val state: WorldBorderState
+
+
+ fun radius(time: Long = millis()): Double = radius
+}
diff --git a/src/main/java/de/bixilon/minosoft/data/world/border/area/DynamicBorderArea.kt b/src/main/java/de/bixilon/minosoft/data/world/border/area/DynamicBorderArea.kt
new file mode 100644
index 000000000..c34c07000
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/data/world/border/area/DynamicBorderArea.kt
@@ -0,0 +1,57 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020-2023 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 .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.data.world.border.area
+
+import de.bixilon.kutil.math.interpolation.DoubleInterpolation.interpolateLinear
+import de.bixilon.kutil.time.TimeUtil.millis
+import de.bixilon.minosoft.data.world.border.WorldBorder
+import de.bixilon.minosoft.data.world.border.WorldBorderState
+
+class DynamicBorderArea(
+ val border: WorldBorder,
+ val oldRadius: Double,
+ val newRadius: Double,
+ val millis: Long,
+) : BorderArea {
+ val start: Long = millis()
+ val end = start + millis
+
+ override var state: WorldBorderState = state()
+ override var radius: Double = oldRadius
+
+ override fun radius(time: Long): Double {
+ return interpolateLinear(progress(time), oldRadius, newRadius)
+ }
+
+ private fun progress(time: Long): Double {
+ return (time - start).toDouble() / (end - start)
+ }
+
+ override fun tick() {
+ val time = millis()
+ if (end <= time) {
+ border.area = StaticBorderArea(newRadius)
+ return
+ }
+
+ this.radius = interpolateLinear(progress(time), this.oldRadius, this.newRadius)
+ this.state = state()
+ }
+
+ private fun state() = when {
+ oldRadius > newRadius -> WorldBorderState.SHRINKING
+ oldRadius < newRadius -> WorldBorderState.GROWING
+ else -> WorldBorderState.STATIC // impossible?
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/data/world/border/area/StaticBorderArea.kt b/src/main/java/de/bixilon/minosoft/data/world/border/area/StaticBorderArea.kt
new file mode 100644
index 000000000..8f904cd90
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/data/world/border/area/StaticBorderArea.kt
@@ -0,0 +1,24 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020-2023 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 .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.data.world.border.area
+
+import de.bixilon.minosoft.data.world.border.WorldBorderState
+
+class StaticBorderArea(
+ override val radius: Double,
+) : BorderArea {
+ override val state: WorldBorderState get() = WorldBorderState.STATIC
+
+ override fun tick() = Unit
+}
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 346fa5ac6..66100a1fb 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
@@ -31,6 +31,7 @@ class Camera(
val view = ViewManager(this)
+ val offset = WorldOffset(this)
fun init() {
matrixHandler.init()
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/MatrixHandler.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/MatrixHandler.kt
index 7cf128de4..04f23479b 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/MatrixHandler.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/MatrixHandler.kt
@@ -32,7 +32,7 @@ import de.bixilon.minosoft.gui.rendering.events.ResizeWindowEvent
import de.bixilon.minosoft.gui.rendering.shader.types.CameraPositionShader
import de.bixilon.minosoft.gui.rendering.shader.types.ViewProjectionShader
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
-import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.blockPosition
+import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.blockPosition
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.chunkPosition
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.sectionHeight
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
@@ -45,9 +45,9 @@ class MatrixHandler(
private val connection = context.connection
private val profile = context.connection.profiles.rendering.camera
val shaking = CameraShaking(camera, profile.shaking)
- val frustum = Frustum(this, connection.world)
+ val frustum = Frustum(camera, this, connection.world)
- private var eyePosition = Vec3.EMPTY
+ private var matrixPosition = Vec3.EMPTY
private var previousFOV = 0.0f
private var front = Vec3.EMPTY
@@ -113,11 +113,13 @@ class MatrixHandler(
val fov = calculateFOV()
val view = camera.view.view
val eyePosition = view.eyePosition
+ context.camera.offset.draw()
+ val matrixPosition = Vec3(eyePosition - context.camera.offset.offset)
val front = view.front
- if (upToDate && eyePosition == this.eyePosition && front == this.front && fov == previousFOV && shaking.isEmpty) {
+ if (upToDate && matrixPosition == this.matrixPosition && front == this.front && fov == previousFOV && shaking.isEmpty) {
return
}
- this.eyePosition = eyePosition
+ this.matrixPosition = matrixPosition
this.front = front
val cameraBlockPosition = eyePosition.blockPosition
if (fov != previousFOV) {
@@ -126,17 +128,18 @@ class MatrixHandler(
previousFOV = fov
updateFront(front)
- updateViewMatrix(eyePosition, front)
+ updateViewMatrix(matrixPosition, front)
updateViewProjectionMatrix()
- val usePosition = if (view.updateFrustum) eyePosition else connection.camera.entity.renderInfo.eyePosition
+ val useMatrixPosition = if (view.updateFrustum) matrixPosition else Vec3(connection.camera.entity.renderInfo.eyePosition - camera.offset.offset)
+ val useEyePosition = if (view.updateFrustum) eyePosition else connection.camera.entity.renderInfo.eyePosition
if (view.updateFrustum) {
frustum.recalculate()
camera.visibilityGraph.updateCamera(cameraBlockPosition.chunkPosition, cameraBlockPosition.sectionHeight)
}
- connection.events.fire(CameraPositionChangeEvent(context, usePosition))
+ connection.events.fire(CameraPositionChangeEvent(context, useEyePosition))
connection.events.fire(
CameraMatrixChangeEvent(
@@ -147,7 +150,7 @@ class MatrixHandler(
)
)
- updateShaders(usePosition)
+ updateShaders(useMatrixPosition)
upToDate = true
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/WorldOffset.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/WorldOffset.kt
new file mode 100644
index 000000000..5cd8c7547
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/WorldOffset.kt
@@ -0,0 +1,48 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020-2023 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 .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.gui.rendering.camera
+
+import de.bixilon.kotlinglm.vec3.Vec3i
+import de.bixilon.kutil.observer.DataObserver.Companion.observed
+import de.bixilon.minosoft.data.world.World
+import de.bixilon.minosoft.gui.rendering.renderer.drawable.Drawable
+import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.blockPosition
+import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.EMPTY
+import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
+
+class WorldOffset(private val camera: Camera) : Drawable {
+ var offset by observed(Vec3i.EMPTY)
+ private set
+
+ override fun draw() {
+ val blockPosition = camera.view.view.eyePosition.blockPosition
+
+ val previous = offset / MAX_DISTANCE
+ val maxOffset = (blockPosition + THRESHOLD) / MAX_DISTANCE
+ val minOffset = (blockPosition - THRESHOLD) / MAX_DISTANCE
+ if (maxOffset == previous || minOffset == previous) {
+ // we need to get away further
+ // this makes the "border" not just 1 pixel wide, it is 256 blocks wide
+ return
+ }
+ this.offset = (blockPosition / MAX_DISTANCE) * MAX_DISTANCE
+ // Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Offset changed: $offset" }
+ }
+
+
+ companion object {
+ const val MAX_DISTANCE = World.MAX_RENDER_DISTANCE * ProtocolDefinition.SECTION_WIDTH_X // coordinates higher than that value are not allowed
+ const val THRESHOLD = (World.MAX_RENDER_DISTANCE / 8) * ProtocolDefinition.SECTION_WIDTH_X // only if value is lower that that value coordinates will be back offset
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/frustum/Frustum.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/frustum/Frustum.kt
index eb3a8dcb7..3e2116006 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/frustum/Frustum.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/frustum/Frustum.kt
@@ -25,6 +25,7 @@ import de.bixilon.kutil.enums.ValuesEnum
import de.bixilon.minosoft.data.registries.shapes.aabb.AABB
import de.bixilon.minosoft.data.world.World
import de.bixilon.minosoft.gui.rendering.RenderConstants
+import de.bixilon.minosoft.gui.rendering.camera.Camera
import de.bixilon.minosoft.gui.rendering.camera.MatrixHandler
import de.bixilon.minosoft.gui.rendering.util.VecUtil.of
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.EMPTY
@@ -33,6 +34,7 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
// Big thanks to: https://gist.github.com/podgorskiy/e698d18879588ada9014768e3e82a644
class Frustum(
+ private val camera: Camera,
private val matrixHandler: MatrixHandler,
private val world: World,
) {
@@ -152,7 +154,8 @@ class Frustum(
}
fun containsChunkSection(chunkPosition: Vec2i, sectionHeight: Int, minPosition: Vec3i = CHUNK_NIN_POSITION, maxPosition: Vec3i = ProtocolDefinition.CHUNK_SECTION_SIZE): Boolean {
- val base = Vec3i.of(chunkPosition, sectionHeight)
+ val offset = camera.offset.offset
+ val base = Vec3i.of(chunkPosition, sectionHeight) - offset
val min = base + minPosition
val max = base + maxPosition + 1
return containsRegion(Vec3(min), Vec3(max))
@@ -160,18 +163,21 @@ class Frustum(
fun containsChunk(chunkPosition: Vec2i): Boolean {
val dimension = world.dimension
- val minY = dimension.minY
- val maxY = dimension.maxY
- val base = Vec2i(chunkPosition.x * ProtocolDefinition.SECTION_WIDTH_X, chunkPosition.y * ProtocolDefinition.SECTION_WIDTH_Z)
+ val offset = camera.offset.offset
+ val minY = dimension.minY - offset.y
+ val maxY = dimension.maxY - offset.y
+ val base = Vec2i(chunkPosition.x * ProtocolDefinition.SECTION_WIDTH_X - offset.x, chunkPosition.y * ProtocolDefinition.SECTION_WIDTH_Z - offset.z)
return containsRegion(Vec3(base.x, minY, base.y), Vec3(base.x + ProtocolDefinition.SECTION_WIDTH_X, maxY, base.y + ProtocolDefinition.SECTION_WIDTH_Z))
}
fun containsRegion(min: Vec3i, max: Vec3i): Boolean {
- return containsRegion(Vec3(min), Vec3(max))
+ val offset = camera.offset.offset
+ return containsRegion(Vec3(min - offset), Vec3(max - offset))
}
fun containsAABB(aabb: AABB): Boolean {
- return containsRegion(Vec3(aabb.min), Vec3(aabb.max))
+ val offset = camera.offset.offset
+ return containsRegion(Vec3(aabb.min - offset), Vec3(aabb.max - offset))
}
private data class FrustumData(val normals: Array, val planes: Array)
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/view/CameraView.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/view/CameraView.kt
index 228aab6e4..5e3371634 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/view/CameraView.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/view/CameraView.kt
@@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.camera.view
import de.bixilon.kotlinglm.vec2.Vec2d
import de.bixilon.kotlinglm.vec3.Vec3
+import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.input.camera.MovementInputActions
@@ -30,7 +31,7 @@ interface CameraView {
val updateFrustum: Boolean get() = true
- val eyePosition: Vec3
+ val eyePosition: Vec3d
val rotation: EntityRotation
val front: Vec3
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/view/DebugView.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/view/DebugView.kt
index b99775863..881f5f5ab 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/view/DebugView.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/view/DebugView.kt
@@ -15,11 +15,13 @@ package de.bixilon.minosoft.gui.rendering.camera.view
import de.bixilon.kotlinglm.vec2.Vec2d
import de.bixilon.kotlinglm.vec3.Vec3
+import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.camera.Camera
import de.bixilon.minosoft.gui.rendering.camera.CameraDefinition.CAMERA_UP_VEC3
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
+import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY
import de.bixilon.minosoft.input.camera.MovementInputActions
import de.bixilon.minosoft.input.camera.PlayerMovementInput
@@ -28,7 +30,7 @@ class DebugView(private val camera: Camera) : CameraView {
override val updateFrustum: Boolean get() = false
override val shaking: Boolean get() = false
- override var eyePosition = Vec3.EMPTY
+ override var eyePosition = Vec3d.EMPTY
override var rotation = EntityRotation.EMPTY
override var front = Vec3.EMPTY
@@ -44,7 +46,7 @@ class DebugView(private val camera: Camera) : CameraView {
speedMultiplier *= 2
}
- val movement = Vec3.EMPTY
+ val movement = Vec3d.EMPTY
if (input.forwards != 0.0f) {
movement += front * input.forwards
@@ -54,7 +56,7 @@ class DebugView(private val camera: Camera) : CameraView {
movement += cameraRight * input.sideways
}
- if (movement.length2() != 0.0f) {
+ if (movement.length2() != 0.0) {
movement.normalizeAssign()
}
movement *= speedMultiplier
@@ -73,7 +75,7 @@ class DebugView(private val camera: Camera) : CameraView {
}
override fun onAttach(previous: CameraView?) {
- this.eyePosition = previous?.eyePosition ?: Vec3.EMPTY
+ this.eyePosition = previous?.eyePosition ?: Vec3d.EMPTY
this.rotation = previous?.rotation ?: EntityRotation.EMPTY
this.front = previous?.front ?: Vec3.EMPTY
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/view/person/FirstPersonView.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/view/person/FirstPersonView.kt
index 4e6825a0d..ce29e5eb9 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/view/person/FirstPersonView.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/view/person/FirstPersonView.kt
@@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.camera.view.person
import de.bixilon.kotlinglm.vec2.Vec2d
import de.bixilon.kotlinglm.vec3.Vec3
+import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.minosoft.data.abilities.Gamemodes
import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity
@@ -22,6 +23,7 @@ import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.camera.Camera
import de.bixilon.minosoft.gui.rendering.camera.view.CameraView
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
+import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY
class FirstPersonView(override val camera: Camera) : PersonView {
override val context: RenderContext get() = camera.context
@@ -37,7 +39,7 @@ class FirstPersonView(override val camera: Camera) : PersonView {
}
override val renderOverlays: Boolean get() = true
- override var eyePosition: Vec3 = Vec3.EMPTY
+ override var eyePosition: Vec3d = Vec3d.EMPTY
override var rotation = EntityRotation.EMPTY
override var front = Vec3.EMPTY
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/view/person/ThirdPersonView.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/view/person/ThirdPersonView.kt
index 7b1d04099..804fcb585 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/view/person/ThirdPersonView.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/view/person/ThirdPersonView.kt
@@ -15,12 +15,14 @@ package de.bixilon.minosoft.gui.rendering.camera.view.person
import de.bixilon.kotlinglm.vec2.Vec2d
import de.bixilon.kotlinglm.vec3.Vec3
+import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.camera.Camera
import de.bixilon.minosoft.gui.rendering.camera.view.CameraView
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3d
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
+import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY
import de.bixilon.minosoft.input.camera.MovementInputActions
import de.bixilon.minosoft.input.camera.PlayerMovementInput
@@ -28,7 +30,7 @@ import de.bixilon.minosoft.input.camera.PlayerMovementInput
class ThirdPersonView(override val camera: Camera) : PersonView {
override val context: RenderContext get() = camera.context
- override var eyePosition: Vec3 = Vec3.EMPTY
+ override var eyePosition: Vec3d = Vec3d.EMPTY
override var rotation = EntityRotation.EMPTY
override var front = Vec3.EMPTY
@@ -53,8 +55,8 @@ class ThirdPersonView(override val camera: Camera) : PersonView {
update(entity.renderInfo.eyePosition, front)
}
- private fun update(position: Vec3, front: Vec3) {
- val target = camera.context.connection.camera.target.raycastBlock(position.toVec3d, (-front).toVec3d).first
+ private fun update(position: Vec3d, front: Vec3) {
+ val target = camera.context.connection.camera.target.raycastBlock(position, (-front).toVec3d).first
val distance = target?.distance?.let { minOf(it, MAX_DISTANCE) } ?: MAX_DISTANCE
this.eyePosition = position + (-front * distance)
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entity/EntityRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entity/EntityRenderer.kt
index 7069f8432..03735da0c 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/entity/EntityRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entity/EntityRenderer.kt
@@ -61,6 +61,8 @@ class EntityRenderer(
var visibleCount: Int = 0
private set
+ private var reset = false
+
override fun init(latch: CountUpAndDownLatch) {
connection.events.listen { event ->
if (event.entity is LocalPlayerEntity) return@listen
@@ -75,6 +77,7 @@ class EntityRenderer(
}
profile.hitbox::enabled.observe(this) { this.hitboxes = it }
+ context.camera.offset::offset.observe(this) { reset = true }
context.inputHandler.registerKeyCallback(
HITBOX_TOGGLE_KEY_COMBINATION,
@@ -104,8 +107,12 @@ class EntityRenderer(
override fun prePrepareDraw() {
val count = AtomicInteger()
+ val reset = reset
runAsync {
it.entity.draw(millis())
+ if (reset) {
+ it.reset()
+ }
it.update = it.checkUpdate()
it.prepareAsync()
if (it.visible) {
@@ -113,6 +120,9 @@ class EntityRenderer(
}
}
this.visibleCount = count.get()
+ if (reset) {
+ this.reset = false
+ }
}
override fun postPrepareDraw() {
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entity/ModelUpdater.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entity/ModelUpdater.kt
index eafeb15e7..44b66bab0 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/entity/ModelUpdater.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entity/ModelUpdater.kt
@@ -23,4 +23,6 @@ interface ModelUpdater : Drawable {
fun prepare() = Unit
fun unload() = Unit
+
+ fun reset() = Unit
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entity/hitbox/EntityHitbox.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entity/hitbox/EntityHitbox.kt
index 77ff044be..6f17896a2 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/entity/hitbox/EntityHitbox.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entity/hitbox/EntityHitbox.kt
@@ -14,6 +14,7 @@
package de.bixilon.minosoft.gui.rendering.entity.hitbox
import de.bixilon.kotlinglm.vec3.Vec3
+import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.minosoft.data.entities.entities.LivingEntity
import de.bixilon.minosoft.data.registries.shapes.aabb.AABB
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
@@ -31,7 +32,6 @@ class EntityHitbox(
private var aabb: AABB = model.aabb
private var data: HitboxData? = null
- private var update = true
var enabled: Boolean = true
get() = field && model.renderer.hitboxes
@@ -52,7 +52,6 @@ class EntityHitbox(
}
this.data = data
this.aabb = aabb
- update = true
return true
}
@@ -80,18 +79,21 @@ class EntityHitbox(
} else {
mesh.drawAABB(aabb = shrunk, color = data.color, margin = 0.1f)
}
- val center = Vec3(shrunk.center)
+ val offset = model.context.camera.offset.offset
+ val center = Vec3(shrunk.center - offset)
+
+
data.velocity?.let { mesh.drawLine(center, center + Vec3(it) * 3, color = ChatColors.YELLOW) }
val eyeHeight = shrunk.min.y + model.entity.eyeHeight
- val eyeAABB = AABB(Vec3(shrunk.min.x, eyeHeight, shrunk.min.z), Vec3(shrunk.max.x, eyeHeight, shrunk.max.z)).hShrink(RenderConstants.DEFAULT_LINE_WIDTH)
+ val eyeAABB = AABB(Vec3d(shrunk.min.x, eyeHeight, shrunk.min.z), Vec3d(shrunk.max.x, eyeHeight, shrunk.max.z)).hShrink(-RenderConstants.DEFAULT_LINE_WIDTH)
mesh.drawAABB(eyeAABB, RenderConstants.DEFAULT_LINE_WIDTH, ChatColors.DARK_RED)
- val eyeStart = Vec3(center.x, eyeHeight, center.z)
+ val eyeStart = Vec3(center.x, eyeHeight - offset.y, center.z)
- mesh.drawLine(eyeStart, eyeStart + Vec3(data.rotation.front) * 5.0f, color = ChatColors.BLUE)
+ mesh.drawLine(eyeStart, eyeStart + data.rotation.front * 5.0f, color = ChatColors.BLUE)
this.mesh = mesh
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entity/models/EntityModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entity/models/EntityModel.kt
index f99ba27b5..74711a38e 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/entity/models/EntityModel.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entity/models/EntityModel.kt
@@ -47,6 +47,11 @@ abstract class EntityModel(
return update
}
+ override fun reset() {
+ update = true
+ hitbox.reset()
+ }
+
override fun prepareAsync() {
if (!update) {
return
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/events/CameraPositionChangeEvent.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/events/CameraPositionChangeEvent.kt
index 75e1dcea6..8e339c532 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/events/CameraPositionChangeEvent.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/events/CameraPositionChangeEvent.kt
@@ -13,13 +13,13 @@
package de.bixilon.minosoft.gui.rendering.events
-import de.bixilon.kotlinglm.vec3.Vec3
+import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.minosoft.gui.rendering.RenderContext
class CameraPositionChangeEvent(
context: RenderContext,
- newPosition: Vec3,
+ newPosition: Vec3d,
) : RenderEvent(context) {
- val newPosition: Vec3 = newPosition
- get() = Vec3(field)
+ val newPosition: Vec3d = newPosition
+ get() = Vec3d(field)
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/exceptions/ShaderLoadingException.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/exceptions/ShaderLoadingException.kt
index cb6511332..062170b29 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/exceptions/ShaderLoadingException.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/exceptions/ShaderLoadingException.kt
@@ -12,7 +12,10 @@
*/
package de.bixilon.minosoft.gui.rendering.exceptions
+import de.bixilon.minosoft.config.StaticConfiguration
+
class ShaderLoadingException : Exception {
constructor()
constructor(message: String) : super(message)
+ constructor(message: String, code: String) : super(message + if (StaticConfiguration.DEBUG_MODE) "\n\n\n" + code else "")
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/simple/WallOverlay.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/simple/WallOverlay.kt
index c956ab768..2c426025b 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/simple/WallOverlay.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/simple/WallOverlay.kt
@@ -26,7 +26,7 @@ import de.bixilon.minosoft.data.world.positions.BlockPositionUtil.positionHash
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.OverlayFactory
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
-import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.blockPosition
+import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.blockPosition
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.EMPTY
import java.util.*
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/SingleBlockRenderable.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/SingleBlockRenderable.kt
index c9271e1c1..be9c1a23b 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/SingleBlockRenderable.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/SingleBlockRenderable.kt
@@ -20,5 +20,5 @@ import java.util.*
interface SingleBlockRenderable {
- fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean
+ fun singleRender(position: Vec3i, offset: FloatArray, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/MultipartBakedModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/MultipartBakedModel.kt
index e50d968e9..530b9167a 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/MultipartBakedModel.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/MultipartBakedModel.kt
@@ -32,10 +32,10 @@ class MultipartBakedModel(
return sizes[direction.ordinal]
}
- override fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean {
+ override fun singleRender(position: Vec3i, offset: FloatArray, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean {
var rendered = false
for (model in models) {
- if (model.singleRender(position, mesh, random, blockState, neighbours, light, tints) && !rendered) {
+ if (model.singleRender(position, offset, mesh, random, blockState, neighbours, light, tints) && !rendered) {
rendered = true
}
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/WeightedBakedModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/WeightedBakedModel.kt
index 58f391683..758508d9c 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/WeightedBakedModel.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/WeightedBakedModel.kt
@@ -59,8 +59,8 @@ class WeightedBakedModel(
Broken("Could not find a model: This should never happen!")
}
- override fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean {
- return getModel(random)?.singleRender(position, mesh, random, blockState, neighbours, light, tints) ?: false
+ override fun singleRender(position: Vec3i, offset: FloatArray, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean {
+ return getModel(random)?.singleRender(position, offset, mesh, random, blockState, neighbours, light, tints) ?: false
}
override fun getParticleTexture(random: Random, blockPosition: Vec3i): AbstractTexture? {
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/BakedBlockStateModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/BakedBlockStateModel.kt
index 0bdf8fa5d..60c37aeb0 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/BakedBlockStateModel.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/BakedBlockStateModel.kt
@@ -25,7 +25,7 @@ import de.bixilon.minosoft.gui.rendering.models.properties.AbstractFacePropertie
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
import de.bixilon.minosoft.gui.rendering.tint.TintManager
import de.bixilon.minosoft.gui.rendering.util.VecUtil.getWorldOffset
-import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.toVec3
+import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.toVec3
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
import de.bixilon.minosoft.gui.rendering.world.preparer.cull.SolidCullSectionPreparer
import java.util.*
@@ -40,8 +40,8 @@ class BakedBlockStateModel(
return touchingFaceProperties[direction.ordinal]
}
- override fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean {
- val floatPosition = position.toVec3()
+ override fun singleRender(position: Vec3i, offset: FloatArray, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean {
+ val floatPosition = offset.toVec3()
if (blockState.block is RandomOffsetBlock) {
blockState.block.randomOffset?.let { floatPosition += position.getWorldOffset(it) }
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleMesh.kt
index d87e7bdaa..32a3f3fef 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleMesh.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleMesh.kt
@@ -35,9 +35,10 @@ class ParticleMesh(context: RenderContext, data: AbstractFloatList) : Mesh(conte
}
val maxTransformedUV = texture.renderData.transformUV(uvMax)
val data = data
- data.add(position.x.toFloat())
- data.add(position.y.toFloat())
- data.add(position.z.toFloat())
+ val offset = context.camera.offset.offset
+ data.add((position.x - offset.x).toFloat())
+ data.add((position.y - offset.y).toFloat())
+ data.add((position.z - offset.z).toFloat())
data.add(minTransformedUV)
data.add(maxTransformedUV)
data.add(texture.renderData.shaderTextureId.buffer())
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/SkeletalInstance.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/SkeletalInstance.kt
index 20145c271..471f6b2cb 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/SkeletalInstance.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/SkeletalInstance.kt
@@ -16,6 +16,7 @@ package de.bixilon.minosoft.gui.rendering.skeletal.instance
import de.bixilon.kotlinglm.func.rad
import de.bixilon.kotlinglm.mat4x4.Mat4
import de.bixilon.kotlinglm.vec3.Vec3
+import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kutil.time.TimeUtil.millis
import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.gui.rendering.RenderContext
@@ -71,9 +72,9 @@ class SkeletalInstance(
context.skeletalManager.draw(this, light)
}
- fun updatePosition(position: Vec3, rotation: EntityRotation) {
+ fun updatePosition(position: Vec3d, rotation: EntityRotation) {
val matrix = Mat4()
- .translateAssign(position)
+ .translateAssign(Vec3(position - context.camera.offset.offset))
.rotateAssign((180.0f - rotation.yaw).rad, Vec3(0, 1, 0))
.translateAssign(Vec3(-0.5, 0.0f, -0.5)) // move to bottom center
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/box/SkyboxRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/box/SkyboxRenderer.kt
index a2a023227..8aa109cc9 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/box/SkyboxRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/box/SkyboxRenderer.kt
@@ -45,8 +45,8 @@ import de.bixilon.minosoft.gui.rendering.events.CameraPositionChangeEvent
import de.bixilon.minosoft.gui.rendering.sky.SkyChildRenderer
import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
-import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.blockPosition
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.interpolateLinear
+import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.blockPosition
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
import java.util.*
import kotlin.math.PI
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudArray.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudArray.kt
index 48d6cb2f6..9b5a09ff5 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudArray.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudArray.kt
@@ -27,6 +27,7 @@ class CloudArray(
}
private fun build() {
+ val offset = layer.clouds.context.camera.offset.offset
val matrix = layer.clouds.matrix
val matrixOffset = (offset * ARRAY_SIZE) and 0xFF
@@ -47,7 +48,7 @@ class CloudArray(
matrix[matrixX - 1, matrixZ + 0], // WEST
matrix[matrixX + 1, matrixZ + 0], // EAST
)
- mesh.createCloud(start, start + CLOUD_SIZE, layer.height.first, layer.height.last, layer.clouds.flat, cull)
+ mesh.createCloud(start, start + CLOUD_SIZE, offset, layer.height.first, layer.height.last, layer.clouds.flat, cull)
}
}
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudLayer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudLayer.kt
index 88a77e64e..b06c2f441 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudLayer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudLayer.kt
@@ -77,6 +77,10 @@ class CloudLayer(
if (offset.y != 0) pushZ(offset.y == 1)
}
+ fun reset() {
+
+ }
+
private fun reset(cloudPosition: Vec2i) {
for (array in arrays.unsafeCast>()) {
array?.unload()
@@ -92,9 +96,13 @@ class CloudLayer(
return this shr 4
}
- private fun updatePosition() {
+ private fun calculateCloudPosition(): Vec2i {
val offset = this.offset.toInt()
- val position = clouds.connection.player.physics.positionInfo.chunkPosition + Vec2i(offset / CloudArray.CLOUD_SIZE, 0)
+ return clouds.connection.player.physics.positionInfo.chunkPosition + Vec2i(offset / CloudArray.CLOUD_SIZE, 0)
+ }
+
+ private fun updatePosition() {
+ val position = calculateCloudPosition()
if (position == this.position) {
return
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudMesh.kt
index 103b21bf8..18291d78c 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudMesh.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudMesh.kt
@@ -16,6 +16,7 @@ package de.bixilon.minosoft.gui.rendering.sky.clouds
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kotlinglm.vec3.Vec3
+import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.system.base.MeshUtil.buffer
@@ -30,9 +31,9 @@ class CloudMesh(context: RenderContext) : Mesh(context, CloudMeshStruct, context
}
- fun createCloud(start: Vec2i, end: Vec2i, yStart: Int, yEnd: Int, flat: Boolean, culling: BooleanArray) {
- val start = Vec3(start.x, yStart, start.y) + CLOUD_OFFSET
- val end = Vec3(end.x, yEnd, end.y) + CLOUD_OFFSET
+ fun createCloud(start: Vec2i, end: Vec2i, offset: Vec3i, yStart: Int, yEnd: Int, flat: Boolean, culling: BooleanArray) {
+ val start = Vec3(start.x - offset.x, yStart - offset.y, start.y - offset.z) + CLOUD_OFFSET
+ val end = Vec3(end.x - offset.x, yEnd - offset.y, end.y - offset.z) + CLOUD_OFFSET
addYQuad(Vec2(start.x, start.z), start.y, Vec2(end.x, end.z)) { position, _ -> addVertex(position, Directions.DOWN) }
if (!flat) {
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudRenderer.kt
index 31e582280..aa6f6af02 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudRenderer.kt
@@ -63,12 +63,16 @@ class CloudRenderer(
var delta = 0.0f
private set
+ private var reset = false
+
override val skipOpaque: Boolean
get() = !sky.effects.clouds || !sky.profile.clouds.enabled || connection.profiles.block.viewDistance < 3 || layers.isEmpty()
override fun asyncInit(latch: CountUpAndDownLatch) {
matrix.load(connection.assetsManager)
+
+ context.camera.offset::offset.observe(this) { reset() }
}
private fun getCloudHeight(index: Int): IntRange {
@@ -103,6 +107,10 @@ class CloudRenderer(
sky.profile.clouds::flat.observe(this, instant = true) { this.flat = it }
}
+ private fun reset() {
+ reset = true
+ }
+
private fun updateLayers(layers: Int) {
while (layers < this.layers.size) {
toUnload += this.layers.removeLast()
@@ -117,6 +125,11 @@ class CloudRenderer(
if (!sky.effects.clouds) {
return
}
+ if (reset) {
+ updateLayers(0)
+ updateLayers(nextLayers)
+ reset = false
+ }
if (layers.size != nextLayers) {
updateLayers(nextLayers)
}
@@ -218,7 +231,7 @@ class CloudRenderer(
private fun setYOffset() {
- val y = context.connection.camera.entity.renderInfo.eyePosition.y
+ val y = (context.connection.camera.entity.renderInfo.eyePosition.y - context.camera.offset.offset.y).toFloat()
var yOffset = 0.0f
if (baseHeight - y > maxDistance) {
yOffset = y - baseHeight + maxDistance
@@ -236,8 +249,8 @@ class CloudRenderer(
setYOffset()
- for (array in layers) {
- array.draw()
+ for (layer in layers) {
+ layer.draw()
}
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/sound/AudioPlayer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/sound/AudioPlayer.kt
index 8d9e6026d..1c435e37a 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/sound/AudioPlayer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/sound/AudioPlayer.kt
@@ -14,6 +14,7 @@
package de.bixilon.minosoft.gui.rendering.sound
import de.bixilon.kotlinglm.vec3.Vec3
+import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kutil.collections.CollectionUtil.synchronizedListOf
import de.bixilon.kutil.collections.CollectionUtil.toSynchronizedList
import de.bixilon.kutil.concurrent.queue.Queue
@@ -25,6 +26,7 @@ import de.bixilon.minosoft.gui.rendering.Rendering
import de.bixilon.minosoft.gui.rendering.camera.CameraDefinition.CAMERA_UP_VEC3
import de.bixilon.minosoft.gui.rendering.events.CameraPositionChangeEvent
import de.bixilon.minosoft.gui.rendering.sound.sounds.Sound
+import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
@@ -121,7 +123,7 @@ class AudioPlayer(
latch.dec()
}
- override fun playSound(sound: ResourceLocation, position: Vec3?, volume: Float, pitch: Float) {
+ override fun playSound(sound: ResourceLocation, position: Vec3d?, volume: Float, pitch: Float) {
if (!initialized) {
return
}
@@ -180,9 +182,9 @@ class AudioPlayer(
return source
}
- private fun shouldPlay(sound: Sound, position: Vec3?): Boolean {
+ private fun shouldPlay(sound: Sound, position: Vec3d?): Boolean {
if (position == null) return true
- val distance = (this.listener.position - position).length2()
+ val distance = (this.listener.position - position.toVec3).length2()
if (distance >= sound.attenuationDistance * sound.attenuationDistance) {
return false
}
@@ -190,7 +192,7 @@ class AudioPlayer(
return true
}
- private fun playSound(sound: Sound, position: Vec3? = null, volume: Float = 1.0f, pitch: Float = 1.0f) {
+ private fun playSound(sound: Sound, position: Vec3d? = null, volume: Float = 1.0f, pitch: Float = 1.0f) {
if (!profile.enabled) {
return
}
@@ -205,7 +207,7 @@ class AudioPlayer(
}
position?.let {
source.relative = false
- source.position = it
+ source.position = it.toVec3
} ?: let {
source.position = Vec3.EMPTY
source.relative = true
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/sound/DefaultAudioBehavior.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/sound/DefaultAudioBehavior.kt
index f64bed425..869eb0bd1 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/sound/DefaultAudioBehavior.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/sound/DefaultAudioBehavior.kt
@@ -1,6 +1,6 @@
/*
* Minosoft
- * Copyright (C) 2020-2022 Moritz Zwerger
+ * Copyright (C) 2020-2023 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.
*
@@ -13,7 +13,6 @@
package de.bixilon.minosoft.gui.rendering.sound
-import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.modding.event.events.ExplosionEvent
import de.bixilon.minosoft.modding.event.events.PlaySoundEvent
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener
@@ -29,9 +28,9 @@ object DefaultAudioBehavior {
val world = connection.world
val invokers = listOf(
CallbackEventListener.of { world.playSound(it.soundEvent, it.position, it.volume, it.pitch) },
- CallbackEventListener.of { world.playSound(ENTITY_GENERIC_EXPLODE, Vec3(it.position), 4.0f, (1.0f + (random.nextFloat() - random.nextFloat()) * 0.2f) * 0.7f) },
+ CallbackEventListener.of { world.playSound(ENTITY_GENERIC_EXPLODE, it.position, 4.0f, (1.0f + (random.nextFloat() - random.nextFloat()) * 0.2f) * 0.7f) },
)
- connection.register(*invokers.toTypedArray())
+ connection.events.register(*invokers.toTypedArray())
}
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLNativeShader.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLNativeShader.kt
index 1fcf3667d..49d967725 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLNativeShader.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLNativeShader.kt
@@ -53,12 +53,13 @@ class OpenGLNativeShader(
throw ShaderLoadingException()
}
- glShaderSource(program, code.code)
+ val glsl = code.code
+ glShaderSource(program, glsl)
glCompileShader(program)
if (glGetShaderi(program, GL_COMPILE_STATUS) == GL_FALSE) {
- throw ShaderLoadingException(getShaderInfoLog(program))
+ throw ShaderLoadingException(getShaderInfoLog(program), glsl)
}
return program
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/LineMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/LineMesh.kt
index 45dabcb9a..fd9a0a9e3 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/LineMesh.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/LineMesh.kt
@@ -80,8 +80,9 @@ open class LineMesh(context: RenderContext) : GenericColorMesh(context) {
fun drawLazyAABB(aabb: AABB, color: RGBColor) {
data.ensureSize(6 * order.size * GenericColorMeshStruct.FLOATS_PER_VERTEX)
+ val offset = context.camera.offset.offset
for (direction in Directions.VALUES) {
- val positions = direction.getPositions(Vec3(aabb.min), Vec3(aabb.max))
+ val positions = direction.getPositions(Vec3(aabb.min - offset), Vec3(aabb.max - offset))
for ((positionIndex, _) in order) {
addVertex(positions[positionIndex], color)
}
@@ -90,8 +91,9 @@ open class LineMesh(context: RenderContext) : GenericColorMesh(context) {
fun drawAABB(aabb: AABB, lineWidth: Float = RenderConstants.DEFAULT_LINE_WIDTH, color: RGBColor, margin: Float = 0.0f, shape: AbstractVoxelShape? = null) {
data.ensureSize(12 * 4 * order.size * GenericColorMeshStruct.FLOATS_PER_VERTEX)
- val min = aabb.min - margin
- val max = aabb.max + margin
+ val offset = context.camera.offset.offset
+ val min = aabb.min - margin - offset
+ val max = aabb.max + margin - offset
fun tryDrawLine(start: Vec3, end: Vec3) {
tryDrawLine(start, end, lineWidth, color, shape)
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/util/vec/vec3/Vec3Util.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/util/vec/vec3/Vec3Util.kt
index d83199a88..f17081d0d 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/util/vec/vec3/Vec3Util.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/util/vec/vec3/Vec3Util.kt
@@ -156,4 +156,8 @@ object Vec3Util {
return Vec3(interpolate(start.x, end.x), interpolate(start.y, end.y), interpolate(start.z, end.z))
}
+
+ fun FloatArray.toVec3(): Vec3 {
+ return Vec3(this[0], this[1], this[2])
+ }
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt
index 47e7f4ad1..4ac0d2218 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt
@@ -113,6 +113,7 @@ class WorldRenderer(
paused = false
}
}
+ context.camera.offset::offset.observe(this) { silentlyClearChunkCache() }
context.inputHandler.registerKeyCallback("minosoft:clear_chunk_cache".toResourceLocation(), KeyBinding(
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F3),
@@ -265,7 +266,7 @@ class WorldRenderer(
private fun onFrustumChange() {
var sortQueue = false
- val cameraPosition = connection.player.renderInfo.eyePosition
+ val cameraPosition = Vec3(connection.player.renderInfo.eyePosition - context.camera.offset.offset)
val cameraChunkPosition = cameraPosition.blockPosition.chunkPosition
val cameraSectionHeight = this.cameraSectionHeight
if (this.cameraPosition != cameraPosition) {
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/border/WorldBorderMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/border/WorldBorderMesh.kt
index 9bbb66a30..a183f31ca 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/border/WorldBorderMesh.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/border/WorldBorderMesh.kt
@@ -13,51 +13,99 @@
package de.bixilon.minosoft.gui.rendering.world.border
+import de.bixilon.kotlinglm.vec2.Vec2
+import de.bixilon.kotlinglm.vec2.Vec2d
import de.bixilon.kotlinglm.vec3.Vec3
+import de.bixilon.kotlinglm.vec3.Vec3i
+import de.bixilon.minosoft.data.world.World
+import de.bixilon.minosoft.data.world.border.WorldBorder
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.system.base.MeshUtil.buffer
-import de.bixilon.minosoft.gui.rendering.system.base.buffer.vertex.PrimitiveTypes
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
import de.bixilon.minosoft.gui.rendering.util.mesh.MeshStruct
+import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
-class WorldBorderMesh(context: RenderContext) : Mesh(context, WorldBorderMeshStruct, PrimitiveTypes.TRIANGLE, initialCacheSize = 6 * 2 * 3 * WorldBorderMeshStruct.FLOATS_PER_VERTEX) {
+class WorldBorderMesh(
+ context: RenderContext,
+ val offset: Vec3i,
+ val center: Vec2d,
+ val radius: Double,
+) : Mesh(context, WorldBorderMeshStruct, initialCacheSize = 6 * 2 * 3 * WorldBorderMeshStruct.FLOATS_PER_VERTEX) {
- init {
- data.add(
- floatArrayOf(
- -1.0f, +1.0f, -1.0f, 1.buffer(),
- +1.0f, -1.0f, -1.0f, 0.buffer(),
- -1.0f, -1.0f, -1.0f, 3.buffer(),
- +1.0f, -1.0f, -1.0f, 0.buffer(),
- -1.0f, +1.0f, -1.0f, 1.buffer(),
- +1.0f, +1.0f, -1.0f, 2.buffer(),
- -1.0f, -1.0f, +1.0f, 3.buffer(),
- -1.0f, +1.0f, -1.0f, 2.buffer(),
- -1.0f, -1.0f, -1.0f, 0.buffer(),
- -1.0f, +1.0f, -1.0f, 2.buffer(),
- -1.0f, -1.0f, +1.0f, 3.buffer(),
- -1.0f, +1.0f, +1.0f, 1.buffer(),
-
- +1.0f, -1.0f, -1.0f, 3.buffer(),
- +1.0f, +1.0f, +1.0f, 2.buffer(),
- +1.0f, -1.0f, +1.0f, 0.buffer(),
- +1.0f, +1.0f, +1.0f, 2.buffer(),
- +1.0f, -1.0f, -1.0f, 3.buffer(),
- +1.0f, +1.0f, -1.0f, 1.buffer(),
-
- -1.0f, -1.0f, +1.0f, 0.buffer(),
- +1.0f, +1.0f, +1.0f, 1.buffer(),
- -1.0f, +1.0f, +1.0f, 2.buffer(),
- +1.0f, +1.0f, +1.0f, 1.buffer(),
- -1.0f, -1.0f, +1.0f, 0.buffer(),
- +1.0f, -1.0f, +1.0f, 3.buffer(),
- ))
+ private fun width(): Float {
+ return minOf(radius.toFloat(), World.MAX_RENDER_DISTANCE.toFloat() * ProtocolDefinition.SECTION_WIDTH_X)
}
+ private fun positions(width: Float, center: Double): Array {
+ val left = (center - width).toFloat()
+ val right = (center + width).toFloat()
+
+ return arrayOf(
+ Vec2(left, -1.0f),
+ Vec2(left, +1.0f),
+ Vec2(right, +1.0f),
+ Vec2(right, -1.0f),
+ )
+ }
+
+ private fun textureIndex(index: Int): Int {
+ return when (index) {
+ 1 -> 2
+ 2 -> 1
+ 3 -> 0
+ else -> 3
+ }
+ }
+
+ private fun addVertexX(x: Float, width: Float, positions: Array, index: Boolean) {
+ for ((position, texture) in order) {
+ val (z, y) = positions[position]
+ val texture = if (index) textureIndex(texture) else texture
+ addVertex(x, y, z, textureIndex(texture), width)
+ }
+ }
+
+ private fun x(width: Float) {
+ val positions = positions(width, center.y)
+ addVertexX((maxOf(-WorldBorder.MAX_RADIUS, center.x - radius) - offset.x).toFloat(), width, positions, false)
+ addVertexX((minOf(WorldBorder.MAX_RADIUS, center.x + radius) - offset.x).toFloat(), width, positions, true)
+ }
+
+ private fun addVertexZ(z: Float, width: Float, positions: Array, index: Boolean) {
+ for ((position, texture) in order) {
+ val (x, y) = positions[position]
+ val texture = if (index) textureIndex(texture) else texture
+ addVertex(x, y, z, textureIndex(texture), width)
+ }
+ }
+
+ private fun z(width: Float) {
+ val positions = positions(width, center.x)
+
+ addVertexZ((maxOf(-WorldBorder.MAX_RADIUS, center.y - radius) - offset.z).toFloat(), width, positions, true)
+ addVertexZ((minOf(WorldBorder.MAX_RADIUS, center.y + radius) - offset.z).toFloat(), width, positions, false)
+ }
+
+ fun build() {
+ val width = width()
+ x(width)
+ z(width)
+ }
+
+ private fun addVertex(x: Float, y: Float, z: Float, uvIndex: Int, width: Float) {
+ data.add(x)
+ data.add(y)
+ data.add(z)
+ data.add(uvIndex.buffer())
+ data.add(width)
+ }
+
+
data class WorldBorderMeshStruct(
val position: Vec3,
val uvIndex: Int,
+ val width: Float,
) {
companion object : MeshStruct(WorldBorderMeshStruct::class)
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/border/WorldBorderRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/border/WorldBorderRenderer.kt
index 16259693f..76323bf93 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/border/WorldBorderRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/border/WorldBorderRenderer.kt
@@ -14,40 +14,46 @@
package de.bixilon.minosoft.gui.rendering.world.border
import de.bixilon.kotlinglm.func.common.clamp
-import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kutil.latch.CountUpAndDownLatch
+import de.bixilon.kutil.observer.DataObserver.Companion.observe
import de.bixilon.kutil.time.TimeUtil.millis
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
+import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.data.text.formatting.color.RGBColor.Companion.asColor
import de.bixilon.minosoft.data.world.border.WorldBorderState
import de.bixilon.minosoft.gui.rendering.RenderContext
+import de.bixilon.minosoft.gui.rendering.renderer.renderer.AsyncRenderer
import de.bixilon.minosoft.gui.rendering.renderer.renderer.Renderer
import de.bixilon.minosoft.gui.rendering.renderer.renderer.RendererBuilder
import de.bixilon.minosoft.gui.rendering.system.base.BlendingFunctions
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
+import de.bixilon.minosoft.gui.rendering.system.base.phases.SkipAll
import de.bixilon.minosoft.gui.rendering.system.base.phases.TranslucentDrawable
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture
+import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.util.KUtil.toResourceLocation
class WorldBorderRenderer(
override val context: RenderContext,
-) : Renderer, TranslucentDrawable {
+) : Renderer, AsyncRenderer, TranslucentDrawable, SkipAll {
override val renderSystem: RenderSystem = context.renderSystem
private val shader = renderSystem.createShader(minosoft("world/border")) { WorldBorderShader(it) }
- private val borderMesh = WorldBorderMesh(context)
+ private var borderMesh: WorldBorderMesh? = null
private val border = context.connection.world.border
private lateinit var texture: AbstractTexture
private var offsetReset = millis()
- override val skipTranslucent: Boolean
+ override val skipAll: Boolean
get() = border.getDistanceTo(context.connection.player.physics.position) > MAX_DISTANCE
+ private var reload = false
override fun init(latch: CountUpAndDownLatch) {
+ shader.native.defines["MAX_DISTANCE"] = MAX_DISTANCE
shader.load()
- borderMesh.load()
texture = context.textureManager.staticTextures.createTexture(TEXTURE)
+ context.camera.offset::offset.observe(this) { reload = true }
}
override fun postInit(latch: CountUpAndDownLatch) {
@@ -55,7 +61,53 @@ class WorldBorderRenderer(
shader.textureIndexLayer = texture.renderData.shaderTextureId
}
+ private fun calculateColor(): RGBColor {
+ val distance = border.getDistanceTo(context.connection.player.physics.position).toFloat() - 1.0f // 1 block padding
+ val strength = 1.0f - distance.clamp(0.0f, MAX_DISTANCE) / MAX_DISTANCE // slowly fade in
+ val color = when (border.area.state) {
+ WorldBorderState.GROWING -> GROWING_COLOR
+ WorldBorderState.SHRINKING -> SHRINKING_COLOR
+ WorldBorderState.STATIC -> STATIC_COLOR
+ }
+ return color.with(alpha = (strength * strength))
+ }
+
+ private fun update() {
+ if (this.borderMesh == null) return
+
+ val time = millis()
+ if (offsetReset - time > ANIMATION_SPEED) {
+ offsetReset = time
+ }
+ val textureOffset = (offsetReset - time) / ANIMATION_SPEED.toFloat()
+ shader.textureOffset = 1.0f - textureOffset
+
+ shader.tintColor = calculateColor()
+ }
+
+
+ override fun prepareDrawAsync() {
+ if (skipAll) return
+
+ val center = border.center
+ val radius = border.area.radius()
+
+ val previous = this.borderMesh
+ if (previous != null && !reload && center == previous.center && radius == previous.radius) return
+
+ context.queue += { previous?.unload() }
+
+ val offset = context.camera.offset.offset
+
+ val mesh = WorldBorderMesh(context, offset, center, radius)
+ mesh.build()
+
+ this.borderMesh = mesh
+ this.reload = false
+ }
+
override fun setupTranslucent() {
+ val mesh = this.borderMesh ?: return
renderSystem.reset(
blending = true,
sourceRGB = BlendingFunctions.SOURCE_ALPHA,
@@ -68,29 +120,15 @@ class WorldBorderRenderer(
polygonOffsetUnit = -3.0f,
)
shader.use()
- val time = millis()
- if (offsetReset - time > ANIMATION_SPEED) {
- offsetReset = time
- }
- val textureOffset = (offsetReset - time) / ANIMATION_SPEED.toFloat()
- shader.textureOffset = 1.0f - textureOffset
- shader.cameraHeight = context.connection.camera.entity.renderInfo.eyePosition.y
+ update()
- val distance = border.getDistanceTo(context.connection.player.physics.position)
- val strength = 1.0f - (distance.toFloat().clamp(0.0f, 100.0f) / 100.0f)
- var color = when (border.state) {
- WorldBorderState.GROWING -> GROWING_COLOR
- WorldBorderState.SHRINKING -> SHRINKING_COLOR
- WorldBorderState.STATIC -> STATIC_COLOR
+ if (mesh.state == Mesh.MeshStates.PREPARING) {
+ mesh.load()
}
- color = color.with(alpha = (strength * strength))
- shader.tintColor = color
- shader.radius = border.diameter.toFloat() / 2.0f
- shader.center = Vec2(border.center)
}
override fun drawTranslucent() {
- borderMesh.draw()
+ borderMesh?.draw()
}
companion object : RendererBuilder {
@@ -99,7 +137,7 @@ class WorldBorderRenderer(
val SHRINKING_COLOR = "#FF3030".asColor()
val STATIC_COLOR = "#20A0FF".asColor()
const val ANIMATION_SPEED = 2000
- const val MAX_DISTANCE = 1000
+ const val MAX_DISTANCE = 100.0f
private val TEXTURE = "minecraft:misc/forcefield".toResourceLocation().texture()
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/border/WorldBorderShader.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/border/WorldBorderShader.kt
index caa4c95f0..e9ec90662 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/border/WorldBorderShader.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/border/WorldBorderShader.kt
@@ -14,21 +14,20 @@
package de.bixilon.minosoft.gui.rendering.world.border
import de.bixilon.kotlinglm.mat4x4.Mat4
-import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.gui.rendering.camera.FogManager
import de.bixilon.minosoft.gui.rendering.shader.Shader
+import de.bixilon.minosoft.gui.rendering.shader.types.CameraPositionShader
import de.bixilon.minosoft.gui.rendering.shader.types.FogShader
import de.bixilon.minosoft.gui.rendering.shader.types.TextureShader
import de.bixilon.minosoft.gui.rendering.shader.types.ViewProjectionShader
import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureManager
-import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
class WorldBorderShader(
override val native: NativeShader,
-) : Shader(), TextureShader, ViewProjectionShader, FogShader {
+) : Shader(), TextureShader, ViewProjectionShader, FogShader, CameraPositionShader {
override var textures: TextureManager by textureManager()
override var viewProjectionMatrix: Mat4 by viewProjectionMatrix()
override var cameraPosition: Vec3 by cameraPosition()
@@ -38,7 +37,4 @@ class WorldBorderShader(
var textureIndexLayer by uniform("uIndexLayer", 0, NativeShader::setUInt)
var textureOffset by uniform("uTextureOffset", 0.0f)
- var radius by uniform("uRadius", 0.0f)
- var center by uniform("uCenter", Vec2.EMPTY)
- var cameraHeight by uniform("uCameraHeight", 0.0f)
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/chunk/ChunkBorderRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/chunk/ChunkBorderRenderer.kt
index 88b66b498..9d3418e80 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/chunk/ChunkBorderRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/chunk/ChunkBorderRenderer.kt
@@ -31,7 +31,8 @@ import de.bixilon.minosoft.gui.rendering.renderer.renderer.RendererBuilder
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
import de.bixilon.minosoft.gui.rendering.system.base.phases.OpaqueDrawable
import de.bixilon.minosoft.gui.rendering.util.mesh.LineMesh
-import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.blockPosition
+import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.blockPosition
+import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.EMPTY
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.chunkPosition
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.sectionHeight
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
@@ -45,6 +46,7 @@ class ChunkBorderRenderer(
) : AsyncRenderer, OpaqueDrawable, MeshSwapper {
private val profile = connection.profiles.rendering
override val renderSystem: RenderSystem = context.renderSystem
+ private var offset = Vec3i.EMPTY
private var chunkPosition: Vec2i? = null
private var sectionHeight: Int = Int.MIN_VALUE
@@ -77,52 +79,54 @@ class ChunkBorderRenderer(
val eyePosition = connection.camera.entity.renderInfo.eyePosition.blockPosition
val chunkPosition = eyePosition.chunkPosition
val sectionHeight = eyePosition.sectionHeight
- if (chunkPosition == this.chunkPosition && sectionHeight == this.sectionHeight && mesh != null) {
+ val offset = context.camera.offset.offset
+ if (chunkPosition == this.chunkPosition && sectionHeight == this.sectionHeight && this.offset == offset && mesh != null) {
return
}
unload = true
val mesh = LineMesh(context)
val dimension = context.connection.world.dimension
- val basePosition = chunkPosition * Vec2i(ProtocolDefinition.SECTION_WIDTH_X, ProtocolDefinition.SECTION_WIDTH_Z)
+ val basePosition = chunkPosition * Vec2i(ProtocolDefinition.SECTION_WIDTH_X, ProtocolDefinition.SECTION_WIDTH_Z) - Vec2i(offset.x, offset.z)
- mesh.drawInnerChunkLines(basePosition, dimension)
+ mesh.drawInnerChunkLines(Vec3i(basePosition.x, -offset.y, basePosition.y), dimension)
if (sectionHeight in dimension.minSection until dimension.maxSection) {
mesh.drawSectionLines(Vec3i(basePosition.x, sectionHeight * ProtocolDefinition.SECTION_HEIGHT_Y, basePosition.y))
}
- mesh.drawOuterChunkLines(chunkPosition, dimension)
+ mesh.drawOuterChunkLines(chunkPosition, offset, dimension)
- this.nextMesh = mesh
this.chunkPosition = chunkPosition
this.sectionHeight = sectionHeight
+ this.offset = offset
+ this.nextMesh = mesh
}
- private fun LineMesh.drawOuterChunkLines(chunkPosition: Vec2i, dimension: DimensionProperties) {
+ private fun LineMesh.drawOuterChunkLines(chunkPosition: Vec2i, offset: Vec3i, dimension: DimensionProperties) {
for (x in -OUTER_CHUNK_SIZE..OUTER_CHUNK_SIZE + 1) {
for (z in -OUTER_CHUNK_SIZE..OUTER_CHUNK_SIZE + 1) {
if ((x == 0 || x == 1) && (z == 0 || z == 1)) {
continue
}
- val chunkBase = (chunkPosition + Vec2i(x, z)) * Vec2i(ProtocolDefinition.SECTION_WIDTH_X, ProtocolDefinition.SECTION_WIDTH_Z)
- drawLine(Vec3(chunkBase.x + 0, dimension.minY, chunkBase.y), Vec3(chunkBase.x + 0, dimension.maxY + 1, chunkBase.y), OUTER_CHUNK_LINE_WIDTH, OUTER_CHUNK_COLOR)
+ val chunkBase = (chunkPosition + Vec2i(x, z)) * Vec2i(ProtocolDefinition.SECTION_WIDTH_X, ProtocolDefinition.SECTION_WIDTH_Z) - Vec2i(offset.x, offset.z)
+ drawLine(Vec3(chunkBase.x + 0, dimension.minY - offset.y, chunkBase.y), Vec3(chunkBase.x + 0, dimension.maxY - offset.y + 1, chunkBase.y), OUTER_CHUNK_LINE_WIDTH, OUTER_CHUNK_COLOR)
}
}
}
- private fun LineMesh.drawInnerChunkLines(basePosition: Vec2i, dimension: DimensionProperties) {
- drawLine(Vec3(basePosition.x + 0, dimension.minY, basePosition.y), Vec3(basePosition.x + 0, dimension.maxY + 1, basePosition.y), INNER_CHUNK_LINE_WIDTH, INNER_CHUNK_COLOR)
- drawLine(Vec3(basePosition.x, dimension.minY, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), Vec3(basePosition.x, dimension.maxY + 1, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), INNER_CHUNK_LINE_WIDTH, INNER_CHUNK_COLOR)
- drawLine(Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, dimension.minY, basePosition.y + 0), Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, dimension.maxY + 1, basePosition.y + 0), INNER_CHUNK_LINE_WIDTH, INNER_CHUNK_COLOR)
- drawLine(Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, dimension.minY, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, dimension.maxY + 1, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), INNER_CHUNK_LINE_WIDTH, INNER_CHUNK_COLOR)
+ private fun LineMesh.drawInnerChunkLines(basePosition: Vec3i, dimension: DimensionProperties) {
+ drawLine(Vec3(basePosition.x + 0, basePosition.y + dimension.minY, basePosition.z), Vec3(basePosition.x + 0, basePosition.y + dimension.maxY + 1, basePosition.z), INNER_CHUNK_LINE_WIDTH, INNER_CHUNK_COLOR)
+ drawLine(Vec3(basePosition.x, basePosition.y + dimension.minY, basePosition.z + ProtocolDefinition.SECTION_WIDTH_Z), Vec3(basePosition.x, basePosition.y + dimension.maxY + 1, basePosition.z + ProtocolDefinition.SECTION_WIDTH_Z), INNER_CHUNK_LINE_WIDTH, INNER_CHUNK_COLOR)
+ drawLine(Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, basePosition.y + dimension.minY, basePosition.z + 0), Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, basePosition.y + dimension.maxY + 1, basePosition.z + 0), INNER_CHUNK_LINE_WIDTH, INNER_CHUNK_COLOR)
+ drawLine(Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, basePosition.y + dimension.minY, basePosition.z + ProtocolDefinition.SECTION_WIDTH_Z), Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, basePosition.y + dimension.maxY + 1, basePosition.z + ProtocolDefinition.SECTION_WIDTH_Z), INNER_CHUNK_LINE_WIDTH, INNER_CHUNK_COLOR)
for (sectionHeight in dimension.minSection..dimension.maxSection) {
- val y = sectionHeight * ProtocolDefinition.SECTION_HEIGHT_Y
- drawLine(Vec3(basePosition.x, y, basePosition.y), Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, y, basePosition.y), INNER_CHUNK_LINE_WIDTH, INNER_CHUNK_COLOR)
- drawLine(Vec3(basePosition.x, y, basePosition.y), Vec3(basePosition.x, y, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), INNER_CHUNK_LINE_WIDTH, INNER_CHUNK_COLOR)
- drawLine(Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, y, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, y, basePosition.y), INNER_CHUNK_LINE_WIDTH, INNER_CHUNK_COLOR)
- drawLine(Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, y, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), Vec3(basePosition.x, y, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), INNER_CHUNK_LINE_WIDTH, INNER_CHUNK_COLOR)
+ val y = basePosition.y + sectionHeight * ProtocolDefinition.SECTION_HEIGHT_Y
+ drawLine(Vec3(basePosition.x, y, basePosition.z), Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, y, basePosition.z), INNER_CHUNK_LINE_WIDTH, INNER_CHUNK_COLOR)
+ drawLine(Vec3(basePosition.x, y, basePosition.z), Vec3(basePosition.x, y, basePosition.z + ProtocolDefinition.SECTION_WIDTH_Z), INNER_CHUNK_LINE_WIDTH, INNER_CHUNK_COLOR)
+ drawLine(Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, y, basePosition.z + ProtocolDefinition.SECTION_WIDTH_Z), Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, y, basePosition.z), INNER_CHUNK_LINE_WIDTH, INNER_CHUNK_COLOR)
+ drawLine(Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, y, basePosition.z + ProtocolDefinition.SECTION_WIDTH_Z), Vec3(basePosition.x, y, basePosition.z + ProtocolDefinition.SECTION_WIDTH_Z), INNER_CHUNK_LINE_WIDTH, INNER_CHUNK_COLOR)
}
}
@@ -186,7 +190,11 @@ class ChunkBorderRenderer(
}
override fun setupOpaque() {
- context.renderSystem.reset()
+ context.renderSystem.reset(
+ polygonOffset = true,
+ polygonOffsetFactor = -1.0f,
+ polygonOffsetUnit = -2.0f,
+ )
context.shaderManager.genericColorShader.use()
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/renderer/sign/SignBlockEntityRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/renderer/sign/SignBlockEntityRenderer.kt
index 967ced78a..9b1ef0ee0 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/renderer/sign/SignBlockEntityRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/renderer/sign/SignBlockEntityRenderer.kt
@@ -32,8 +32,8 @@ import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.font.Font
import de.bixilon.minosoft.gui.rendering.font.renderer.ChatComponentRenderer
import de.bixilon.minosoft.gui.rendering.models.unbaked.element.UnbakedElement
-import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rotateAssign
+import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.toVec3
import de.bixilon.minosoft.gui.rendering.world.entities.OnlyMeshedBlockEntityRenderer
import de.bixilon.minosoft.gui.rendering.world.mesh.SingleWorldMesh
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
@@ -52,19 +52,19 @@ class SignBlockEntityRenderer(
return rotation * 22.5f
}
- override fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean {
+ override fun singleRender(position: Vec3i, offset: FloatArray, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean {
val block = this.blockState.block
if (block is StandingSignBlock) {
- renderStandingText(position, mesh, light[SolidCullSectionPreparer.SELF_LIGHT_INDEX].toInt())
+ renderStandingText(offset, mesh, light[SolidCullSectionPreparer.SELF_LIGHT_INDEX].toInt())
} else if (block is WallSignBlock) {
- renderWallText(position, mesh, light[SolidCullSectionPreparer.SELF_LIGHT_INDEX].toInt())
+ renderWallText(offset, mesh, light[SolidCullSectionPreparer.SELF_LIGHT_INDEX].toInt())
}
return true
}
- private fun renderText(position: Vec3i, rotationVector: Vec3, yRotation: Float, mesh: WorldMesh, light: Int) {
- val textPosition = position.toVec3 + rotationVector
+ private fun renderText(offset: FloatArray, rotationVector: Vec3, yRotation: Float, mesh: WorldMesh, light: Int) {
+ val textPosition = offset.toVec3() + rotationVector
val textMesh = mesh.textMesh!!
var primitives = 0
@@ -79,15 +79,15 @@ class SignBlockEntityRenderer(
}
}
- private fun renderStandingText(position: Vec3i, mesh: WorldMesh, light: Int) {
+ private fun renderStandingText(offset: FloatArray, mesh: WorldMesh, light: Int) {
val yRotation = getRotation()
val rotationVector = Vec3(X_OFFSET, 17.5f / UnbakedElement.BLOCK_RESOLUTION - Y_OFFSET, 9.0f / UnbakedElement.BLOCK_RESOLUTION + Z_OFFSET)
rotationVector.signRotate(yRotation.rad)
- renderText(position, rotationVector, yRotation, mesh, light)
+ renderText(offset, rotationVector, yRotation, mesh, light)
}
- private fun renderWallText(position: Vec3i, mesh: WorldMesh, light: Int) {
+ private fun renderWallText(position: FloatArray, mesh: WorldMesh, light: Int) {
val yRotation = -when (val rotation = this.blockState.getFacing()) {
Directions.SOUTH -> 0.0f
Directions.EAST -> 90.0f
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/renderer/storage/DoubleChestRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/renderer/storage/DoubleChestRenderer.kt
index cd41c6df3..6ecfe1257 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/renderer/storage/DoubleChestRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/renderer/storage/DoubleChestRenderer.kt
@@ -38,7 +38,7 @@ class DoubleChestRenderer(
light: Int,
) : StorageBlockEntityRenderer(
blockState,
- SkeletalInstance(context, model, blockPosition.toVec3, (blockState.getFacing()).rotatedMatrix),
+ SkeletalInstance(context, model, (blockPosition - context.camera.offset.offset).toVec3, (blockState.getFacing()).rotatedMatrix),
light,
) {
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/renderer/storage/SingleChestRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/renderer/storage/SingleChestRenderer.kt
index f774ae9fd..141d17403 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/renderer/storage/SingleChestRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/renderer/storage/SingleChestRenderer.kt
@@ -38,7 +38,7 @@ class SingleChestRenderer(
light: Int,
) : StorageBlockEntityRenderer(
blockState,
- SkeletalInstance(context, model, blockPosition.toVec3, blockState.getFacing().rotatedMatrix),
+ SkeletalInstance(context, model, (blockPosition - context.camera.offset.offset).toVec3, blockState.getFacing().rotatedMatrix),
light,
) {
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/outline/BlockOutlineRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/outline/BlockOutlineRenderer.kt
index 6751524ff..a1ee6b15b 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/outline/BlockOutlineRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/outline/BlockOutlineRenderer.kt
@@ -63,7 +63,6 @@ class BlockOutlineRenderer(
override var unload: Boolean = false
override fun init(latch: CountUpAndDownLatch) {
- val profile = connection.profiles.block
this.profile::enabled.observe(this) { reload = true }
this.profile::collisions.observe(this) { reload = true }
this.profile::outlineColor.observe(this) { reload = true }
@@ -77,7 +76,11 @@ class BlockOutlineRenderer(
}
override fun setupOther() {
- context.renderSystem.reset()
+ context.renderSystem.reset(
+ polygonOffset = true,
+ polygonOffsetFactor = -3.0f,
+ polygonOffsetUnit = -3.0f,
+ )
if (profile.showThroughWalls) {
context.renderSystem.depth = DepthFunctions.ALWAYS
}
@@ -113,7 +116,9 @@ class BlockOutlineRenderer(
}
}
- if (target.blockPosition == position && target.state == state && !reload) { // TODO: also compare shapes, some blocks dynamically change it (e.g. scaffolding)
+ val offsetPosition = (target.blockPosition - context.camera.offset.offset)
+
+ if (offsetPosition == position && target.state == state && !reload) { // TODO: also compare shapes, some blocks dynamically change it (e.g. scaffolding)
return
}
@@ -139,7 +144,7 @@ class BlockOutlineRenderer(
this.nextMesh = mesh
- this.position = target.blockPosition
+ this.position = offsetPosition
this.state = target.state
this.reload = false
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/preparer/cull/FluidCullSectionPreparer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/preparer/cull/FluidCullSectionPreparer.kt
index f7f8f710a..e16a5e5ae 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/preparer/cull/FluidCullSectionPreparer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/preparer/cull/FluidCullSectionPreparer.kt
@@ -68,6 +68,8 @@ class FluidCullSectionPreparer(
var rendered = false
var tint: Int
+ val cameraOffset = context.camera.offset.offset
+
val offsetX = chunkPosition.x * ProtocolDefinition.SECTION_WIDTH_X
val offsetY = sectionHeight * ProtocolDefinition.SECTION_HEIGHT_Y
val offsetZ = chunkPosition.y * ProtocolDefinition.SECTION_WIDTH_Z
@@ -130,6 +132,8 @@ class FluidCullSectionPreparer(
getCornerHeight(chunk, chunkPosition, position + Directions.SOUTH, fluid),
)
+ val offsetPosition = Vec3(position - cameraOffset)
+
if (!skip[Directions.O_UP]) {
val velocity = fluid.getVelocity(blockState, position, chunk)
val still = velocity.x == 0.0 && velocity.z == 0.0
@@ -164,10 +168,10 @@ class FluidCullSectionPreparer(
val meshToUse = texture.transparency.getMesh(mesh)
val positions = arrayOf(
- Vec3(position.x, position.y + cornerHeights[0], position.z),
- Vec3(position.x + 1, position.y + cornerHeights[1], position.z),
- Vec3(position.x + 1, position.y + cornerHeights[2], position.z + 1),
- Vec3(position.x, position.y + cornerHeights[3], position.z + 1),
+ Vec3(offsetPosition.x, offsetPosition.y + cornerHeights[0], offsetPosition.z),
+ Vec3(offsetPosition.x + 1, offsetPosition.y + cornerHeights[1], offsetPosition.z),
+ Vec3(offsetPosition.x + 1, offsetPosition.y + cornerHeights[2], offsetPosition.z + 1),
+ Vec3(offsetPosition.x, offsetPosition.y + cornerHeights[3], offsetPosition.z + 1),
)
@@ -182,9 +186,9 @@ class FluidCullSectionPreparer(
if (skip[Directions.SIDE_OFFSET + direction]) {
continue
}
- var faceX = position.x.toFloat()
+ var faceX = offsetPosition.x
var faceXEnd = faceX
- var faceZ = position.z.toFloat()
+ var faceZ = offsetPosition.z
var faceZEnd = faceZ
var v1 = 0.0f
var v2 = 0.0f
@@ -222,10 +226,10 @@ class FluidCullSectionPreparer(
val positions = arrayOf(
- Vec3(faceX, position.y + v1, faceZ),
- Vec3(faceX, position.y, faceZ),
- Vec3(faceXEnd, position.y, faceZEnd),
- Vec3(faceXEnd, position.y + v2, faceZEnd),
+ Vec3(faceX, offsetPosition.y + v1, faceZ),
+ Vec3(faceX, offsetPosition.y, faceZ),
+ Vec3(faceXEnd, offsetPosition.y, faceZEnd),
+ Vec3(faceXEnd, offsetPosition.y + v2, faceZEnd),
)
val texturePositions = arrayOf(
TEXTURE_1,
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/preparer/cull/SolidCullSectionPreparer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/preparer/cull/SolidCullSectionPreparer.kt
index 7251ae05d..d14b3593d 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/preparer/cull/SolidCullSectionPreparer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/preparer/cull/SolidCullSectionPreparer.kt
@@ -76,15 +76,21 @@ class SolidCullSectionPreparer(
val neighbourBlocks: Array = arrayOfNulls(Directions.SIZE)
val light = ByteArray(Directions.SIZE + 1) // last index (6) for the current block
+ val cameraOffset = context.camera.offset.offset
+
val offsetX = chunkPosition.x * ProtocolDefinition.SECTION_WIDTH_X
val offsetY = sectionHeight * ProtocolDefinition.SECTION_HEIGHT_Y
val offsetZ = chunkPosition.y * ProtocolDefinition.SECTION_WIDTH_Z
+ val floatOffset = FloatArray(3)
+
for (y in blocks.minPosition.y..blocks.maxPosition.y) {
position.y = offsetY + y
+ floatOffset[1] = (position.y - cameraOffset.y).toFloat()
val fastBedrock = y == 0 && isLowestSection && fastBedrock
for (x in blocks.minPosition.x..blocks.maxPosition.x) {
position.x = offsetX + x
+ floatOffset[0] = (position.x - cameraOffset.x).toFloat()
for (z in blocks.minPosition.z..blocks.maxPosition.z) {
val baseIndex = (z shl 4) or x
val index = (y shl 8) or baseIndex
@@ -94,6 +100,7 @@ class SolidCullSectionPreparer(
}
light[SELF_LIGHT_INDEX] = sectionLight[index]
position.z = offsetZ + z
+ floatOffset[2] = (position.z - cameraOffset.z).toFloat()
val maxHeight = chunk.light.heightmap[baseIndex]
if (position.y >= maxHeight) {
@@ -158,10 +165,10 @@ class SolidCullSectionPreparer(
random.setSeed(0L)
}
tints = tintColorCalculator.getAverageBlockTint(chunk, neighbourChunks, blockState, x, y, z)
- rendered = model.singleRender(position, mesh, random, blockState, neighbourBlocks, light, tints)
+ rendered = model.singleRender(position, floatOffset, mesh, random, blockState, neighbourBlocks, light, tints)
if (blockEntityModel is MeshedBlockEntityRenderer<*>) {
- rendered = blockEntityModel.singleRender(position, mesh, random, blockState, neighbourBlocks, light, tints) || rendered
+ rendered = blockEntityModel.singleRender(position, floatOffset, mesh, random, blockState, neighbourBlocks, light, tints) || rendered
}
if (rendered) {
diff --git a/src/main/java/de/bixilon/minosoft/modding/event/events/PlaySoundEvent.kt b/src/main/java/de/bixilon/minosoft/modding/event/events/PlaySoundEvent.kt
index c8861f16d..d2d36b9ca 100644
--- a/src/main/java/de/bixilon/minosoft/modding/event/events/PlaySoundEvent.kt
+++ b/src/main/java/de/bixilon/minosoft/modding/event/events/PlaySoundEvent.kt
@@ -13,7 +13,7 @@
package de.bixilon.minosoft.modding.event.events
-import de.bixilon.kotlinglm.vec3.Vec3
+import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.minosoft.data.SoundCategories
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent
@@ -24,15 +24,15 @@ import de.bixilon.minosoft.protocol.packets.s2c.play.sound.SoundEventS2CP
class PlaySoundEvent(
connection: PlayConnection,
val category: SoundCategories?,
- position: Vec3,
+ position: Vec3d,
val soundEvent: ResourceLocation,
val volume: Float,
val pitch: Float,
) : PlayConnectionEvent(connection), CancelableEvent {
- val position: Vec3 = position
- get() = Vec3(field)
+ val position: Vec3d = position
+ get() = Vec3d(field)
- constructor(connection: PlayConnection, packet: SoundEventS2CP) : this(connection, packet.category, Vec3(packet.position), packet.sound, packet.volume, packet.pitch.toFloat())
+ constructor(connection: PlayConnection, packet: SoundEventS2CP) : this(connection, packet.category, packet.position, packet.sound, packet.volume, packet.pitch)
- constructor(connection: PlayConnection, packet: NamedSoundS2CP) : this(connection, packet.category, packet.position, packet.soundEvent!!, packet.volume, packet.pitch.toFloat())
+ constructor(connection: PlayConnection, packet: NamedSoundS2CP) : this(connection, packet.category, packet.position, packet.soundEvent!!, packet.volume, packet.pitch)
}
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/border/InitializeWorldBorderS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/border/InitializeWorldBorderS2CP.kt
index a30c7fb99..08b50af3d 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/border/InitializeWorldBorderS2CP.kt
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/border/InitializeWorldBorderS2CP.kt
@@ -23,8 +23,8 @@ import de.bixilon.minosoft.util.logging.LogMessageType
@LoadPacket(parent = true)
class InitializeWorldBorderS2CP(buffer: PlayInByteBuffer) : WorldBorderS2CP {
val center = buffer.readVec2d()
- val oldDiameter = buffer.readDouble()
- val newDiameter = buffer.readDouble()
+ val oldRadius = buffer.readDouble() / 2.0
+ val newRadius = buffer.readDouble() / 2.0
val millis = buffer.readVarLong()
val portalBound = buffer.readVarInt()
val warningTime = buffer.readVarInt()
@@ -32,13 +32,13 @@ class InitializeWorldBorderS2CP(buffer: PlayInByteBuffer) : WorldBorderS2CP {
override fun handle(connection: PlayConnection) {
connection.world.border.center = center
- connection.world.border.interpolate(oldDiameter, newDiameter, millis)
+ connection.world.border.interpolate(oldRadius, newRadius, millis)
connection.world.border.portalBound = portalBound
connection.world.border.warningTime = warningTime
connection.world.border.warningBlocks = warningBlocks
}
override fun log(reducedLog: Boolean) {
- Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Initialize world border (center=$center, oldDiameter=$oldDiameter, newDiameter=$newDiameter, speed=$millis, portalBound=$portalBound, warningTime=$warningTime, warningBlocks=$warningBlocks)" }
+ Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Initialize world border (center=$center, oldRadius=$oldRadius, newRadius=$newRadius, speed=$millis, portalBound=$portalBound, warningTime=$warningTime, warningBlocks=$warningBlocks)" }
}
}
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/border/InterpolateWorldBorderS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/border/InterpolateWorldBorderS2CP.kt
index 7335eb9cb..409a828a6 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/border/InterpolateWorldBorderS2CP.kt
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/border/InterpolateWorldBorderS2CP.kt
@@ -22,15 +22,15 @@ import de.bixilon.minosoft.util.logging.LogMessageType
@LoadPacket(parent = true)
class InterpolateWorldBorderS2CP(buffer: PlayInByteBuffer) : WorldBorderS2CP {
- val oldDiameter = buffer.readDouble()
- val newDiameter = buffer.readDouble()
+ val oldRadius = buffer.readDouble() / 2.0
+ val newRadius = buffer.readDouble() / 2.0
val millis = buffer.readVarLong()
override fun handle(connection: PlayConnection) {
- connection.world.border.interpolate(oldDiameter, newDiameter, millis)
+ connection.world.border.interpolate(oldRadius, newRadius, millis)
}
override fun log(reducedLog: Boolean) {
- Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Interpolate size world border (oldDiameter=$oldDiameter, newDiameter=$newDiameter, millis=$millis)" }
+ Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Interpolate size world border (oldRadius=$oldRadius, newRadius=$newRadius, millis=$millis)" }
}
}
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/border/SizeWorldBorderS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/border/SizeWorldBorderS2CP.kt
index bf618b6e0..c42872c75 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/border/SizeWorldBorderS2CP.kt
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/border/SizeWorldBorderS2CP.kt
@@ -13,6 +13,7 @@
package de.bixilon.minosoft.protocol.packets.s2c.play.border
+import de.bixilon.minosoft.data.world.border.area.StaticBorderArea
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.packets.factory.LoadPacket
import de.bixilon.minosoft.protocol.protocol.buffers.play.PlayInByteBuffer
@@ -22,14 +23,13 @@ import de.bixilon.minosoft.util.logging.LogMessageType
@LoadPacket(parent = true)
class SizeWorldBorderS2CP(buffer: PlayInByteBuffer) : WorldBorderS2CP {
- val diameter = buffer.readDouble()
+ val radius = buffer.readDouble() / 2.0
override fun handle(connection: PlayConnection) {
- connection.world.border.stopInterpolating()
- connection.world.border.diameter = diameter
+ connection.world.border.area = StaticBorderArea(radius)
}
override fun log(reducedLog: Boolean) {
- Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Size set world border (diameter=$diameter)" }
+ Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Size set world border (radius=$radius)" }
}
}
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/sound/NamedSoundS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/sound/NamedSoundS2CP.kt
index d277dc699..35af3fadd 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/sound/NamedSoundS2CP.kt
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/sound/NamedSoundS2CP.kt
@@ -12,7 +12,7 @@
*/
package de.bixilon.minosoft.protocol.packets.s2c.play.sound
-import de.bixilon.kotlinglm.vec3.Vec3
+import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.minosoft.data.SoundCategories
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.modding.event.events.PlaySoundEvent
@@ -33,7 +33,7 @@ class NamedSoundS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
val soundEvent: ResourceLocation?
val volume: Float
val pitch: Float
- lateinit var position: Vec3
+ lateinit var position: Vec3d
private set
lateinit var category: SoundCategories
private set
@@ -49,13 +49,13 @@ class NamedSoundS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
buffer.readString() // parrot entity type
}
if (buffer.versionId < V_16W02A) {
- position = Vec3(buffer.readInt() * 8, buffer.readInt() * 8, buffer.readInt() * 8) // ToDo: check if it is not * 4
+ position = Vec3d(buffer.readInt() * 4, buffer.readInt() * 4, buffer.readInt() * 4)
}
if (buffer.versionId >= V_16W02A && (buffer.versionId !in V_17W15A until V_17W18A)) {
this.category = SoundCategories[buffer.readVarInt()]
}
if (buffer.versionId >= V_16W02A) {
- position = Vec3(buffer.readFixedPointNumberInt() * 4, buffer.readFixedPointNumberInt() * 4, buffer.readFixedPointNumberInt() * 4)
+ position = Vec3d(buffer.readFixedPointNumberInt() * 4, buffer.readFixedPointNumberInt() * 4, buffer.readFixedPointNumberInt() * 4)
}
volume = buffer.readFloat()
pitch = buffer.readSoundPitch()
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/sound/SoundEventS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/sound/SoundEventS2CP.kt
index 9125f935e..2e95fd043 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/sound/SoundEventS2CP.kt
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/sound/SoundEventS2CP.kt
@@ -12,7 +12,7 @@
*/
package de.bixilon.minosoft.protocol.packets.s2c.play.sound
-import de.bixilon.kotlinglm.vec3.Vec3i
+import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.minosoft.data.SoundCategories
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.modding.event.events.PlaySoundEvent
@@ -33,7 +33,7 @@ import de.bixilon.minosoft.util.logging.LogMessageType
class SoundEventS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
var category: SoundCategories? = null
private set
- val position: Vec3i
+ val position: Vec3d
val sound: ResourceLocation
val volume: Float
val pitch: Float
@@ -65,7 +65,7 @@ class SoundEventS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
if (buffer.versionId >= V_16W02A && (buffer.versionId !in V_17W15A until V_17W18A)) {
this.category = SoundCategories[buffer.readVarInt()]
}
- position = Vec3i(buffer.readFixedPointNumberInt() * 4, buffer.readFixedPointNumberInt() * 4, buffer.readFixedPointNumberInt() * 4)
+ position = Vec3d(buffer.readFixedPointNumberInt() * 4, buffer.readFixedPointNumberInt() * 4, buffer.readFixedPointNumberInt() * 4)
volume = buffer.readFloat()
pitch = buffer.readSoundPitch()
diff --git a/src/main/resources/assets/minosoft/rendering/shader/includes/uv.glsl b/src/main/resources/assets/minosoft/rendering/shader/includes/uv.glsl
index 211f9353d..345208cbc 100644
--- a/src/main/resources/assets/minosoft/rendering/shader/includes/uv.glsl
+++ b/src/main/resources/assets/minosoft/rendering/shader/includes/uv.glsl
@@ -1,6 +1,6 @@
-const vec2 CONST_UV[4] = vec2[4](
- vec2(+ 0.0f, + 1.0f),
- vec2(+ 1.0f, + 0.0f),
+const vec2 CONST_UV[4] = vec2[](
vec2(+ 0.0f, + 0.0f),
- vec2(+ 1.0f, + 1.0f)
+ vec2(+ 0.0f, + 1.0f),
+ vec2(+ 1.0f, + 1.0f),
+ vec2(+ 1.0f, + 0.0f)
);
diff --git a/src/main/resources/assets/minosoft/rendering/shader/world/border/border.vsh b/src/main/resources/assets/minosoft/rendering/shader/world/border/border.vsh
index 0fb35a12d..61409d4b6 100644
--- a/src/main/resources/assets/minosoft/rendering/shader/world/border/border.vsh
+++ b/src/main/resources/assets/minosoft/rendering/shader/world/border/border.vsh
@@ -14,19 +14,21 @@
#version 330 core
layout (location = 0) in vec3 vinPosition;
-layout (location = 1) in float uvIndex;
+layout (location = 1) in float vinUVIndex;
+layout (location = 2) in float vinWidth;
uniform mat4 uViewProjectionMatrix;
uniform uint uIndexLayer;
uniform float uTextureOffset;
-uniform float uRadius;
-uniform vec2 uCenter;
-uniform float uCameraHeight;
+
+uniform vec3 uCameraPosition;
flat out uint finTextureIndex;
out vec3 finTextureCoordinates;
-out vec3 finFragmentPosition;
+out vec3 finFragmentPosition; // fog
+#define DENSITY 2.0f
+#define HEIGHT 150.0f
#include "minosoft:uv"
#include "minosoft:color"
@@ -34,23 +36,22 @@ out vec3 finFragmentPosition;
void main() {
vec3 position = vinPosition;
- position = position * uRadius;
if (position.y < 0.0f) {
- position.y = uCameraHeight - 300;
+ position.y = uCameraPosition.y - HEIGHT;
} else if (position.y > 0.0f) {
- position.y = uCameraHeight + 300;
+ position.y = uCameraPosition.y + HEIGHT;
}
- position.x += uCenter.x;
- position.z += uCenter.y;
gl_Position = uViewProjectionMatrix * vec4(position, 1.0f);
- finFragmentPosition = position;
finTextureIndex = uIndexLayer >> 28u;
- vec2 uv = CONST_UV[floatBitsToUint(uvIndex)];
- uv.x *= (uRadius / 5.0f);
- uv.y *= (300 / 5.0f);
- finTextureCoordinates = vec3(uv, ((uIndexLayer >> 12) & 0xFFFFu));
+ vec2 uv = CONST_UV[floatBitsToUint(vinUVIndex)];
+ uv.x *= (vinWidth / DENSITY); // TODO: insert width
+ uv.y *= (HEIGHT / DENSITY);
+
+ finTextureCoordinates = vec3(uv, ((uIndexLayer >> 12u) & 0xFFFFu));
finTextureCoordinates.x += uTextureOffset;
finTextureCoordinates.y += uTextureOffset;
+
+ finFragmentPosition = position.xyz;
}