From 118554dbababbc3843601a4cd282a0e0c4f8b571 Mon Sep 17 00:00:00 2001 From: gnembon Date: Wed, 10 Jun 2020 12:30:33 -0300 Subject: [PATCH] added 'cylinder' shape --- docs/scarpet/api/Auxiliary.md | 11 +- .../carpet/script/utils/ShapeDispatcher.java | 14 +- .../carpet/script/utils/ShapesRenderer.java | 242 ++++++++++++++++-- 3 files changed, 248 insertions(+), 19 deletions(-) diff --git a/docs/scarpet/api/Auxiliary.md b/docs/scarpet/api/Auxiliary.md index 8cb0c117..98021758 100644 --- a/docs/scarpet/api/Auxiliary.md +++ b/docs/scarpet/api/Auxiliary.md @@ -88,13 +88,22 @@ Available shapes: * `from` - triple coordinates, entity, or block value indicating one corner of the box * `to` - other corner, same format as `from` - * `'sphere'` - draws a sphere + * `'sphere'`: * Required attributes: * `center` - center of the sphere * `radius` - radius of the sphere * Optional attributes: * `level` - level of details, or grid size. The more the denser your sphere. Default level of 0, means that the level of detail will be selected automatically based on radius. + + * `'cylinder'`: + * Required attributes: + * `center` - center of the base + * `radius` - radius of the base circle + * Optional attributes: + * `axis` - cylinder direction, one of `'x'`, `'y'`, `'z'` defaults to `'y'` + * `height` - height of the cyllinder, defaults to `0`, so flat disk. Can be negative. + * `level` - level of details, see `'sphere'`. ### `create_marker(text, pos, rotation?, block?)` diff --git a/src/main/java/carpet/script/utils/ShapeDispatcher.java b/src/main/java/carpet/script/utils/ShapeDispatcher.java index 9007d675..58f30095 100644 --- a/src/main/java/carpet/script/utils/ShapeDispatcher.java +++ b/src/main/java/carpet/script/utils/ShapeDispatcher.java @@ -714,7 +714,7 @@ public class ShapeDispatcher put("center", new Vec3Param("center", false)); put("radius", new PositiveFloatParam("radius")); put("level", new PositiveIntParam("level")); - put("height", new NonNegativeFloatParam("height")); + put("height", new FloatParam("height")); put("axis", new StringChoiceParam("axis", "x", "y", "z")); put("points", new PointsParam("points")); }}; @@ -794,6 +794,15 @@ public class ShapeDispatcher return value; } } + public static class FloatParam extends NumericParam + { + protected FloatParam(String id) { super(id); } + @Override + public Value decode(Tag tag) { return new NumericValue(((FloatTag)tag).getFloat()); } + @Override + public Tag toTag(Value value) { return FloatTag.of(NumericValue.asNumber(value, id).getFloat()); } + } + public static abstract class PositiveParam extends NumericParam { protected PositiveParam(String id) { super(id); } @@ -851,6 +860,9 @@ public class ShapeDispatcher } } + + + public static class Vec3Param extends Param { private boolean roundsUpForBlocks; diff --git a/src/main/java/carpet/script/utils/ShapesRenderer.java b/src/main/java/carpet/script/utils/ShapesRenderer.java index d4bb1e9f..c2a799b9 100644 --- a/src/main/java/carpet/script/utils/ShapesRenderer.java +++ b/src/main/java/carpet/script/utils/ShapesRenderer.java @@ -257,8 +257,8 @@ public class ShapesRenderer Vec3d vc = shape.relativiseRender(client.world, shape.center, partialTick); RenderSystem.lineWidth(shape.lineWidth); drawSphereWireframe(tessellator, bufferBuilder, - (float)(vc.x-cx-renderEpsilon), (float)(vc.y-cy-renderEpsilon), (float)(vc.z-cz-renderEpsilon), - shape.radius, shape.subdivisions, + (float)(vc.x-cx), (float)(vc.y-cy), (float)(vc.z-cz), + (float)(shape.radius+renderEpsilon), shape.subdivisions, shape.r, shape.g, shape.b, shape.a); } @Override @@ -268,8 +268,8 @@ public class ShapesRenderer Vec3d vc = shape.relativiseRender(client.world, shape.center, partialTick); RenderSystem.lineWidth(1.0f); drawSphereFaces(tessellator, bufferBuilder, - (float)(vc.x-cx-renderEpsilon), (float)(vc.y-cy-renderEpsilon), (float)(vc.z-cz-renderEpsilon), - shape.radius, shape.subdivisions, + (float)(vc.x-cx), (float)(vc.y-cy), (float)(vc.z-cz), + (float)(shape.radius+renderEpsilon), shape.subdivisions, shape.fr, shape.fg, shape.fb, shape.fa); } } @@ -286,21 +286,26 @@ public class ShapesRenderer if (shape.a == 0.0) return; Vec3d vc = shape.relativiseRender(client.world, shape.center, partialTick); RenderSystem.lineWidth(shape.lineWidth); + double dir = MathHelper.sign(shape.height); drawCylinderWireframe(tessellator, bufferBuilder, - (float)(vc.x-cx-renderEpsilon), (float)(vc.y-cy-renderEpsilon), (float)(vc.z-cz-renderEpsilon), - shape.radius, shape.height, shape.axis, shape.subdivisions, + (float) (vc.x - cx - dir * renderEpsilon), (float) (vc.y - cy - dir * renderEpsilon), (float) (vc.z - cz - dir * renderEpsilon), + (float) (shape.radius + renderEpsilon), (float) (shape.height + 2*dir*renderEpsilon), shape.axis, + shape.subdivisions, shape.radius == 0, shape.r, shape.g, shape.b, shape.a); + } @Override public void renderFaces(Tessellator tessellator, BufferBuilder bufferBuilder, double cx, double cy, double cz, float partialTick) { if (shape.fa == 0.0) return; - //Vec3d vc = shape.relativiseRender(client.world, shape.center, partialTick); - //RenderSystem.lineWidth(1.0f); - //drawSphereFaces(tessellator, bufferBuilder, - // (float)(vc.x-cx-renderEpsilon), (float)(vc.y-cy-renderEpsilon), (float)(vc.z-cz-renderEpsilon), - // shape.radius, shape.subdivisions, - // shape.fr, shape.fg, shape.fb, shape.fa); + Vec3d vc = shape.relativiseRender(client.world, shape.center, partialTick); + RenderSystem.lineWidth(1.0f); + double dir = MathHelper.sign(shape.height); + drawCylinderFaces(tessellator, bufferBuilder, + (float) (vc.x - cx - dir * renderEpsilon), (float) (vc.y - cy - dir * renderEpsilon), (float) (vc.z - cz - dir * renderEpsilon), + (float) (shape.radius + renderEpsilon), (float) (shape.height + 2*dir*renderEpsilon), shape.axis, + shape.subdivisions, shape.radius == 0, + shape.fr, shape.fg, shape.fb, shape.fa); } } @@ -429,15 +434,19 @@ public class ShapesRenderer public static void drawCylinderWireframe(Tessellator tessellator, BufferBuilder builder, float cx, float cy, float cz, - float r, float h, Direction.Axis axis, int subd, + float r, float h, Direction.Axis axis, int subd, boolean isFlat, float red, float grn, float blu, float alpha) { float step = (float)Math.PI / (subd/2); int num_steps180 = (int)(Math.PI / step)+1; int num_steps360 = (int)(2*Math.PI / step); - int hsteps = (h>0) ? ((int)Math.ceil(h / (step*r))+1) : 1; - float hstep = (h>0) ? (h / (hsteps-1)) : 1; - // draw base + int hsteps = 1; + float hstep = 1.0f; + if (!isFlat) + { + hsteps = (int) Math.ceil(MathHelper.abs(h) / (step * r)) + 1; + hstep = h / (hsteps - 1); + }// draw base if (axis == Direction.Axis.Y) { @@ -456,7 +465,7 @@ public class ShapesRenderer tessellator.draw(); } - if (h > 0) + if (!isFlat) { for (int i = 0; i <= num_steps180; i++) { @@ -473,6 +482,19 @@ public class ShapesRenderer tessellator.draw(); } } + else + { + builder.begin(GL11.GL_LINES, VertexFormats.POSITION_COLOR); + for (int i = 0; i <= num_steps180; i++) + { + float theta = step * i; + float x = r * MathHelper.cos(theta); + float z = r * MathHelper.sin(theta); + builder.vertex(cx - x, cy, cz + z).color(red, grn, blu, alpha).next(); + builder.vertex(cx + x, cy, cz - z).color(red, grn, blu, alpha).next(); + } + tessellator.draw(); + } } else if (axis == Direction.Axis.X) @@ -491,6 +513,37 @@ public class ShapesRenderer } tessellator.draw(); } + + if (!isFlat) + { + for (int i = 0; i <= num_steps180; i++) + { + builder.begin(GL11.GL_LINE_LOOP, VertexFormats.POSITION_COLOR); + float theta = step * i; + float y = r * MathHelper.cos(theta); + + float z = r * MathHelper.sin(theta); + + builder.vertex(cx + 0, cy - y, cz + z).color(red, grn, blu, alpha).next(); + builder.vertex(cx + 0, cy + y, cz - z).color(red, grn, blu, alpha).next(); + builder.vertex(cx + h, cy + y, cz - z).color(red, grn, blu, alpha).next(); + builder.vertex(cx + h, cy - y, cz + z).color(red, grn, blu, alpha).next(); + tessellator.draw(); + } + } + else + { + builder.begin(GL11.GL_LINES, VertexFormats.POSITION_COLOR); + for (int i = 0; i <= num_steps180; i++) + { + float theta = step * i; + float y = r * MathHelper.cos(theta); + float z = r * MathHelper.sin(theta); + builder.vertex(cx, cy - y, cz + z).color(red, grn, blu, alpha).next(); + builder.vertex(cx, cy + y, cz - z).color(red, grn, blu, alpha).next(); + } + tessellator.draw(); + } } else if (axis == Direction.Axis.Z) { @@ -508,6 +561,161 @@ public class ShapesRenderer } tessellator.draw(); } + if (!isFlat) + { + for (int i = 0; i <= num_steps180; i++) + { + builder.begin(GL11.GL_LINE_LOOP, VertexFormats.POSITION_COLOR); + float theta = step * i; + float x = r * MathHelper.cos(theta); + + float y = r * MathHelper.sin(theta); + + builder.vertex(cx + x, cy - y, cz + 0).color(red, grn, blu, alpha).next(); + builder.vertex(cx - x, cy + y, cz + 0).color(red, grn, blu, alpha).next(); + builder.vertex(cx - x, cy + y, cz + h).color(red, grn, blu, alpha).next(); + builder.vertex(cx + x, cy - y, cz + h).color(red, grn, blu, alpha).next(); + tessellator.draw(); + } + } + else + { + builder.begin(GL11.GL_LINES, VertexFormats.POSITION_COLOR); + for (int i = 0; i <= num_steps180; i++) + { + float theta = step * i; + float x = r * MathHelper.cos(theta); + float y = r * MathHelper.sin(theta); + builder.vertex(cx + x, cy - y, cz).color(red, grn, blu, alpha).next(); + builder.vertex(cx - x, cy + y, cz).color(red, grn, blu, alpha).next(); + } + tessellator.draw(); + } + + } + } + + public static void drawCylinderFaces(Tessellator tessellator, BufferBuilder builder, + float cx, float cy, float cz, + float r, float h, Direction.Axis axis, int subd, boolean isFlat, + float red, float grn, float blu, float alpha) + { + float step = (float)Math.PI / (subd/2); + int num_steps180 = (int)(Math.PI / step)+1; + int num_steps360 = (int)(2*Math.PI / step)+1; + + if (axis == Direction.Axis.Y) + { + + builder.begin(GL11.GL_TRIANGLE_FAN, VertexFormats.POSITION_COLOR); + builder.vertex(cx, cy, cz).color(red, grn, blu, alpha).next(); + for (int i = 0; i <= num_steps360; i++) + { + float theta = step * i; + float x = r * MathHelper.cos(theta); + float z = r * MathHelper.sin(theta); + builder.vertex(x + cx, cy, z + cz).color(red, grn, blu, alpha).next(); + } + tessellator.draw(); + if (!isFlat) + { + builder.begin(GL11.GL_TRIANGLE_FAN, VertexFormats.POSITION_COLOR); + builder.vertex(cx, cy+h, cz).color(red, grn, blu, alpha).next(); + for (int i = 0; i <= num_steps360; i++) + { + float theta = step * i; + float x = r * MathHelper.cos(theta); + float z = r * MathHelper.sin(theta); + builder.vertex(x + cx, cy+h, z + cz).color(red, grn, blu, alpha).next(); + } + tessellator.draw(); + + builder.begin(GL11.GL_QUAD_STRIP, VertexFormats.POSITION_COLOR); + for (int i = 0; i <= num_steps360; i++) + { + float theta = step * i; + float x = r * MathHelper.cos(theta); + float z = r * MathHelper.sin(theta); + builder.vertex(cx + x, cy + 0, cz + z).color(red, grn, blu, alpha).next(); + builder.vertex(cx + x, cy + h, cz + z).color(red, grn, blu, alpha).next(); + } + tessellator.draw(); + } + + } + else if (axis == Direction.Axis.X) + { + builder.begin(GL11.GL_TRIANGLE_FAN, VertexFormats.POSITION_COLOR); + builder.vertex(cx, cy, cz).color(red, grn, blu, alpha).next(); + for (int i = 0; i <= num_steps360; i++) + { + float theta = step * i; + float y = r * MathHelper.cos(theta); + float z = r * MathHelper.sin(theta); + builder.vertex(cx, cy + y, z + cz).color(red, grn, blu, alpha).next(); + } + tessellator.draw(); + if (!isFlat) + { + builder.begin(GL11.GL_TRIANGLE_FAN, VertexFormats.POSITION_COLOR); + builder.vertex(cx+h, cy, cz).color(red, grn, blu, alpha).next(); + for (int i = 0; i <= num_steps360; i++) + { + float theta = step * i; + float y = r * MathHelper.cos(theta); + float z = r * MathHelper.sin(theta); + builder.vertex(cx+h, cy + y, cz + z).color(red, grn, blu, alpha).next(); + } + tessellator.draw(); + + builder.begin(GL11.GL_QUAD_STRIP, VertexFormats.POSITION_COLOR); + for (int i = 0; i <= num_steps360; i++) + { + float theta = step * i; + float y = r * MathHelper.cos(theta); + float z = r * MathHelper.sin(theta); + builder.vertex(cx + 0, cy + y, cz + z).color(red, grn, blu, alpha).next(); + builder.vertex(cx + h, cy + y, cz + z).color(red, grn, blu, alpha).next(); + } + tessellator.draw(); + } + } + else if (axis == Direction.Axis.Z) + { + builder.begin(GL11.GL_TRIANGLE_FAN, VertexFormats.POSITION_COLOR); + builder.vertex(cx, cy, cz).color(red, grn, blu, alpha).next(); + for (int i = 0; i <= num_steps360; i++) + { + float theta = step * i; + float x = r * MathHelper.cos(theta); + float y = r * MathHelper.sin(theta); + builder.vertex(x + cx, cy+y, cz).color(red, grn, blu, alpha).next(); + } + tessellator.draw(); + if (!isFlat) + { + builder.begin(GL11.GL_TRIANGLE_FAN, VertexFormats.POSITION_COLOR); + builder.vertex(cx, cy, cz+h).color(red, grn, blu, alpha).next(); + for (int i = 0; i <= num_steps360; i++) + { + float theta = step * i; + float x = r * MathHelper.cos(theta); + float y = r * MathHelper.sin(theta); + builder.vertex(x + cx, cy+y, cz+h).color(red, grn, blu, alpha).next(); + } + tessellator.draw(); + + builder.begin(GL11.GL_QUAD_STRIP, VertexFormats.POSITION_COLOR); + for (int i = 0; i <= num_steps360; i++) + { + float theta = step * i; + float x = r * MathHelper.cos(theta); + float y = r * MathHelper.sin(theta); + builder.vertex(cx + x, cy + y, cz + 0).color(red, grn, blu, alpha).next(); + builder.vertex(cx + x, cy + y, cz + h).color(red, grn, blu, alpha).next(); + } + tessellator.draw(); + } } }