From 05fbc499293c5aba2fe2436c1fca3d0299565544 Mon Sep 17 00:00:00 2001 From: ThatGravyBoat Date: Sat, 2 Mar 2024 17:03:02 -0330 Subject: [PATCH] Update highlight internals to use less memory Updated highlight internals to use less memory --- .../client/highlights/HighlightHandler.java | 72 +++++++++++++++++-- .../client/highlights/base/HighlightLine.java | 23 +++++- 2 files changed, 88 insertions(+), 7 deletions(-) diff --git a/common/src/main/java/com/teamresourceful/resourcefullib/client/highlights/HighlightHandler.java b/common/src/main/java/com/teamresourceful/resourcefullib/client/highlights/HighlightHandler.java index 62d413b..40eb792 100644 --- a/common/src/main/java/com/teamresourceful/resourcefullib/client/highlights/HighlightHandler.java +++ b/common/src/main/java/com/teamresourceful/resourcefullib/client/highlights/HighlightHandler.java @@ -6,9 +6,14 @@ import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.serialization.Codec; import com.mojang.serialization.JsonOps; +import com.teamresourceful.resourcefullib.client.CloseablePoseStack; import com.teamresourceful.resourcefullib.client.highlights.base.Highlight; +import com.teamresourceful.resourcefullib.client.highlights.base.HighlightLine; import com.teamresourceful.resourcefullib.client.highlights.base.Highlightable; import com.teamresourceful.resourcefullib.client.highlights.state.HighlightStates; +import com.teamresourceful.resourcefullib.common.color.Color; +import it.unimi.dsi.fastutil.objects.Reference2ReferenceMap; +import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; import net.minecraft.core.BlockPos; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; @@ -25,10 +30,14 @@ public class HighlightHandler extends SimpleJsonResourceReloadListener { - private static final Map STATE_CACHE = new HashMap<>(); + private static final Reference2ReferenceMap STATE_CACHE = new Reference2ReferenceOpenHashMap<>(); private static final Map BOX_CACHE = new HashMap<>(); public static final Codec HIGHLIGHT_CODEC = ResourceLocation.CODEC.xmap(HighlightHandler::getOrThrow, Highlight::id); + private static float red = 0f; + private static float green = 0f; + private static float blue = 0f; + private static float alpha = 0.4f; public HighlightHandler() { super(new Gson(), "resourcefullib/highlights"); @@ -45,10 +54,34 @@ protected void apply(@NotNull Map jsons, @NotNull highlights.forEach((key, value) -> Highlight.codec(key).parse(JsonOps.INSTANCE, value).result().ifPresent(box -> BOX_CACHE.put(key, box))); + Map cache = new HashMap<>(); + blocks.forEach((key, value) -> BuiltInRegistries.BLOCK.getOptional(key) - .flatMap(block -> HighlightStates.codec(block).parse(JsonOps.INSTANCE, value).result()) - .ifPresent(variants -> variants.states().forEach((states, box) -> states.forEach(state -> STATE_CACHE.put(state, box)))) + .flatMap(block -> HighlightStates.codec(block).parse(JsonOps.INSTANCE, value).result()) + .ifPresent(variants -> variants.states().forEach((states, box) -> states.forEach(state -> { + if (cache.containsKey(box)) { + STATE_CACHE.put(state, cache.get(box)); + } else { + float[] lines = new float[box.lines().size() * 9]; + int i = 0; + for (HighlightLine line : box.lines()) { + lines[i++] = line.start().x(); + lines[i++] = line.start().y(); + lines[i++] = line.start().z(); + lines[i++] = line.end().x(); + lines[i++] = line.end().y(); + lines[i++] = line.end().z(); + lines[i++] = line.normal().x(); + lines[i++] = line.normal().y(); + lines[i++] = line.normal().z(); + } + STATE_CACHE.put(state, lines); + cache.put(box, lines); + } + }))) ); + + BOX_CACHE.clear(); } public static boolean onBlockHighlight(Vec3 cameraPos, Entity cameraEntity, PoseStack stack, BlockPos blockPos, BlockState state, VertexConsumer consumer) { @@ -60,7 +93,30 @@ public static boolean onBlockHighlight(Vec3 cameraPos, Entity cameraEntity, Pose } } if (STATE_CACHE.containsKey(state)) { - STATE_CACHE.get(state).render(consumer, stack, cameraPos, state.getOffset(cameraEntity.level(), blockPos), blockPos); + Vec3 offset = state.getOffset(cameraEntity.level(), blockPos); + try (var ignored = new CloseablePoseStack(stack)) { + float x = (float) (blockPos.getX() - cameraPos.x()); + float y = (float) (blockPos.getY() - cameraPos.y()); + float z = (float) (blockPos.getZ() - cameraPos.z()); + x += (float) offset.x(); + y += (float) offset.y(); + z += (float) offset.z(); + + float[] lines = STATE_CACHE.get(state); + if (lines.length % 9 != 0) return false; + + for (int i = 0; i < lines.length; i += 9) { + HighlightLine.render( + stack, consumer, + red, green, blue, alpha, + x, y, z, + lines[i], lines[i + 1], lines[i + 2], + lines[i + 3], lines[i + 4], lines[i + 5], + lines[i + 6], lines[i + 7], lines[i + 8] + ); + } + } + return true; } return false; @@ -71,4 +127,12 @@ private static Highlight getOrThrow(ResourceLocation id) { if (highlight == null) throw new RuntimeException("No highlight with the id '" + id + "' was found!"); return highlight; } + + public static void setColor(int value) { + Color color = new Color(value); + red = color.getFloatRed(); + green = color.getFloatGreen(); + blue = color.getFloatBlue(); + alpha = color.getFloatAlpha(); + } } diff --git a/common/src/main/java/com/teamresourceful/resourcefullib/client/highlights/base/HighlightLine.java b/common/src/main/java/com/teamresourceful/resourcefullib/client/highlights/base/HighlightLine.java index 26be526..08673cb 100644 --- a/common/src/main/java/com/teamresourceful/resourcefullib/client/highlights/base/HighlightLine.java +++ b/common/src/main/java/com/teamresourceful/resourcefullib/client/highlights/base/HighlightLine.java @@ -35,10 +35,27 @@ public void recalculateNormal() { } public void render(PoseStack poseStack, VertexConsumer consumer, float x, float y, float z) { - PoseStack.Pose last = poseStack.last(); + render( + poseStack, consumer, + 0f, 0f, 0f, 0.4f, + x, y, z, + start.x(), start.y(), start.z(), + end.x(), end.y(), end.z(), + normal.x(), normal.y(), normal.z() + ); + } - consumer.vertex(last.pose(), x+start.x(), y+start.y(), z+start.z()).color(0f, 0f, 0f, 0.4f).normal(last.normal(), normal.x(), normal.y(), normal.z()).endVertex(); - consumer.vertex(last.pose(), x+end.x(), y+end.y(), z+end.z()).color(0f, 0f, 0f, 0.4f).normal(last.normal(), normal.x(), normal.y(), normal.z()).endVertex(); + public static void render( + PoseStack stack, VertexConsumer consumer, + float r, float g, float b, float a, + float x, float y, float z, + float x1, float y1, float z1, + float x2, float y2, float z2, + float normalX, float normalY, float normalZ + ) { + PoseStack.Pose last = stack.last(); + consumer.vertex(last.pose(), x + x1, y + y1, z + z1).color(r, g, b, a).normal(last.normal(), normalX, normalY, normalZ).endVertex(); + consumer.vertex(last.pose(), x + x2, y + y2, z + z2).color(r, g, b, a).normal(last.normal(), normalX, normalY, normalZ).endVertex(); } private static Vector3f normal(Vector3f start, Vector3f end) {