From ab6ee0bb165c98a640ce0444eaa1468943a8603b Mon Sep 17 00:00:00 2001 From: Moritz Zwerger Date: Wed, 15 Nov 2023 23:52:37 +0100 Subject: [PATCH] particle: cache chunk, chunk iterating improvements --- .../data/world/iterator/WorldIterator.kt | 6 ++++- .../entities/feature/block/BlockFeature.kt | 2 +- .../entities/feature/item/ItemFeature.kt | 4 ++-- .../gui/rendering/particle/types/Particle.kt | 23 ++++++++++++++++++- .../particle/types/render/RenderParticle.kt | 2 +- 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/data/world/iterator/WorldIterator.kt b/src/main/java/de/bixilon/minosoft/data/world/iterator/WorldIterator.kt index 8de05e71d..c2353e2f1 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/iterator/WorldIterator.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/iterator/WorldIterator.kt @@ -35,11 +35,13 @@ class WorldIterator( private var chunk: Chunk? = null, ) : Iterator { private var next: BlockPair? = null + private var revision = -1 constructor(aabb: AABB, world: World, chunk: Chunk? = null) : this(aabb.positions(), world, chunk) private fun update(): Boolean { + if (world.chunks.chunks.unsafe.isEmpty()) return false if (!iterator.hasNext()) return false var chunk = this.chunk @@ -53,7 +55,9 @@ class WorldIterator( chunkPosition.assignChunkPosition(position) if (chunk == null) { - chunk = world.chunks[chunkPosition] ?: continue // TODO: Don't query same chunk multiple times + if (revision == world.chunks.revision) continue // previously found no chunk, can not find it now + this.revision = world.chunks.revision + chunk = world.chunks[chunkPosition] ?: continue } else if (chunk.chunkPosition != chunkPosition) { offset.x = chunkPosition.x - chunk.chunkPosition.x offset.y = chunkPosition.y - chunk.chunkPosition.y diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/block/BlockFeature.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/block/BlockFeature.kt index deecb2b51..1c3b303de 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/block/BlockFeature.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/block/BlockFeature.kt @@ -71,7 +71,7 @@ open class BlockFeature( } override fun draw(mesh: BlockMesh) { - renderer.renderer.context.system.reset(faceCulling = false) + renderer.renderer.context.system.set(EntityLayer.Translucent.settings) val shader = renderer.renderer.features.block.shader draw(mesh, shader) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/item/ItemFeature.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/item/ItemFeature.kt index 9c86f6140..c18498cb8 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/item/ItemFeature.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/item/ItemFeature.kt @@ -107,7 +107,7 @@ open class ItemFeature( } override fun draw(mesh: BlockMesh) { - renderer.renderer.context.system.reset(faceCulling = false) + renderer.renderer.context.system.set(EntityLayer.Translucent.settings) val shader = renderer.renderer.features.block.shader draw(mesh, shader) } @@ -132,7 +132,7 @@ open class ItemFeature( EXTREME(48.0), ; - val distance = distance * distance + val distance = distance * distance * distance companion object { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt index c3be05a0f..c8fb9d430 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt @@ -21,6 +21,7 @@ import de.bixilon.minosoft.data.physics.PhysicsEntity import de.bixilon.minosoft.data.registries.blocks.shapes.collision.context.ParticleCollisionContext import de.bixilon.minosoft.data.registries.particle.data.ParticleData import de.bixilon.minosoft.data.registries.shapes.aabb.AABB +import de.bixilon.minosoft.data.world.chunk.chunk.Chunk import de.bixilon.minosoft.gui.rendering.particle.ParticleFactory import de.bixilon.minosoft.gui.rendering.particle.ParticleMesh import de.bixilon.minosoft.gui.rendering.util.VecUtil.plusAssign @@ -52,6 +53,9 @@ abstract class Particle( protected val random = Random() private var lastTickTime = -1L + private var chunk: Chunk? = null + private var chunkRevision = -1 + // ageing var dead = false var age: Int = 0 @@ -89,6 +93,23 @@ abstract class Particle( aabb = AABB(Vec3d(x, aabb.min.y, z), Vec3d(x + spacing.x, aabb.min.y + spacing.y, z + spacing.z)) } + protected fun getChunk(): Chunk? { + val revision = connection.world.chunks.revision + var chunk = this.chunk + + if (chunk != null) { + if (chunk.chunkPosition == this.chunkPosition) return chunk + chunk = chunk.neighbours.trace(chunkPosition - chunk.chunkPosition) + } + if (chunk == null && revision != this.chunkRevision) { + chunk = connection.world.chunks[chunkPosition] + this.chunk = chunk + this.chunkRevision = revision + } + + return chunk + } + init { this.velocity += { (random.nextDouble() * 2.0 - 1.0) * MAGIC_VELOCITY_CONSTANT } @@ -117,7 +138,7 @@ abstract class Particle( private fun collide(movement: Vec3d): Vec3d { val aabb = aabb + movement val context = ParticleCollisionContext(this) - val collisions = connection.world.collectCollisions(context, movement, aabb, null) // TODO: cache chunk + val collisions = connection.world.collectCollisions(context, movement, aabb, getChunk()) val adjusted = collide(movement, aabb, collisions) if (adjusted.y != movement.y) { onGround = true diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/RenderParticle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/RenderParticle.kt index 997fed166..2800027d0 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/RenderParticle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/RenderParticle.kt @@ -43,7 +43,7 @@ abstract class RenderParticle(connection: PlayConnection, position: Vec3d, veloc var maxSkyLight = 0 val chunkPosition = position.chunkPosition - val chunk = connection.world.chunks[chunkPosition] ?: return maxBlockLight + val chunk = getChunk() ?: return maxBlockLight val offset = Vec2i.EMPTY val inChunk = Vec3i()