From 35fd2eebb776a3a4e7351ccd3a72797258544c10 Mon Sep 17 00:00:00 2001 From: Moritz Zwerger Date: Sun, 22 Oct 2023 22:43:56 +0200 Subject: [PATCH] improve block entity ticking performance --- .../minosoft/data/entities/block/BlockEntity.kt | 2 +- .../data/entities/block/CampfireBlockEntity.kt | 10 +++++----- .../data/entities/block/MobSpawnerBlockEntity.kt | 4 ++-- .../data/entities/block/NoteBlockBlockEntity.kt | 4 ++-- .../bixilon/minosoft/data/world/chunk/ChunkSection.kt | 7 ++++++- .../minosoft/gui/rendering/chunk/mesh/ChunkMesh.kt | 2 +- .../gui/rendering/chunk/mesher/SolidSectionMesher.kt | 2 +- 7 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/data/entities/block/BlockEntity.kt b/src/main/java/de/bixilon/minosoft/data/entities/block/BlockEntity.kt index 8d031100e..f9af33c40 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/block/BlockEntity.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/block/BlockEntity.kt @@ -29,7 +29,7 @@ abstract class BlockEntity( open fun updateNBT(nbt: JsonObject) = Unit - open fun tick(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, random: Random) = Unit + open fun tick(connection: PlayConnection, state: BlockState, position: Vec3i, random: Random) = Unit open fun getRenderer(context: RenderContext, state: BlockState, position: Vec3i, light: Int): BlockEntityRenderer? { if (this.renderer?.state != state) { diff --git a/src/main/java/de/bixilon/minosoft/data/entities/block/CampfireBlockEntity.kt b/src/main/java/de/bixilon/minosoft/data/entities/block/CampfireBlockEntity.kt index b1f8cba19..37566f93d 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/block/CampfireBlockEntity.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/block/CampfireBlockEntity.kt @@ -63,18 +63,18 @@ class CampfireBlockEntity(connection: PlayConnection) : BlockEntity(connection) } - override fun tick(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, random: Random) { - if (blockState.block !is CampfireBlock || !blockState.isLit()) { + override fun tick(connection: PlayConnection, state: BlockState, position: Vec3i, random: Random) { + if (state.block !is CampfireBlock || !state.isLit()) { return } if (random.nextFloat() < 0.11f) { for (i in 0 until random.nextInt(2) + 2) { - blockState.block.spawnSmokeParticles(connection, blockState, blockPosition, false, random) + state.block.spawnSmokeParticles(connection, state, position, false, random) } } - val facing = blockState.getFacing().campfireId + val facing = state.getFacing().campfireId for ((index, item) in items.withIndex()) { item ?: continue @@ -83,7 +83,7 @@ class CampfireBlockEntity(connection: PlayConnection) : BlockEntity(connection) } val direction = HORIZONTAL[Math.floorMod(index + facing, Directions.SIDES.size)] - val position = Vec3d(blockPosition) + Vec3d( + val position = Vec3d(position) + Vec3d( 0.5f - direction.vector.x * DIRECTION_OFFSET + direction.rotateY().vector.x * DIRECTION_OFFSET, 0.5f, 0.5f - direction.vector.z * DIRECTION_OFFSET + direction.rotateY().vector.z * DIRECTION_OFFSET, diff --git a/src/main/java/de/bixilon/minosoft/data/entities/block/MobSpawnerBlockEntity.kt b/src/main/java/de/bixilon/minosoft/data/entities/block/MobSpawnerBlockEntity.kt index 6bcf99c88..9dd74cbbf 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/block/MobSpawnerBlockEntity.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/block/MobSpawnerBlockEntity.kt @@ -59,8 +59,8 @@ class MobSpawnerBlockEntity(connection: PlayConnection) : BlockEntity(connection // ToDo: {MaxNearbyEntities: 6s, RequiredPlayerRange: 16s, SpawnCount: 4s, x: -80, y: 4, SpawnData: {id: "minecraft:zombie"}, z: 212, id: "minecraft:mob_spawner", MaxSpawnDelay: 800s, SpawnRange: 4s, Delay: 0s, MinSpawnDelay: 200s} } - override fun tick(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, random: Random) { - spawnParticles(blockPosition, random) + override fun tick(connection: PlayConnection, state: BlockState, position: Vec3i, random: Random) { + spawnParticles(position, random) } companion object : BlockEntityFactory { diff --git a/src/main/java/de/bixilon/minosoft/data/entities/block/NoteBlockBlockEntity.kt b/src/main/java/de/bixilon/minosoft/data/entities/block/NoteBlockBlockEntity.kt index 3befa8c9d..8e2348f4f 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/block/NoteBlockBlockEntity.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/block/NoteBlockBlockEntity.kt @@ -57,7 +57,7 @@ class NoteBlockBlockEntity(connection: PlayConnection) : BlockEntity(connection) // ToDo: Play sound? } - override fun tick(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, random: Random) { + override fun tick(connection: PlayConnection, state: BlockState, position: Vec3i, random: Random) { if (!showParticleNextTick) { return } @@ -65,7 +65,7 @@ class NoteBlockBlockEntity(connection: PlayConnection) : BlockEntity(connection) noteParticleType?.let { - connection.world += NoteParticle(connection, blockPosition.toVec3d + Vec3d(0.5, 1.2, 0.5), blockState.getNote() / 24.0f, it.default()) + connection.world += NoteParticle(connection, position.toVec3d + Vec3d(0.5, 1.2, 0.5), state.getNote() / 24.0f, it.default()) } } diff --git a/src/main/java/de/bixilon/minosoft/data/world/chunk/ChunkSection.kt b/src/main/java/de/bixilon/minosoft/data/world/chunk/ChunkSection.kt index c9246e7e5..ad43ed312 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/chunk/ChunkSection.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/chunk/ChunkSection.kt @@ -46,16 +46,21 @@ class ChunkSection( if (blockEntities.isEmpty) { return } + val offset = Vec3i.of(chunkPosition, sectionHeight) + val position = Vec3i() + acquire() val min = blockEntities.minPosition val max = blockEntities.maxPosition for (y in min.y..max.y) { + position.y = offset.y + y for (z in min.z..max.z) { + position.z = offset.z + z for (x in min.x..max.x) { val index = getIndex(x, y, z) val entity = blockEntities[index] ?: continue val state = blocks[index] ?: continue - val position = Vec3i.of(chunkPosition, sectionHeight, index.indexPosition) + position.x = offset.x + x entity.tick(connection, state, position, random) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/ChunkMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/ChunkMesh.kt index 99f9aa52a..4b9b4daf5 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/ChunkMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/ChunkMesh.kt @@ -32,7 +32,7 @@ class ChunkMesh( var translucentMesh: SingleChunkMesh? = SingleChunkMesh(context, if (smallMesh) 3000 else 10000, onDemand = true) var transparentMesh: SingleChunkMesh? = SingleChunkMesh(context, if (smallMesh) 3000 else 20000, onDemand = true) var textMesh: SingleChunkMesh? = SingleChunkMesh(context, if (smallMesh) 5000 else 50000, onDemand = true) - var blockEntities: List>? = null + var blockEntities: ArrayList>? = null // used for frustum culling val minPosition = Vec3i(16) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/SolidSectionMesher.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/SolidSectionMesher.kt index ee1279cc9..d9c94f77c 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/SolidSectionMesher.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/SolidSectionMesher.kt @@ -62,7 +62,7 @@ class SolidSectionMesher( val isHighestSection = sectionHeight == chunk.maxSection val blocks = section.blocks val sectionLight = section.light - val entities: MutableList> = ArrayList() + val entities: ArrayList> = ArrayList(section.blockEntities.count) val position = BlockPosition() val neighbourBlocks: Array = arrayOfNulls(Directions.SIZE)