PaperMC/Spigot-Server-Patches/0032-Optimize-explosions.patch

149 lines
6.8 KiB
Diff
Raw Normal View History

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2015-06-16 14:55:15 +02:00
From: Byteflux <byte@byteflux.net>
2016-03-01 00:09:49 +01:00
Date: Wed, 2 Mar 2016 11:59:48 -0600
2015-06-16 14:55:15 +02:00
Subject: [PATCH] Optimize explosions
The process of determining an entity's exposure from explosions can be
expensive when there are hundreds or more entities in range.
This patch adds a per-tick cache that is used for storing and retrieving
an entity's exposure during an explosion.
2016-03-01 00:09:49 +01:00
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index 88f5a415770da5dfcf7af95045f547e0761adc8b..41d03030741f2bc5dd904957be546de82be61a47 100644
2016-03-01 00:09:49 +01:00
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -151,4 +151,10 @@ public class PaperWorldConfig {
disableEndCredits = getBoolean("game-mechanics.disable-end-credits", false);
log("End credits disabled: " + disableEndCredits);
2016-03-01 00:09:49 +01:00
}
+
+ public boolean optimizeExplosions;
+ private void optimizeExplosions() {
+ optimizeExplosions = getBoolean("optimize-explosions", false);
+ log("Optimize explosions: " + optimizeExplosions);
+ }
}
2015-06-16 14:55:15 +02:00
diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java
index afe61a1ddc75f155836411b6749198f71ed09919..ac39b02ec5f02f6f2db9f293513686d2d29d4036 100644
2015-06-16 14:55:15 +02:00
--- a/src/main/java/net/minecraft/server/Explosion.java
+++ b/src/main/java/net/minecraft/server/Explosion.java
@@ -173,7 +173,7 @@ public class Explosion {
2015-06-16 14:55:15 +02:00
d8 /= d11;
d9 /= d11;
d10 /= d11;
2019-04-24 04:34:11 +02:00
- double d12 = (double) a(vec3d, entity);
+ double d12 = this.getBlockDensity(vec3d, entity); // Paper - Optimize explosions
2015-06-16 14:55:15 +02:00
double d13 = (1.0D - d7) * d12;
2016-03-01 00:09:49 +01:00
// CraftBukkit start
@@ -392,4 +392,84 @@ public class Explosion {
2019-04-24 04:34:11 +02:00
private Effect() {}
2015-06-16 14:55:15 +02:00
}
2016-03-01 00:09:49 +01:00
+ // Paper start - Optimize explosions
2019-04-24 04:34:11 +02:00
+ private float getBlockDensity(Vec3D vec3d, Entity entity) {
2016-03-01 00:09:49 +01:00
+ if (!this.world.paperConfig.optimizeExplosions) {
2019-04-24 04:34:11 +02:00
+ return a(vec3d, entity);
2015-06-16 14:55:15 +02:00
+ }
2019-04-24 04:34:11 +02:00
+ CacheKey key = new CacheKey(this, entity.getBoundingBox());
2015-06-16 14:55:15 +02:00
+ Float blockDensity = this.world.explosionDensityCache.get(key);
+ if (blockDensity == null) {
2019-04-24 04:34:11 +02:00
+ blockDensity = a(vec3d, entity);
2015-06-16 14:55:15 +02:00
+ this.world.explosionDensityCache.put(key, blockDensity);
+ }
+
+ return blockDensity;
+ }
+
+ static class CacheKey {
+ private final World world;
+ private final double posX, posY, posZ;
+ private final double minX, minY, minZ;
+ private final double maxX, maxY, maxZ;
+
+ public CacheKey(Explosion explosion, AxisAlignedBB aabb) {
+ this.world = explosion.world;
+ this.posX = explosion.posX;
+ this.posY = explosion.posY;
+ this.posZ = explosion.posZ;
2018-10-23 01:16:21 +02:00
+ this.minX = aabb.minX;
+ this.minY = aabb.minY;
+ this.minZ = aabb.minZ;
+ this.maxX = aabb.maxX;
+ this.maxY = aabb.maxY;
+ this.maxZ = aabb.maxZ;
2015-06-16 14:55:15 +02:00
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ CacheKey cacheKey = (CacheKey) o;
+
+ if (Double.compare(cacheKey.posX, posX) != 0) return false;
+ if (Double.compare(cacheKey.posY, posY) != 0) return false;
+ if (Double.compare(cacheKey.posZ, posZ) != 0) return false;
+ if (Double.compare(cacheKey.minX, minX) != 0) return false;
+ if (Double.compare(cacheKey.minY, minY) != 0) return false;
+ if (Double.compare(cacheKey.minZ, minZ) != 0) return false;
+ if (Double.compare(cacheKey.maxX, maxX) != 0) return false;
+ if (Double.compare(cacheKey.maxY, maxY) != 0) return false;
+ if (Double.compare(cacheKey.maxZ, maxZ) != 0) return false;
+ return world.equals(cacheKey.world);
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ long temp;
+ result = world.hashCode();
+ temp = Double.doubleToLongBits(posX);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(posY);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(posZ);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(minX);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(minY);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(minZ);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(maxX);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(maxY);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(maxZ);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+ }
2016-03-01 00:09:49 +01:00
+ // Paper end
2015-06-16 14:55:15 +02:00
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 775306d7e59ff135004e54d2d055bd05edba7e61..4d3cb70f1567b042e1605b30637706560bd883d9 100644
2015-06-16 14:55:15 +02:00
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1207,6 +1207,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
2019-04-24 04:34:11 +02:00
2020-06-25 11:27:25 +02:00
this.methodProfiler.exit();
this.methodProfiler.exit();
+ worldserver.explosionDensityCache.clear(); // Paper - Optimize explosions
}
2015-06-16 14:55:15 +02:00
2020-06-25 11:27:25 +02:00
this.methodProfiler.exitEnter("connection");
2015-06-16 14:55:15 +02:00
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index dab129dd83024bdcee251393e1854ff384ff3c26..611c7a5c1da8afa9a8caaa668c40517d560c8396 100644
2015-06-16 14:55:15 +02:00
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
2020-06-26 18:20:03 +02:00
@@ -84,6 +84,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
private org.spigotmc.TickLimiter entityLimiter;
private org.spigotmc.TickLimiter tileLimiter;
2015-06-16 14:55:15 +02:00
private int tileTickPosition;
+ public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
2015-06-16 14:55:15 +02:00
2016-03-01 00:09:49 +01:00
public CraftWorld getWorld() {
return this.world;