Yatopia/patches/api/0011-Optimise-Bukkit-s-MapPalette.patch

114 lines
4.4 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: epserv <admin@epserv.ru>
Date: Sun, 6 Dec 2020 16:57:19 +0500
Subject: [PATCH] Optimise Bukkit's MapPalette
diff --git a/src/main/java/org/bukkit/map/MapPalette.java b/src/main/java/org/bukkit/map/MapPalette.java
index 95fe3f4d081053a6cf484e4ef07b474f2dc2ab02..5e938a83377ddf1b952d3597c9974d0ca79afb79 100644
--- a/src/main/java/org/bukkit/map/MapPalette.java
+++ b/src/main/java/org/bukkit/map/MapPalette.java
@@ -22,7 +22,9 @@ public final class MapPalette {
return new Color(r, g, b);
}
- private static double getDistance(@NotNull Color c1, @NotNull Color c2) {
+ // Yatopia start - faster method
+ private static int getDistanceSquared(@NotNull Color c1, @NotNull Color c2) {
+ /*
double rmean = (c1.getRed() + c2.getRed()) / 2.0;
double r = c1.getRed() - c2.getRed();
double g = c1.getGreen() - c2.getGreen();
@@ -31,10 +33,24 @@ public final class MapPalette {
double weightG = 4.0;
double weightB = 2 + (255 - rmean) / 256.0;
return weightR * r * r + weightG * g * g + weightB * b * b;
+ */
+ if (c1.getRGB() == c2.getRGB()) {
+ return 0;
+ }
+ int r = c1.getRed() - c2.getRed(),
+ g = c1.getGreen() - c2.getGreen(),
+ b = c1.getBlue() - c2.getBlue();
+ // because of performed tests, this accuracy is enough
+ return r * r + g * g + b * b;
+ }
+ // getDistance method itself
+ private static double getDistance(@NotNull Color c1, @NotNull Color c2) {
+ return Math.sqrt(getDistanceSquared(c1, c2));
}
+ // Yatopia end
@NotNull
- static final Color[] colors = {
+ static Color[] colors = { // Yatopia
c(0, 0, 0), c(0, 0, 0), c(0, 0, 0), c(0, 0, 0),
c(89, 125, 39), c(109, 153, 48), c(127, 178, 56), c(67, 94, 29),
c(174, 164, 115), c(213, 201, 140), c(247, 233, 163), c(130, 123, 86),
@@ -95,6 +111,24 @@ public final class MapPalette {
c(60, 31, 43), c(74, 37, 53), c(86, 44, 62), c(45, 23, 32),
c(14, 127, 93), c(17, 155, 114), c(20, 180, 133), c(10, 95, 70)
};
+ // Yatopia start
+ @NotNull
+ static Color[] sortedColors = new Color[colors.length];
+ @NotNull
+ static int[] sortedRgbColors = new int[colors.length];
+ @NotNull
+ static int[] rgbColors = new int[colors.length];
+ static {
+ for (short i = 0; i < rgbColors.length; i++) {
+ rgbColors[i] = colors[i].getRGB();
+ }
+ sortedRgbColors = rgbColors.clone();
+ java.util.Arrays.sort(sortedRgbColors);
+ for (short i = 0; i < sortedColors.length; i++) {
+ sortedColors[i] = new Color(sortedRgbColors[i]);
+ }
+ }
+ // Yatopia end
// Interface
/**
@@ -235,6 +269,8 @@ public final class MapPalette {
public static byte matchColor(@NotNull Color color) {
if (color.getAlpha() < 128) return 0;
+ // Yatopia start - use binary search
+ /*
int index = 0;
double best = -1;
@@ -245,9 +281,30 @@ public final class MapPalette {
index = i;
}
}
+ */
+ int index = 0;
+ int binaryIndex = java.util.Arrays.binarySearch(sortedRgbColors, color.getRGB());
+ if (binaryIndex >= 0) {
+ return (byte) (binaryIndex < 128 ? binaryIndex : binaryIndex - 256);
+ }
+ int insertionPoint = (-binaryIndex) - 1;
+ if (insertionPoint == sortedColors.length - 1) {
+ index = sortedColors.length - 1;
+ } else {
+ // now don't loop over all the colors, just select one of neighbor colors
+ // we don't need a distance itself, so we can use distance squared
+ int d1 = getDistanceSquared(color, sortedColors[insertionPoint - 1]), d2 = getDistanceSquared(color, sortedColors[insertionPoint]);
+ if (d1 > d2) {
+ index = insertionPoint;
+ } else {
+ index = insertionPoint - 1;
+ }
+ }
+ index = com.google.common.primitives.Ints.indexOf(rgbColors, sortedRgbColors[index]);
+ // Yatopia end
// Minecraft has 143 colors, some of which have negative byte representations
- return (byte) (index < 128 ? index : -129 + (index - 127));
+ return (byte) (index < 128 ? index : index - 256); // Yatopia
}
/**