mirror of
https://github.com/YatopiaMC/Yatopia.git
synced 2024-11-22 18:46:27 +01:00
Merge branch 'patch-mappalette' of https://github.com/YatopiaMC/Yatopia into patch-mappalette
This commit is contained in:
commit
b185779850
@ -1,11 +1,11 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: epserv <admin@epserv.ru>
|
||||
Date: Sun, 6 Dec 2020 16:57:19 +0500
|
||||
Date: Mon, 21 Dec 2020 23:12:15 +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..beef3860f9f3bdd8c1924663fe5042501bcc6898 100644
|
||||
index 95fe3f4d081053a6cf484e4ef07b474f2dc2ab02..84daffdda568039423d0f6d18981bb9d9a392e1f 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 {
|
||||
@ -19,86 +19,131 @@ index 95fe3f4d081053a6cf484e4ef07b474f2dc2ab02..beef3860f9f3bdd8c1924663fe504250
|
||||
double rmean = (c1.getRed() + c2.getRed()) / 2.0;
|
||||
double r = c1.getRed() - c2.getRed();
|
||||
double g = c1.getGreen() - c2.getGreen();
|
||||
@@ -31,7 +33,21 @@ public final class MapPalette {
|
||||
@@ -31,7 +33,23 @@ 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()) {
|
||||
+ */
|
||||
+ if (c1.getRGB() == c2.getRGB()) { // check if colors are same
|
||||
+ 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
|
||||
+ // (x1 - x2)^2 + (y1 - y2)^2 + (z1 - z2)^2 formula
|
||||
+ // but with colors. red is x, green is y, blue is z
|
||||
+ return r * r + g * g + b * b;
|
||||
+ }
|
||||
+ // getDistance method itself
|
||||
+ private static double getDistance(@NotNull Color c1, @NotNull Color c2) {
|
||||
+
|
||||
+ // getDistance method itself to keep it plugins-compatible
|
||||
+ public static double getDistance(@NotNull Color c1, @NotNull Color c2) {
|
||||
+ return Math.sqrt(getDistanceSquared(c1, c2));
|
||||
}
|
||||
+ // Yatopia end
|
||||
|
||||
@NotNull
|
||||
static final Color[] colors = {
|
||||
@@ -95,6 +111,24 @@ public final class MapPalette {
|
||||
@@ -95,6 +113,52 @@ 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];
|
||||
+ private static final int[] modifiers = {180, 220, 255, 135}; // vanilla color modifiers
|
||||
+ @NotNull
|
||||
+ static int[] sortedRgbColors = new int[colors.length];
|
||||
+ static Color[] vanillaColors; // vanilla colors
|
||||
+ @NotNull
|
||||
+ static int[] rgbColors = new int[colors.length];
|
||||
+ static Color[][] doubleColors; // two-dimensional array where doubleColors[index] is an array of possible modifications of vanillaColors[index]
|
||||
+ @NotNull
|
||||
+ static int[] rgbColors; // an array of rgb values of each color
|
||||
+
|
||||
+ 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]);
|
||||
+ // getting an array of rgb values of each color
|
||||
+ rgbColors = java.util.Arrays.stream(colors).mapToInt(Color::getRGB).toArray();
|
||||
+
|
||||
+ try {
|
||||
+ // load net.minecraft.server.MaterialMapColor class. using reflection because build fails. maven thinks nms isn't accessible from Yatopia-API
|
||||
+ Class<?> materialMapColorClass = MapPalette.class.getClassLoader().loadClass("net.minecraft.server.MaterialMapColor");
|
||||
+ // get vanilla colors
|
||||
+ Object[] vanillaColorObjects = (Object[]) java.util.Arrays.stream(materialMapColorClass.getFields()).filter(f -> f.getType().isArray() && f.getType().getComponentType().equals(materialMapColorClass)).findAny().get().get(null);
|
||||
+ // get MaterialMapColor.rgb instance field
|
||||
+ java.lang.reflect.Field rgbField = materialMapColorClass.getDeclaredField("rgb");
|
||||
+ // get vanilla colors array as java.awt.Color instances array
|
||||
+ vanillaColors = java.util.Arrays.stream(vanillaColorObjects).filter(java.util.Objects::nonNull).mapToInt(objColor -> {
|
||||
+ try {
|
||||
+ return rgbField.getInt(materialMapColorClass.cast(objColor));
|
||||
+ } catch (Exception ex) {
|
||||
+ throw new RuntimeException(ex);
|
||||
+ }
|
||||
+ }).mapToObj(Color::new).toArray(Color[]::new);
|
||||
+ // get two-dimensional array where doubleColors[index] is an array of possible modifications of vanillaColors[index]
|
||||
+ doubleColors = new Color[vanillaColors.length][modifiers.length];
|
||||
+ for (int i = 0; i < vanillaColors.length; i++) {
|
||||
+ Color vanillaColor = vanillaColors[i];
|
||||
+ for (int j = 0; j < modifiers.length; j++) {
|
||||
+ int modifier = modifiers[j];
|
||||
+ int mr = vanillaColor.getRed() * modifier / 255;
|
||||
+ int mg = vanillaColor.getGreen() * modifier / 255;
|
||||
+ int mb = vanillaColor.getBlue() * modifier / 255;
|
||||
+ doubleColors[i][j] = c(mr, mg, mb);
|
||||
+ }
|
||||
+ }
|
||||
+ } catch (Exception ex) {
|
||||
+ throw new RuntimeException(ex);
|
||||
+ }
|
||||
+ }
|
||||
+ // Yatopia end
|
||||
|
||||
// Interface
|
||||
/**
|
||||
@@ -235,6 +269,8 @@ public final class MapPalette {
|
||||
@@ -235,6 +299,8 @@ public final class MapPalette {
|
||||
public static byte matchColor(@NotNull Color color) {
|
||||
if (color.getAlpha() < 128) return 0;
|
||||
|
||||
+ // Yatopia start - use binary search
|
||||
+ // Yatopia start - foreach a maximum of 62 colors instead of 236 per pixel
|
||||
+ /*
|
||||
int index = 0;
|
||||
double best = -1;
|
||||
|
||||
@@ -245,9 +281,30 @@ public final class MapPalette {
|
||||
@@ -245,9 +311,45 @@ 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;
|
||||
+ int best = -1;
|
||||
+
|
||||
+ for (int i = 0; i < vanillaColors.length; i++) {
|
||||
+ int distance = getDistanceSquared(color, vanillaColors[i]);
|
||||
+ if (distance == 0) {
|
||||
+ index = i;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (distance < best || best == -1) {
|
||||
+ best = distance;
|
||||
+ index = i;
|
||||
+ }
|
||||
+ }
|
||||
+ index = com.google.common.primitives.Ints.indexOf(rgbColors, sortedRgbColors[index]);
|
||||
+ Color[] modColors = doubleColors[index];
|
||||
+ best = -1;
|
||||
+ for (int i = 0; i < modColors.length; i++) {
|
||||
+ int distance = getDistanceSquared(color, modColors[i]);
|
||||
+ if (distance == 0) {
|
||||
+ index = i;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (distance < best || best == -1) {
|
||||
+ best = distance;
|
||||
+ index = i;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ index = com.google.common.primitives.Ints.indexOf(rgbColors, modColors[index].getRGB());
|
||||
+ // we have already checked if color is transparent so now there aren't any transparent colors
|
||||
+ // and if (index < 4) then nearest color was black (hex #000000), so we need to return the most black color
|
||||
+ if (index < 4)
|
||||
+ index = 119;
|
||||
+ // Yatopia end
|
||||
|
||||
// Minecraft has 143 colors, some of which have negative byte representations
|
||||
@ -107,3 +152,12 @@ index 95fe3f4d081053a6cf484e4ef07b474f2dc2ab02..beef3860f9f3bdd8c1924663fe504250
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,7 +362,7 @@ public final class MapPalette {
|
||||
@Deprecated
|
||||
@NotNull
|
||||
public static Color getColor(byte index) {
|
||||
- if ((index > -21 && index < 0) || index > 127) {
|
||||
+ if (index > -21 && index < 0) { // Yatopia
|
||||
throw new IndexOutOfBoundsException();
|
||||
} else {
|
||||
// Minecraft has 143 colors, some of which have negative byte representations
|
||||
|
Loading…
Reference in New Issue
Block a user