From 6e4b5ebaf640b5abef43becab98f037f0de60758 Mon Sep 17 00:00:00 2001 From: gnembon Date: Sun, 31 May 2020 19:42:49 -0300 Subject: [PATCH] detecting refreshed shapes --- .../carpet/script/utils/ShapeDispatcher.java | 44 ++++++- .../carpet/script/utils/ShapesRenderer.java | 120 ++++++++++++++---- .../assets/carpet/scripts/overlay.sc | 22 ++-- 3 files changed, 147 insertions(+), 39 deletions(-) diff --git a/src/main/java/carpet/script/utils/ShapeDispatcher.java b/src/main/java/carpet/script/utils/ShapeDispatcher.java index 4a6c8c7c..e898974d 100644 --- a/src/main/java/carpet/script/utils/ShapeDispatcher.java +++ b/src/main/java/carpet/script/utils/ShapeDispatcher.java @@ -74,6 +74,7 @@ public class ShapeDispatcher protected float r, g, b, a; protected int color; protected int duration = 0; + private int key; public ExpiringShape(int duration, int color) { this.r = (float)(color >> 24 & 0xFF) / 255.0F; @@ -82,7 +83,8 @@ public class ShapeDispatcher this.a = (float)(color & 0xFF) / 255.0F; this.color = color; this.duration = duration; - }; + key = 0; + } public int getExpiry() { return duration; }; public CompoundTag toTag() @@ -93,6 +95,18 @@ public class ShapeDispatcher return tag; }; public abstract Consumer alternative(); + public int key() + { + if (key!=0) return key; + key = calcKey(); + return key; + } + protected int calcKey() + { + int hash = 17; + hash = 31*hash + color; + return hash; + }; } public static class Box extends ExpiringShape @@ -146,6 +160,20 @@ public class ShapeDispatcher return p -> mesh(Collections.singletonList(p), particle, density, x1, y1, z1, x2, y2, z2); } + @Override + public int calcKey() + { + int hash = super.calcKey(); + hash = 31*hash + 1; + hash = 31*hash + Float.hashCode(x1); + hash = 31*hash + Float.hashCode(y1); + hash = 31*hash + Float.hashCode(z1); + hash = 31*hash + Float.hashCode(x2); + hash = 31*hash + Float.hashCode(y2); + hash = 31*hash + Float.hashCode(z2); + return hash; + } + public static int mesh(List playerList, ParticleEffect particle, double density, double x1, double y1, double z1, double x2, double y2, double z2 ) { @@ -217,6 +245,20 @@ public class ShapeDispatcher double density = Math.max(2.0, Math.sqrt(dx*dx+dy*dy+dz*dz) /50) / (a+0.1); return p -> drawParticleLine(Collections.singletonList(p), particle, pos1, pos2, density); } + + @Override + public int calcKey() + { + int hash = super.calcKey(); + hash = 31*hash + 2; + hash = 31*hash + Float.hashCode(x1); + hash = 31*hash + Float.hashCode(y1); + hash = 31*hash + Float.hashCode(z1); + hash = 31*hash + Float.hashCode(x2); + hash = 31*hash + Float.hashCode(y2); + hash = 31*hash + Float.hashCode(z2); + return hash; + } } private static boolean isStraight(Vec3d from, Vec3d to, double density) diff --git a/src/main/java/carpet/script/utils/ShapesRenderer.java b/src/main/java/carpet/script/utils/ShapesRenderer.java index a4590182..d6db7387 100644 --- a/src/main/java/carpet/script/utils/ShapesRenderer.java +++ b/src/main/java/carpet/script/utils/ShapesRenderer.java @@ -2,6 +2,7 @@ package carpet.script.utils; import carpet.CarpetSettings; import com.mojang.blaze3d.systems.RenderSystem; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.Tessellator; @@ -14,16 +15,13 @@ import net.minecraft.world.IWorld; import net.minecraft.world.dimension.DimensionType; import org.lwjgl.opengl.GL11; -import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; -import java.util.List; import java.util.Map; import java.util.function.BiFunction; public class ShapesRenderer { - private final Map>> shapes; + private final Map>> shapes; private MinecraftClient client; private Map>> renderedShapes @@ -37,9 +35,9 @@ public class ShapesRenderer { this.client = minecraftClient; shapes = new HashMap<>(); - shapes.put(DimensionType.OVERWORLD, new ArrayList<>()); - shapes.put(DimensionType.THE_NETHER, new ArrayList<>()); - shapes.put(DimensionType.THE_END, new ArrayList<>()); + shapes.put(DimensionType.OVERWORLD, new Int2ObjectOpenHashMap<>()); + shapes.put(DimensionType.THE_NETHER, new Int2ObjectOpenHashMap<>()); + shapes.put(DimensionType.THE_END, new Int2ObjectOpenHashMap<>()); } public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, double cameraX, double cameraY, double cameraZ) @@ -48,8 +46,10 @@ public class ShapesRenderer DimensionType dimensionType = iWorld.getDimension().getType(); if (shapes.get(dimensionType).isEmpty()) return; long currentTime = client.world.getTime(); - RenderSystem.enableDepthTest(); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + //RenderSystem.blendFuncSeparate(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE, GlStateManager.SrcFactor.ONE, GlStateManager.DstFactor.ZERO); RenderSystem.shadeModel(7425); RenderSystem.enableAlphaTest(); RenderSystem.defaultAlphaFunc(); @@ -59,20 +59,21 @@ public class ShapesRenderer double d = 0.0D - cameraY; double e = 256.0D - cameraY; RenderSystem.disableTexture(); - RenderSystem.disableBlend(); + //RenderSystem.disableBlend(); double f = (double)(entity.chunkX << 4) - cameraX; double g = (double)(entity.chunkZ << 4) - cameraZ; - // render synchronized (shapes) { - Iterator> it = shapes.get(dimensionType).iterator(); - while (it.hasNext()) - { - RenderedShape shape = it.next(); - if (shape.isExpired(currentTime)) it.remove(); - shape.render(tessellator, bufferBuilder, (float) cameraX, (float) cameraY, (float) cameraZ); - } + shapes.get(dimensionType).int2ObjectEntrySet().removeIf( + entry -> entry.getValue().isExpired(currentTime) + ); + shapes.get(dimensionType).values().forEach( + s -> s.render(tessellator, bufferBuilder, (float) cameraX, (float) cameraY, (float) cameraZ) + ); + shapes.get(dimensionType).values().forEach( + s -> s.render2pass(tessellator, bufferBuilder, (float) cameraX, (float) cameraY, (float) cameraZ) + ); } RenderSystem.lineWidth(1.0F); @@ -91,54 +92,87 @@ public class ShapesRenderer } else { - synchronized (shapes) { shapes.get(dim).add(shapeFactory.apply(client, tag)); } + RenderedShape rshape = shapeFactory.apply(client, tag); + int key = rshape.key(); + synchronized (shapes) + { + RenderedShape existing = shapes.get(dim).get(key); + if (existing != null) + { // promoting previous shape + existing.expiryTick = rshape.expiryTick; + } + else + { + shapes.get(dim).put(key, rshape); + } + } } } public void reset() { synchronized (shapes) { - shapes.values().forEach(List::clear); + shapes.values().forEach(Int2ObjectOpenHashMap::clear); } } public abstract static class RenderedShape { - T shape; + protected T shape; long expiryTick; + float renderEpsilon = 0; public abstract void render(Tessellator tessellator, BufferBuilder builder, float cx, float cy, float cz ); + public void render2pass(Tessellator tessellator, BufferBuilder builder, float cx, float cy, float cz ) {}; protected RenderedShape(MinecraftClient client, T shape) { this.shape = shape; expiryTick = client.world.getTime()+shape.getExpiry(); + renderEpsilon = (2+((float)shape.key())/Integer.MAX_VALUE)/1000; } public boolean isExpired(long currentTick) { return expiryTick < currentTick; } + public int key() + { + return shape.key(); + }; } public static class RenderedBox extends RenderedShape { + public RenderedBox(MinecraftClient client, CompoundTag boxData) { super(client, (ShapeDispatcher.Box)ShapeDispatcher.Box.fromTag(boxData)); + } @Override public void render(Tessellator tessellator, BufferBuilder bufferBuilder, float cx, float cy, float cz) { RenderSystem.lineWidth(2.0F); bufferBuilder.begin(GL11.GL_LINES, VertexFormats.POSITION_COLOR); // 3 - drawBox(bufferBuilder, - shape.x1-cx, shape.y1-cy, shape.z1-cz, - shape.x2-cx, shape.y2-cy, shape.z2-cz, + drawBoxWireGLLines(bufferBuilder, + shape.x1 - cx-renderEpsilon, shape.y1 - cy-renderEpsilon, shape.z1 - cz-renderEpsilon, + shape.x2 - cx+renderEpsilon, shape.y2 - cy+renderEpsilon, shape.z2 - cz+renderEpsilon, shape.r, shape.g, shape.b, shape.a, shape.r, shape.g, shape.b ); tessellator.draw(); } - + @Override + public void render2pass(Tessellator tessellator, BufferBuilder bufferBuilder, float cx, float cy, float cz) + { + RenderSystem.lineWidth(1.0F); + bufferBuilder.begin(GL11.GL_QUADS, VertexFormats.POSITION_COLOR); // 3 + drawBox(bufferBuilder, + shape.x1-cx-renderEpsilon, shape.y1-cy-renderEpsilon, shape.z1-cz-renderEpsilon, + shape.x2-cx+renderEpsilon, shape.y2-cy+renderEpsilon, shape.z2-cz+renderEpsilon, + shape.r, shape.g, shape.b, shape.a/6 + ); + tessellator.draw(); + } } public static class RenderedLine extends RenderedShape @@ -153,8 +187,8 @@ public class ShapesRenderer RenderSystem.lineWidth(2.0F); bufferBuilder.begin(GL11.GL_LINES, VertexFormats.POSITION_COLOR); // 3 drawLine(bufferBuilder, - shape.x1-cx, shape.y1-cy, shape.z1-cz, - shape.x2-cx, shape.y2-cy, shape.z2-cz, + shape.x1-cx-renderEpsilon, shape.y1-cy-renderEpsilon, shape.z1-cz-renderEpsilon, + shape.x2-cx+renderEpsilon, shape.y2-cy+renderEpsilon, shape.z2-cz+renderEpsilon, shape.r, shape.g, shape.b, shape.a ); tessellator.draw(); @@ -169,7 +203,7 @@ public class ShapesRenderer builder.vertex(x2, y2, z2).color(red1, grn1, blu1, alpha).next(); } - public static void drawBox(BufferBuilder builder, float x1, float y1, float z1, float x2, float y2, float z2, float red1, float grn1, float blu1, float alpha, float red2, float grn2, float blu2) { + public static void drawBoxWireGLLines(BufferBuilder builder, float x1, float y1, float z1, float x2, float y2, float z2, float red1, float grn1, float blu1, float alpha, float red2, float grn2, float blu2) { builder.vertex(x1, y1, z1).color(red1, grn2, blu2, alpha).next(); builder.vertex(x2, y1, z1).color(red1, grn2, blu2, alpha).next(); builder.vertex(x1, y1, z1).color(red2, grn1, blu2, alpha).next(); @@ -195,4 +229,36 @@ public class ShapesRenderer builder.vertex(x2, y2, z1).color(red1, grn1, blu1, alpha).next(); builder.vertex(x2, y2, z2).color(red1, grn1, blu1, alpha).next(); } + + public static void drawBox(BufferBuilder builder, float x1, float y1, float z1, float x2, float y2, float z2, float red1, float grn1, float blu1, float alpha) { + builder.vertex(x1, y1, z1).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x2, y1, z1).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x2, y2, z1).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x1, y2, z1).color(red1, grn1, blu1, alpha).next(); + + builder.vertex(x1, y1, z2).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x2, y1, z2).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x2, y2, z2).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x1, y2, z2).color(red1, grn1, blu1, alpha).next(); + + builder.vertex(x1, y1, z1).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x1, y1, z2).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x1, y2, z2).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x1, y2, z1).color(red1, grn1, blu1, alpha).next(); + + builder.vertex(x2, y1, z1).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x2, y1, z2).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x2, y2, z2).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x2, y2, z1).color(red1, grn1, blu1, alpha).next(); + + builder.vertex(x1, y1, z1).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x2, y1, z1).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x2, y1, z2).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x1, y1, z2).color(red1, grn1, blu1, alpha).next(); + + builder.vertex(x1, y2, z1).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x2, y2, z1).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x2, y2, z2).color(red1, grn1, blu1, alpha).next(); + builder.vertex(x1, y2, z2).color(red1, grn1, blu1, alpha).next(); + } } diff --git a/src/main/resources/assets/carpet/scripts/overlay.sc b/src/main/resources/assets/carpet/scripts/overlay.sc index 45be90a4..95d4fca5 100644 --- a/src/main/resources/assets/carpet/scripts/overlay.sc +++ b/src/main/resources/assets/carpet/scripts/overlay.sc @@ -95,7 +95,7 @@ __structure_renderer(player_name) -> total_size = _euclidean(from, to); density = max(10, total_size/10); //particle_box('dust 0 1 1 2', from, to+1, density); - marker_box(from, to+1, 10, 0x00FFFFFF ); + marker_box(from, to+1, 15, 0x00FFFFFF ); structure_pieces = slice(sort_key(structure_pieces, _euclidean_sq((_:2+_:3)/2,ppos)), 0, config:'max_pieces'); for (structure_pieces, l(piece, direction, from, to) = _; //factor = 1- _i / config:'max_pieces' / 2; @@ -107,11 +107,11 @@ __structure_renderer(player_name) -> b = 255; a = 255; color = a+256*(b+256*(g+256*r)); - marker_box(from, to+1, 10, color); + marker_box(from, to+1, 15, color); ) ) ); - schedule(5, '__structure_renderer', player_name); + schedule(10, '__structure_renderer', player_name); ); __chunk_renderer(player_name) -> @@ -128,7 +128,7 @@ __chunk_renderer(player_name) -> for (range(-r,r), cz = _; ref_pos = ppos + l(16*cx,0,16*cz); if(has(config:'tasks':'slime_chunks') && in_slime_chunk(ref_pos), - player_distance = _euclidean(ppos, ref_pos+8); + player_distance = _euclidean(ppos, ref_pos); top_00 = ref_pos + l(0, top('terrain', ref_pos)+10, 0); top_11 = ref_pos + l(16, top('terrain', ref_pos+l(15,0,15))+10, 16); top_10 = ref_pos + l(16, top('terrain', ref_pos+l(15, 0, 0))+10, 0); @@ -140,12 +140,12 @@ __chunk_renderer(player_name) -> b = 30; a = max(0, 255-player_distance); color = a+256*(b+256*(g+256*r)); - marker_line(top_00, top_10, 10, color); - marker_line(top_10, top_11, 10, color); - marker_line(top_11, top_01, 10, color); - marker_line(top_01, top_00, 10, color); - marker_line(top_00, top_11, 10, color); - marker_line(top_01, top_10, 10, color); + marker_line(top_00, top_10, 15, color); + marker_line(top_10, top_11, 15, color); + marker_line(top_11, top_01, 15, color); + marker_line(top_01, top_00, 15, color); + marker_line(top_00, top_11, 15, color); + marker_line(top_01, top_10, 15, color); //particle_line(part, top_00, top_10, density); //particle_line(part, top_10, top_11, density); @@ -157,5 +157,5 @@ __chunk_renderer(player_name) -> ) ) ); - schedule(5, '__chunk_renderer', player_name); + schedule(10, '__chunk_renderer', player_name); ) \ No newline at end of file