rendering: use position offset

This commit is contained in:
Bixilon 2023-05-23 17:08:44 +02:00
parent 1556fed1e4
commit 4794d1cf61
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
9 changed files with 41 additions and 31 deletions

View File

@ -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.CameraPositionShader
import de.bixilon.minosoft.gui.rendering.shader.types.ViewProjectionShader 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.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.chunkPosition
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.sectionHeight import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.sectionHeight
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
@ -45,9 +45,9 @@ class MatrixHandler(
private val connection = context.connection private val connection = context.connection
private val profile = context.connection.profiles.rendering.camera private val profile = context.connection.profiles.rendering.camera
val shaking = CameraShaking(camera, profile.shaking) 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 previousFOV = 0.0f
private var front = Vec3.EMPTY private var front = Vec3.EMPTY
@ -112,12 +112,13 @@ class MatrixHandler(
shaking.draw() shaking.draw()
val fov = calculateFOV() val fov = calculateFOV()
val view = camera.view.view val view = camera.view.view
val eyePosition = view.matrixPosition val eyePosition = view.eyePosition
val matrixPosition = view.matrixPosition
val front = view.front 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 return
} }
this.eyePosition = eyePosition this.matrixPosition = matrixPosition
this.front = front this.front = front
val cameraBlockPosition = eyePosition.blockPosition val cameraBlockPosition = eyePosition.blockPosition
if (fov != previousFOV) { if (fov != previousFOV) {
@ -126,17 +127,18 @@ class MatrixHandler(
previousFOV = fov previousFOV = fov
updateFront(front) updateFront(front)
updateViewMatrix(eyePosition, front) updateViewMatrix(matrixPosition, front)
updateViewProjectionMatrix() 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) { if (view.updateFrustum) {
frustum.recalculate() frustum.recalculate()
camera.visibilityGraph.updateCamera(cameraBlockPosition.chunkPosition, cameraBlockPosition.sectionHeight) camera.visibilityGraph.updateCamera(cameraBlockPosition.chunkPosition, cameraBlockPosition.sectionHeight)
} }
connection.events.fire(CameraPositionChangeEvent(context, usePosition)) connection.events.fire(CameraPositionChangeEvent(context, useEyePosition))
connection.events.fire( connection.events.fire(
CameraMatrixChangeEvent( CameraMatrixChangeEvent(
@ -147,7 +149,7 @@ class MatrixHandler(
) )
) )
updateShaders(usePosition) updateShaders(useMatrixPosition)
upToDate = true upToDate = true
} }

View File

@ -17,11 +17,10 @@ import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.kutil.observer.DataObserver.Companion.observed import de.bixilon.kutil.observer.DataObserver.Companion.observed
import de.bixilon.minosoft.data.world.World import de.bixilon.minosoft.data.world.World
import de.bixilon.minosoft.gui.rendering.renderer.drawable.Drawable 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 import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
class WorldOffset(private val camera: Camera) : Drawable { class WorldOffset(private val camera: Camera) : Drawable {
var offset by observed(Vec3i.EMPTY) var offset by observed(Vec3i(100, 100, 100))
private set private set
override fun draw() { override fun draw() {

View File

@ -25,6 +25,7 @@ import de.bixilon.kutil.enums.ValuesEnum
import de.bixilon.minosoft.data.registries.shapes.aabb.AABB import de.bixilon.minosoft.data.registries.shapes.aabb.AABB
import de.bixilon.minosoft.data.world.World import de.bixilon.minosoft.data.world.World
import de.bixilon.minosoft.gui.rendering.RenderConstants 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.camera.MatrixHandler
import de.bixilon.minosoft.gui.rendering.util.VecUtil.of import de.bixilon.minosoft.gui.rendering.util.VecUtil.of
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.EMPTY 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 // Big thanks to: https://gist.github.com/podgorskiy/e698d18879588ada9014768e3e82a644
class Frustum( class Frustum(
private val camera: Camera,
private val matrixHandler: MatrixHandler, private val matrixHandler: MatrixHandler,
private val world: World, 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 { 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 min = base + minPosition
val max = base + maxPosition + 1 val max = base + maxPosition + 1
return containsRegion(Vec3(min), Vec3(max)) return containsRegion(Vec3(min), Vec3(max))
@ -160,18 +163,21 @@ class Frustum(
fun containsChunk(chunkPosition: Vec2i): Boolean { fun containsChunk(chunkPosition: Vec2i): Boolean {
val dimension = world.dimension val dimension = world.dimension
val minY = dimension.minY val offset = camera.offset.offset
val maxY = dimension.maxY val minY = dimension.minY - offset.y
val base = Vec2i(chunkPosition.x * ProtocolDefinition.SECTION_WIDTH_X, chunkPosition.y * ProtocolDefinition.SECTION_WIDTH_Z) 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)) 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 { 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 { 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<Vec3>, val planes: Array<Vec4>) private data class FrustumData(val normals: Array<Vec3>, val planes: Array<Vec4>)

View File

@ -13,13 +13,13 @@
package de.bixilon.minosoft.gui.rendering.events 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 import de.bixilon.minosoft.gui.rendering.RenderContext
class CameraPositionChangeEvent( class CameraPositionChangeEvent(
context: RenderContext, context: RenderContext,
newPosition: Vec3, newPosition: Vec3d,
) : RenderEvent(context) { ) : RenderEvent(context) {
val newPosition: Vec3 = newPosition val newPosition: Vec3d = newPosition
get() = Vec3(field) get() = Vec3d(field)
} }

View File

@ -35,9 +35,10 @@ class ParticleMesh(context: RenderContext, data: AbstractFloatList) : Mesh(conte
} }
val maxTransformedUV = texture.renderData.transformUV(uvMax) val maxTransformedUV = texture.renderData.transformUV(uvMax)
val data = data val data = data
data.add(position.x.toFloat()) val offset = context.camera.offset.offset
data.add(position.y.toFloat()) data.add((position.x - offset.x).toFloat())
data.add(position.z.toFloat()) data.add((position.y - offset.y).toFloat())
data.add((position.z - offset.z).toFloat())
data.add(minTransformedUV) data.add(minTransformedUV)
data.add(maxTransformedUV) data.add(maxTransformedUV)
data.add(texture.renderData.shaderTextureId.buffer()) data.add(texture.renderData.shaderTextureId.buffer())

View File

@ -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.SkyChildRenderer
import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer 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.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.Vec3Util.interpolateLinear
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.blockPosition
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
import java.util.* import java.util.*
import kotlin.math.PI import kotlin.math.PI

View File

@ -38,7 +38,7 @@ class DoubleChestRenderer(
light: Int, light: Int,
) : StorageBlockEntityRenderer<StorageBlockEntity>( ) : StorageBlockEntityRenderer<StorageBlockEntity>(
blockState, blockState,
SkeletalInstance(context, model, blockPosition.toVec3, (blockState.getFacing()).rotatedMatrix), SkeletalInstance(context, model, (blockPosition - context.camera.offset.offset).toVec3, (blockState.getFacing()).rotatedMatrix),
light, light,
) { ) {

View File

@ -38,7 +38,7 @@ class SingleChestRenderer(
light: Int, light: Int,
) : StorageBlockEntityRenderer<StorageBlockEntity>( ) : StorageBlockEntityRenderer<StorageBlockEntity>(
blockState, blockState,
SkeletalInstance(context, model, blockPosition.toVec3, blockState.getFacing().rotatedMatrix), SkeletalInstance(context, model, (blockPosition - context.camera.offset.offset).toVec3, blockState.getFacing().rotatedMatrix),
light, light,
) { ) {

View File

@ -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 return
} }
@ -123,7 +125,7 @@ class BlockOutlineRenderer(
val mesh = LineMesh(context) val mesh = LineMesh(context)
val blockOffset = target.blockPosition.toVec3d val blockOffset = offsetPosition.toVec3d
if (target.state.block is RandomOffsetBlock) { if (target.state.block is RandomOffsetBlock) {
target.state.block.randomOffset?.let { blockOffset += target.blockPosition.getWorldOffset(it) } target.state.block.randomOffset?.let { blockOffset += target.blockPosition.getWorldOffset(it) }
} }
@ -139,7 +141,7 @@ class BlockOutlineRenderer(
this.nextMesh = mesh this.nextMesh = mesh
this.position = target.blockPosition this.position = offsetPosition
this.state = target.state this.state = target.state
this.reload = false this.reload = false
} }