Skip to content
Draft
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
Date: Sun, 7 Nov 2077 00:00:00 +1400
Subject: [PATCH] Raytrace Entity Tracker

Original project: https://github.com/tr7zw/EntityCulling
Original license: Custom License

Original project: https://github.com/LogisticsCraft/OcclusionCulling
Original license: MIT

Ported by: https://github.com/LuminolMC/Luminol
Fixed and updated by: https://github.com/Winds-Studio/Leaf

TODO:
Check diff https://github.com/tr7zw/EntityCulling/compare/5774b56c6d7881fe3407ab80b662b94150dffafc...main

EntityCulling commit: null

diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
index 9803c395fce103cb7bc746f43a017ff9ed99728c..1cdc7f01f99355c2d9ebd6b76654c45921c20cff 100644
--- a/net/minecraft/server/level/ChunkMap.java
+++ b/net/minecraft/server/level/ChunkMap.java
@@ -1487,7 +1487,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
double d1 = vec3_dx * vec3_dx + vec3_dz * vec3_dz; // Paper
double d2 = d * d;
// Paper start - Configurable entity tracking range by Y
- boolean flag = d1 <= d2;
+ boolean flag = d1 <= d2 && !entity.isCulled(player); // Leaf - Raytrace Entity Tracker
if (flag && level.paperConfig().entities.trackingRangeY.enabled) {
double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1);
if (rangeY != -1) {
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index e7b375720c1bb78a9c3edf6d49c973eba1fcf115..0df23c381891fc9b8362b01196bfcc56c2e1903d 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -145,7 +145,7 @@ import net.minecraft.world.waypoints.WaypointTransmitter;
import org.jetbrains.annotations.Contract;
import org.slf4j.Logger;

-public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder, DataComponentGetter, ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity, ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity { // Paper - rewrite chunk system // Paper - optimise entity tracker
+public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder, DataComponentGetter, ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity, ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity, dev.tr7zw.entityculling.versionless.access.Cullable { // Paper - rewrite chunk system // Paper - optimise entity tracker // Leaf - Raytrace entity tracker
public static javax.script.ScriptEngine scriptEngine = new javax.script.ScriptEngineManager().getEngineByName("rhino"); // Purpur - Configurable entity base attributes
// CraftBukkit start
private static final int CURRENT_LEVEL = 2;
@@ -5296,6 +5296,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return;
}
// Paper end - rewrite chunk system
+ dev.tr7zw.entityculling.CullTask.onEntityRemoval(this); // Leaf - Raytrace entity tracker
org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit
final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers
if (this.removalReason == null) {
@@ -5600,4 +5601,36 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return this.distanceToSqr(entity.position());
}
// Leaf end - Optimize Entity distanceToSqr
+
+ // Leaf start - Raytrace entity tracker
+ private long lastTime = 0;
+
+ @Override
+ public void setTimeout() {
+ this.lastTime = System.currentTimeMillis() + 1000;
+ }
+
+ @Override
+ public boolean isForcedVisible() {
+ return this.lastTime > System.currentTimeMillis();
+ }
+
+ @Override
+ public void setCulled(boolean value, Player player) {
+ dev.tr7zw.entityculling.CullTask task = player.cullTask;
+ if (task == null) return;
+ task.setCulled(this, value);
+ if (!value) {
+ setTimeout();
+ }
+ }
+
+ @Override
+ public boolean isCulled(Player player) {
+ if (!org.dreeam.leaf.config.modules.misc.RaytraceTracker.enabled) return false;
+ dev.tr7zw.entityculling.CullTask task = player.cullTask;
+ if (task == null) return false;
+ return task.isEntityCulled(this);
+ }
+ // Leaf end - Raytrace entity tracker
}
diff --git a/net/minecraft/world/entity/EntityType.java b/net/minecraft/world/entity/EntityType.java
index e65b1818c49e1b7d04d5bcc912804c821f00bdbc..7ea2cdf57fc1b2d28b7b60f9beaa529640ebd4d5 100644
--- a/net/minecraft/world/entity/EntityType.java
+++ b/net/minecraft/world/entity/EntityType.java
@@ -1086,6 +1086,7 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
private final int clientTrackingRange;
private final int updateInterval;
public boolean dabEnabled = false; // Pufferfish
+ public boolean skipRaytraceCheck = false; // Leaf - Raytrace Entity Tracker
private final String descriptionId;
@Nullable
private Component description;
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
index 108ef0759e4060fc02d517175731f413c7e2532f..3dbe2fca96439f7202ffe9bd73b43d3f79f5223d 100644
--- a/net/minecraft/world/entity/player/Player.java
+++ b/net/minecraft/world/entity/player/Player.java
@@ -223,6 +223,11 @@ public abstract class Player extends LivingEntity {
public int burpDelay = 0; // Purpur - Burp delay
public boolean canPortalInstant = false; // Purpur - Add portal permission bypass
public int sixRowEnderchestSlotCount = -1; // Purpur - Barrels and enderchests 6 rows
+ // Leaf start - Raytrace Entity Tracker
+ @Nullable public dev.tr7zw.entityculling.CullTask cullTask;
+ @Nullable private Level lastCullWorld;
+ private final boolean needToCull = !(this instanceof org.leavesmc.leaves.replay.ServerPhotographer);
+ // Leaf end - Raytrace Entity Tracker

// CraftBukkit start
public boolean fauxSleeping;
@@ -320,6 +325,37 @@ public abstract class Player extends LivingEntity {
}
// Purpur end - Burp delay

+ // Leaf start - Raytrace Entity Tracker
+ if (this.needToCull) {
+ if (!org.dreeam.leaf.config.modules.misc.RaytraceTracker.enabled) {
+ if (this.cullTask != null) {
+ this.cullTask.signalStop();
+ this.cullTask = null;
+ }
+ } else {
+ Level currLevel = this.level();
+ boolean needsUpdate = this.cullTask == null || this.lastCullWorld != currLevel;
+
+ if (needsUpdate) {
+ if (this.cullTask != null) {
+ this.cullTask.signalStop();
+ }
+ final com.logisticscraft.occlusionculling.OcclusionCullingInstance culling = new com.logisticscraft.occlusionculling.OcclusionCullingInstance(
+ org.dreeam.leaf.config.modules.misc.RaytraceTracker.maxTraceDistance,
+ new dev.tr7zw.entityculling.DefaultChunkDataProvider(currLevel)
+ );
+ this.cullTask = new dev.tr7zw.entityculling.CullTask(
+ culling,
+ this,
+ org.dreeam.leaf.config.modules.misc.RaytraceTracker.boundingBoxLimit,
+ org.dreeam.leaf.config.modules.misc.RaytraceTracker.traceInterval
+ );
+ this.cullTask.setup();
+ this.lastCullWorld = currLevel;
+ }
+ }
+ }
+ // Leaf end - Raytrace Entity Tracker
this.noPhysics = this.isSpectator();
if (this.isSpectator() || this.isPassenger()) {
this.setOnGround(false);
@@ -1493,6 +1529,12 @@ public abstract class Player extends LivingEntity {
if (this.containerMenu != null && this.hasContainerOpen()) {
this.doCloseContainer();
}
+ // Leaf start - Raytrace Entity Tracker
+ if (this.cullTask != null) {
+ this.cullTask.signalStop();
+ this.cullTask = null;
+ }
+ // Leaf end - Raytrace Entity Tracker
}

@Override
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
index 2a1c89bb6712c97ad48b9f64c26f36afe8c811e4..3b3199b0bb2729ac3a8dd08467a9b6e6ebdbda1e 100644
--- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java
@@ -1185,6 +1185,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
}
// Imanity end - AntiXraySDK integration
this.chunkPacketBlockController.onBlockChange(this, pos, state, blockState, flags, recursionLeft); // Paper - Anti-Xray
+ dev.tr7zw.entityculling.CullTask.onBlockChange(this, pos); // Leaf - Raytrace Entity Tracker
// CraftBukkit end
if (blockState == null) {
// CraftBukkit start - remove blockstate if failed (or the same)
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.logisticscraft.occlusionculling;

import com.logisticscraft.occlusionculling.util.Vec3d;

public interface DataProvider {

/**
* Prepares the requested chunk. Returns true if the chunk is ready, false when
* not loaded. Should not reload the chunk when the x and y are the same as the
* last request!
*
* @param chunkX
* @param chunkZ
* @return
*/
boolean prepareChunk(int chunkX, int chunkZ);

/**
* Location is inside the chunk.
*
* @param x
* @param y
* @param z
* @return
*/
boolean isOpaqueFullCube(int x, int y, int z);

default void cleanup() {
}

default void checkingPosition(Vec3d[] targetPoints, int size, Vec3d viewerPosition) {
}

}
Loading