9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-20 07:29:17 +00:00

缓存是负优化

This commit is contained in:
XiaoMoMi
2025-11-29 02:13:06 +08:00
parent c59478e891
commit 19d1cb2a21
2 changed files with 2 additions and 60 deletions

View File

@@ -576,12 +576,11 @@ public class BukkitServerPlayer extends Player {
CullingData cullingData = cullableObject.cullable.cullingData(); CullingData cullingData = cullableObject.cullable.cullingData();
if (cullingData != null) { if (cullingData != null) {
Vec3d vec3d = LocationUtils.toVec3d(platformPlayer().getEyeLocation()); Vec3d vec3d = LocationUtils.toVec3d(platformPlayer().getEyeLocation());
boolean visible = this.culling.isVisible(cullingData, vec3d, vec3d); boolean visible = this.culling.isVisible(cullingData, vec3d);
cullableObject.setShown(this, visible); cullableObject.setShown(this, visible);
} else { } else {
cullableObject.setShown(this, true); cullableObject.setShown(this, true);
} }
this.culling.resetCache();
} }
long nano2 = System.nanoTime(); long nano2 = System.nanoTime();

View File

@@ -17,8 +17,6 @@ public final class EntityCulling {
private final MutableVec3d[] targetPoints = new MutableVec3d[MAX_SAMPLES]; private final MutableVec3d[] targetPoints = new MutableVec3d[MAX_SAMPLES];
private final int[] lastHitBlock = new int[MAX_SAMPLES * 3]; private final int[] lastHitBlock = new int[MAX_SAMPLES * 3];
private final boolean[] canCheckLastHitBlock = new boolean[MAX_SAMPLES]; private final boolean[] canCheckLastHitBlock = new boolean[MAX_SAMPLES];
// 相机附近的点位大概率会多次重复获取
private final long[] occlusionCache = new long[32 * 32 * 32 / 32];
private int hitBlockCount = 0; private int hitBlockCount = 0;
private int lastVisitChunkX = Integer.MAX_VALUE; private int lastVisitChunkX = Integer.MAX_VALUE;
private int lastVisitChunkZ = Integer.MAX_VALUE; private int lastVisitChunkZ = Integer.MAX_VALUE;
@@ -31,11 +29,7 @@ public final class EntityCulling {
} }
} }
public void resetCache() { public boolean isVisible(CullingData cullable, Vec3d cameraPos) {
Arrays.fill(this.occlusionCache, 0);
}
public boolean isVisible(CullingData cullable, Vec3d cameraPos, Vec3d playerHeadPos) {
// 情空标志位 // 情空标志位
Arrays.fill(this.canCheckLastHitBlock, false); Arrays.fill(this.canCheckLastHitBlock, false);
this.hitBlockCount = 0; this.hitBlockCount = 0;
@@ -282,32 +276,6 @@ public final class EntityCulling {
return false; return false;
} }
// 0 = 没缓存
// 1 = 没遮挡
// 2 = 有遮挡
private int getCacheState(int index) {
int arrayIndex = index / 32; // 获取数组下标
int offset = (index % 32) * 2; // 每个状态占2bit计算位偏移
if (arrayIndex >= 0 && arrayIndex < this.occlusionCache.length) {
long cacheValue = this.occlusionCache[arrayIndex];
// 提取2bit的状态值 (0-3)
return (int) ((cacheValue >> offset) & 0b11);
}
return 0; // 索引越界时返回默认状态
}
private void setCacheState(int index, int state) {
long[] cache = this.occlusionCache;
int arrayIndex = index / 32;
int offset = (index % 32) * 2;
if (arrayIndex >= 0 && arrayIndex < cache.length) {
long mask = ~(0b11L << offset); // 创建清除掩码
long newValue = (cache[arrayIndex] & mask) | ((state & 0b11L) << offset);
cache[arrayIndex] = newValue;
}
}
private boolean stepRay(int startingX, int startingY, int startingZ, private boolean stepRay(int startingX, int startingY, int startingZ,
double stepSizeX, double stepSizeY, double stepSizeZ, double stepSizeX, double stepSizeY, double stepSizeZ,
int remainingSteps, int remainingSteps,
@@ -321,37 +289,12 @@ public final class EntityCulling {
// 遍历射线路径上的所有方块(跳过最后一个目标方块) // 遍历射线路径上的所有方块(跳过最后一个目标方块)
for (; remainingSteps > 1; remainingSteps--) { for (; remainingSteps > 1; remainingSteps--) {
int cacheIndex = getCacheIndex(currentBlockX, currentBlockY, currentBlockZ, startingX, startingY, startingZ);
if (cacheIndex != -1) {
int cacheState = getCacheState(cacheIndex);
// 没遮挡
if (cacheState == 1) {
continue;
}
// 有遮挡
else if (cacheState == 2) {
this.lastHitBlock[this.hitBlockCount * 3] = currentBlockX;
this.lastHitBlock[this.hitBlockCount * 3 + 1] = currentBlockY;
this.lastHitBlock[this.hitBlockCount * 3 + 2] = currentBlockZ;
return false;
}
}
// 检查当前方块是否遮挡视线 // 检查当前方块是否遮挡视线
if (isOccluding(currentBlockX, currentBlockY, currentBlockZ)) { if (isOccluding(currentBlockX, currentBlockY, currentBlockZ)) {
this.lastHitBlock[this.hitBlockCount * 3] = currentBlockX; this.lastHitBlock[this.hitBlockCount * 3] = currentBlockX;
this.lastHitBlock[this.hitBlockCount * 3 + 1] = currentBlockY; this.lastHitBlock[this.hitBlockCount * 3 + 1] = currentBlockY;
this.lastHitBlock[this.hitBlockCount * 3 + 2] = currentBlockZ; this.lastHitBlock[this.hitBlockCount * 3 + 2] = currentBlockZ;
// 设置缓存
if (cacheIndex != -1) {
setCacheState(cacheIndex, 2);
}
return false; // 视线被遮挡,立即返回 return false; // 视线被遮挡,立即返回
} else {
// 设置缓存
if (cacheIndex != -1) {
setCacheState(cacheIndex, 1);
}
} }
// 基于时间参数选择下一个要遍历的方块方向 // 基于时间参数选择下一个要遍历的方块方向