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 ff3485447..23b7487ec 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 @@ -112,12 +112,13 @@ class MatrixHandler( shaking.draw() val fov = calculateFOV() val view = camera.view.view - val eyePosition = view.matrixPosition + val eyePosition = view.eyePosition + val matrixPosition = view.matrixPosition 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 +127,18 @@ class MatrixHandler( previousFOV = fov updateFront(front) - updateViewMatrix(eyePosition, front) + updateViewMatrix(matrixPosition, front) updateViewProjectionMatrix() - val usePosition = if (view.updateFrustum) eyePosition else Vec3(connection.camera.entity.renderInfo.eyePosition - camera.offset.offset) + 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 +149,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 index 9d1cbe9c6..956b5e673 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/WorldOffset.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/WorldOffset.kt @@ -17,11 +17,10 @@ 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.Vec3iUtil.EMPTY import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition class WorldOffset(private val camera: Camera) : Drawable { - var offset by observed(Vec3i.EMPTY) + var offset by observed(Vec3i(100, 100, 100)) private set override fun draw() { 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/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/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/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/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..effcc7b3d 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 @@ -113,7 +113,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 } @@ -123,7 +125,7 @@ class BlockOutlineRenderer( val mesh = LineMesh(context) - val blockOffset = target.blockPosition.toVec3d + val blockOffset = offsetPosition.toVec3d if (target.state.block is RandomOffsetBlock) { target.state.block.randomOffset?.let { blockOffset += target.blockPosition.getWorldOffset(it) } } @@ -139,7 +141,7 @@ class BlockOutlineRenderer( this.nextMesh = mesh - this.position = target.blockPosition + this.position = offsetPosition this.state = target.state this.reload = false }