2018-08-26 20:11:49 +02:00
|
|
|
From 4c8a9a911c8fa1fbd7920c736e653b5dc3976cb8 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
|
2018-08-26 20:11:49 +02:00
|
|
|
index aa2f5414b0..bd1ac77aef 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
|
2018-07-24 02:24:44 +02:00
|
|
|
@@ -142,4 +142,10 @@ public class PaperWorldConfig {
|
2018-07-15 03:53:17 +02:00
|
|
|
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
|
2018-08-26 20:11:49 +02:00
|
|
|
index 439d7ef40c..e440d6d631 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
|
2018-08-26 20:11:49 +02:00
|
|
|
@@ -137,7 +137,7 @@ public class Explosion {
|
2015-06-16 14:55:15 +02:00
|
|
|
d8 /= d11;
|
|
|
|
d9 /= d11;
|
|
|
|
d10 /= d11;
|
|
|
|
- double d12 = (double) this.world.a(vec3d, entity.getBoundingBox());
|
2016-03-01 00:09:49 +01:00
|
|
|
+ double d12 = this.getBlockDensity(vec3d, entity.getBoundingBox()); // 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
|
2018-08-26 20:11:49 +02:00
|
|
|
@@ -313,4 +313,85 @@ public class Explosion {
|
2015-06-16 14:55:15 +02:00
|
|
|
public List<BlockPosition> getBlocks() {
|
|
|
|
return this.blocks;
|
|
|
|
}
|
|
|
|
+
|
2016-03-01 00:09:49 +01:00
|
|
|
+ // Paper start - Optimize explosions
|
2015-06-16 14:55:15 +02:00
|
|
|
+ private float getBlockDensity(Vec3D vec3d, AxisAlignedBB aabb) {
|
2016-03-01 00:09:49 +01:00
|
|
|
+ if (!this.world.paperConfig.optimizeExplosions) {
|
2015-06-16 14:55:15 +02:00
|
|
|
+ return this.world.a(vec3d, aabb);
|
|
|
|
+ }
|
|
|
|
+ CacheKey key = new CacheKey(this, aabb);
|
|
|
|
+ Float blockDensity = this.world.explosionDensityCache.get(key);
|
|
|
|
+ if (blockDensity == null) {
|
|
|
|
+ blockDensity = this.world.a(vec3d, aabb);
|
|
|
|
+ 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;
|
|
|
|
+ this.minX = aabb.a;
|
|
|
|
+ this.minY = aabb.b;
|
|
|
|
+ this.minZ = aabb.c;
|
|
|
|
+ this.maxX = aabb.d;
|
|
|
|
+ this.maxY = aabb.e;
|
|
|
|
+ this.maxZ = aabb.f;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @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
|
2018-08-26 20:11:49 +02:00
|
|
|
index c47f56ed8d..bdc779ef3b 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
|
2018-08-26 20:11:49 +02:00
|
|
|
@@ -1051,6 +1051,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
|
2016-04-30 03:23:40 +02:00
|
|
|
worldserver.getTracker().updatePlayers();
|
2018-07-15 03:53:17 +02:00
|
|
|
this.methodProfiler.e();
|
|
|
|
this.methodProfiler.e();
|
2016-03-01 00:09:49 +01:00
|
|
|
+ worldserver.explosionDensityCache.clear(); // Paper - Optimize explosions
|
2018-07-15 03:53:17 +02:00
|
|
|
}
|
2018-08-26 20:11:49 +02:00
|
|
|
}
|
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
|
2018-08-26 20:11:49 +02:00
|
|
|
index 93d1449750..9e192b7c04 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
|
2018-08-26 20:11:49 +02:00
|
|
|
@@ -24,6 +24,7 @@ import org.apache.logging.log4j.Logger;
|
2016-03-01 00:09:49 +01:00
|
|
|
|
2016-03-25 07:38:38 +01:00
|
|
|
// CraftBukkit start
|
|
|
|
import com.google.common.collect.Maps;
|
|
|
|
+import java.util.HashMap; // Paper
|
|
|
|
import java.util.Map;
|
|
|
|
import org.bukkit.Bukkit;
|
|
|
|
import org.bukkit.block.BlockState;
|
2018-08-26 20:11:49 +02:00
|
|
|
@@ -145,6 +146,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
2016-03-25 07:38:38 +01:00
|
|
|
private org.spigotmc.TickLimiter entityLimiter;
|
2015-09-13 06:29:23 +02:00
|
|
|
private org.spigotmc.TickLimiter tileLimiter;
|
2015-06-16 14:55:15 +02:00
|
|
|
private int tileTickPosition;
|
2016-03-25 07:38:38 +01:00
|
|
|
+ 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;
|
2015-06-16 14:55:15 +02:00
|
|
|
--
|
2018-07-04 09:55:24 +02:00
|
|
|
2.18.0
|
2015-06-16 14:55:15 +02:00
|
|
|
|