Skip to content

Commit f139c9c

Browse files
committed
Revert "[EntityCulling] opt: Grid partition entities", still keep some slight opt
1 parent 39d6c11 commit f139c9c

File tree

1 file changed

+49
-81
lines changed
  • bukkit/version/v1_18/src/main/kotlin/io/github/rothes/esu/bukkit/module/networkthrottle/entityculling/v1_18

1 file changed

+49
-81
lines changed

bukkit/version/v1_18/src/main/kotlin/io/github/rothes/esu/bukkit/module/networkthrottle/entityculling/v1_18/RaytraceHandlerImpl.kt

Lines changed: 49 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,8 @@ import io.github.rothes.esu.core.util.UnsafeUtils.usBooleanAccessor
2525
import io.github.rothes.esu.core.util.extension.math.floorI
2626
import io.github.rothes.esu.core.util.extension.math.frac
2727
import io.github.rothes.esu.core.util.extension.math.square
28-
import it.unimi.dsi.fastutil.Hash
2928
import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap
3029
import it.unimi.dsi.fastutil.ints.IntArrayList
31-
import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap
3230
import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap
3331
import kotlinx.coroutines.*
3432
import net.minecraft.server.level.ServerLevel
@@ -61,7 +59,6 @@ import kotlin.time.Duration.Companion.seconds
6159
object RaytraceHandlerImpl: RaytraceHandler<RaytraceHandlerImpl.RaytraceConfig, EmptyConfiguration>() {
6260

6361
private const val COLLISION_EPSILON = 1E-7
64-
private const val GRID_SIZE = 5
6562
private val INIT_SECTION: Array<LevelChunkSection> = arrayOf()
6663
private val ENTITY_TYPES: Int
6764

@@ -197,7 +194,7 @@ object RaytraceHandlerImpl: RaytraceHandler<RaytraceHandlerImpl.RaytraceConfig,
197194
}
198195
val entities = entityMap.int2ReferenceEntrySet().map {
199196
val squaredRange = (it.intKey + 8).square() // Add extra 8 blocks
200-
SlicedEntities(squaredRange, it.value)
197+
SortedEntities(squaredRange, it.value)
201198
}
202199
/* Sort entities by tracking range */
203200

@@ -271,80 +268,67 @@ object RaytraceHandlerImpl: RaytraceHandler<RaytraceHandlerImpl.RaytraceConfig,
271268

272269
}
273270

274-
fun tickPlayer(player: ServerPlayer, bukkit: Player, userCullData: UserCullData, level: ServerLevel, collected: List<SlicedEntities>) {
271+
fun tickPlayer(player: ServerPlayer, bukkit: Player, userCullData: UserCullData, level: ServerLevel, entities: List<SortedEntities>) {
275272
val viewDistanceSquared = (bukkit.viewDistance + 1).square() shl 8
276273

277-
val shouldCull = userCullData.shouldCull
278-
fun predicatePlayerPos(): Vec3? {
279-
if (shouldCull && config.predicatePlayerPositon) {
280-
val velocity = playerVelocityGetter.getPlayerMoveVelocity(player)
281-
if (velocity.lengthSqr() >= 0.06) { // Threshold for sprinting
282-
var x = player.x
283-
var y = player.eyeY
284-
var z = player.z
285-
286-
var vx = velocity.x
287-
var vy = velocity.y
288-
var vz = velocity.z
289-
290-
for (i in 0 until 3) {
291-
x += vx
292-
y += vy
293-
z += vz
294-
295-
vx *= 0.91f
296-
vy *= 0.98f
297-
vz *= 0.91f
298-
}
299-
return Vec3(x, y, z)
300-
}
301-
}
302-
return null
303-
}
304-
val predicatedPlayerPos = predicatePlayerPos()
305-
306-
var tickedEntities = 0
307-
308274
val playerX = player.x
309275
val playerY = player.y
310276
val playerZ = player.z
311277

312-
for (sorted in collected) {
313-
val range = min(sorted.trackRangeSquared, viewDistanceSquared)
314-
val sqrt = sqrt(range.toDouble())
315-
for (x in (playerX - sqrt).gridIndex().toLong() .. (playerX + sqrt).gridIndex()) {
316-
for (z in (playerZ - sqrt).gridIndex().toLong() .. (playerZ + sqrt).gridIndex()) {
317-
val index = x and (z shl Int.SIZE_BITS)
318-
val entities = sorted.slices.get(index) ?: continue
319-
for (entity in entities) {
320-
val dist = (playerX - entity.x).square() + (playerZ - entity.z).square()
321-
if (dist > range) continue
322-
323-
tickedEntities++
324-
325-
if (
326-
!shouldCull
327-
|| entity.isCurrentlyGlowing
328-
|| config.visibleEntityTypes.contains(entity.type)
329-
|| dist + (playerY - entity.y).square() <= forceVisibleDistanceSquared
330-
) {
331-
userCullData.setCulled(entity.bukkitEntity, entity.id, false)
332-
continue
333-
}
278+
val shouldCull = userCullData.shouldCull
279+
val predicatedPlayerPos = if (shouldCull && config.predicatePlayerPositon) {
280+
val velocity = playerVelocityGetter.getPlayerMoveVelocity(player)
281+
if (velocity.lengthSqr() >= 0.06) { // Threshold for sprinting
282+
var x = playerX
283+
var y = player.eyeY
284+
var z = playerZ
285+
286+
var vx = velocity.x
287+
var vy = velocity.y
288+
var vz = velocity.z
289+
290+
for (i in 0 until 3) {
291+
x += vx
292+
y += vy
293+
z += vz
294+
295+
vx *= 0.91f
296+
vy *= 0.98f
297+
vz *= 0.91f
298+
}
299+
Vec3(x, y, z)
300+
} else null
301+
} else null
334302

335-
userCullData.setCulled(entity.bukkitEntity, entity.id, raytrace(player, predicatedPlayerPos, entity, level))
336-
}
303+
var tickedEntities = 0
304+
305+
for ((trackRange, entities) in entities) {
306+
val maxRange = min(trackRange, viewDistanceSquared)
307+
for (entity in entities) {
308+
if (entity === player) continue
309+
val pos = entity.position()
310+
val dist = (playerX - pos.x).square() + (playerZ - pos.z).square()
311+
if (dist > maxRange) continue
312+
313+
tickedEntities++
314+
315+
if (
316+
!shouldCull
317+
|| entity.isCurrentlyGlowing
318+
|| config.visibleEntityTypes.contains(entity.type)
319+
|| dist + (playerY - pos.y).square() <= forceVisibleDistanceSquared
320+
) {
321+
userCullData.setCulled(entity.bukkitEntity, entity.id, false)
322+
continue
337323
}
324+
325+
userCullData.setCulled(entity.bukkitEntity, entity.id, raytrace(player, predicatedPlayerPos, entity, level))
338326
}
339327
}
340328
userCullData.shouldCull = tickedEntities >= config.cullThreshold
341329
userCullData.tick()
342330
}
343331

344-
private fun Location.toVec3(): Vec3 {
345-
return Vec3(x, y, z)
346-
}
347-
348332
fun raytrace(player: ServerPlayer, predPlayer: Vec3?, entity: Entity, level: ServerLevel): Boolean {
349333
val from = player.eyePosition
350334
val aabb = entity.boundingBox
@@ -622,23 +606,7 @@ object RaytraceHandlerImpl: RaytraceHandler<RaytraceHandlerImpl.RaytraceConfig,
622606
}
623607
}
624608

625-
class SlicedEntities(val trackRangeSquared: Int, entities: List<Entity>) {
626-
627-
val slices = Long2ReferenceOpenHashMap<MutableList<Entity>>(16, Hash.VERY_FAST_LOAD_FACTOR)
628-
629-
init {
630-
for (entity in entities) {
631-
val id = entity.x.gridIndex().toLong() and (entity.z.gridIndex().toLong() shl Int.SIZE_BITS)
632-
val get = slices.get(id)
633-
if (get != null)
634-
get.add(entity)
635-
else
636-
slices.put(id, ArrayList<Entity>(16).also { it.add(entity) })
637-
}
638-
}
639-
}
640-
641-
private fun Double.gridIndex() = floorI() shr GRID_SIZE
609+
data class SortedEntities(val trackRangeSquared: Int, val entities: List<Entity>)
642610

643611
data class RaytraceConfig(
644612
@Comment("Asynchronous threads used to calculate visibility. More to update faster.")

0 commit comments

Comments
 (0)