1313import meteordevelopment .meteorclient .events .world .TickEvent ;
1414import meteordevelopment .meteorclient .settings .BoolSetting ;
1515import meteordevelopment .meteorclient .settings .ColorSetting ;
16+ import meteordevelopment .meteorclient .settings .DoubleSetting ;
1617import meteordevelopment .meteorclient .settings .EnumSetting ;
1718import meteordevelopment .meteorclient .settings .IntSetting ;
1819import meteordevelopment .meteorclient .settings .Setting ;
@@ -87,7 +88,7 @@ public class SculkRangeEsp extends Module {
8788 private final Setting <SettingColor > shapeColor = sgGeneral .add (new ColorSetting .Builder ()
8889 .name ("shape-color" )
8990 .description ("Color of the range indicator." )
90- .defaultValue (new SettingColor (146 , 188 , 98 , 255 ))
91+ .defaultValue (new SettingColor (146 , 188 , 98 , 75 ))
9192 .build ());
9293
9394 private final Setting <Boolean > advancedView = sgGeneral .add (new BoolSetting .Builder ()
@@ -99,14 +100,14 @@ public class SculkRangeEsp extends Module {
99100 private final Setting <SettingColor > redstoneColor = sgGeneral .add (new ColorSetting .Builder ()
100101 .name ("redstone-shape-color" )
101102 .description ("Color of the range indicator with redstone output." )
102- .defaultValue (new SettingColor (170 , 0 , 0 , 255 ))
103+ .defaultValue (new SettingColor (170 , 0 , 0 , 75 ))
103104 .visible (advancedView ::get )
104105 .build ());
105106
106107 private final Setting <SettingColor > shriekerColor = sgGeneral .add (new ColorSetting .Builder ()
107108 .name ("shrieker-shape-color" )
108109 .description ("Color of the range indicator with a shrieker in range." )
109- .defaultValue (new SettingColor (0 , 69 , 170 , 255 ))
110+ .defaultValue (new SettingColor (0 , 69 , 170 , 75 ))
110111 .visible (advancedView ::get )
111112 .build ());
112113
@@ -117,12 +118,19 @@ public class SculkRangeEsp extends Module {
117118 .visible (() -> shape .get () == Shape .Circle || shape .get () == Shape .Both )
118119 .build ());
119120
121+ private final Setting <Double > circleThickness = sgGeneral .add (new DoubleSetting .Builder ()
122+ .name ("circle-thickness" )
123+ .description ("The thickness of the circle." )
124+ .defaultValue (0.08 )
125+ .sliderMax (1 )
126+ .visible (() -> shape .get () == Shape .Sphere || shape .get () == Shape .Both )
127+ .build ());
128+
120129 public Setting <Integer > gradation = sgGeneral .add (new IntSetting .Builder ()
121130 .name ("gradation" )
122131 .description (
123- "Determines the smoothness/detail of the sphere shape. Higher values produce a smoother sphere, lower values make it more blocky." )
132+ "Determines the smoothness of the sphere shape. Higher values produce a smoother sphere, lower values make it more blocky." )
124133 .defaultValue (30 )
125- .range (20 , 100 )
126134 .sliderRange (20 , 100 )
127135 .visible (() -> shape .get () == Shape .Sphere || shape .get () == Shape .Both )
128136 .build ());
@@ -282,29 +290,47 @@ private void onRender(Render3DEvent event) {
282290 if (renderAtPlayerHeight .get ()) {
283291 renderPos = new BlockPos (sensor .pos .getX (), (int ) mc .player .getY (), sensor .pos .getZ ());
284292 }
285- renderCircle (event , radius , renderPos , sensor );
293+ renderCircle (event , radius , circleThickness . get (), renderPos , sensor );
286294 }
287295 }
288296 }
289297 }
290298
291- private void renderCircle (Render3DEvent event , double radius , BlockPos origin , FoundSensor sensor ) {
299+ private void renderCircle (Render3DEvent event , double radius , double thickness , BlockPos origin ,
300+ FoundSensor sensor ) {
292301 final double maxSegmentLength = 0.2 ;
293302
294303 int segments = (int ) Math .ceil (2 * Math .PI * radius / maxSegmentLength );
295304 segments = Math .max (16 , segments );
296305
297- Vec3d [] pts = new Vec3d [segments ];
306+ Vec3d [] outerPts = new Vec3d [segments ];
307+ Vec3d [] innerPts = new Vec3d [segments ];
298308 SettingColor [] cols = new SettingColor [segments ];
299309
300310 boolean both = sensor .hasRedstoneOutput () && sensor .shriekerInRange ();
301311 boolean advanced = advancedView .get ();
302312
313+ double outerRadius = radius + thickness / 2.0 ;
314+ double innerRadius = radius - thickness / 2.0 ;
315+
316+ if (innerRadius < 0 ) {
317+ innerRadius = 0 ;
318+ }
319+
303320 for (int s = 0 ; s < segments ; s ++) {
304321 double angle = 2 * Math .PI * s / segments ;
305- double sin = Math .sin (angle ) * radius ;
306- double cos = Math .cos (angle ) * radius ;
307- pts [s ] = new Vec3d (origin .getX () + sin , origin .getY (), origin .getZ () + cos );
322+ double sin = Math .sin (angle );
323+ double cos = Math .cos (angle );
324+
325+ outerPts [s ] = new Vec3d (
326+ origin .getX () + sin * outerRadius ,
327+ origin .getY (),
328+ origin .getZ () + cos * outerRadius );
329+
330+ innerPts [s ] = new Vec3d (
331+ origin .getX () + sin * innerRadius ,
332+ origin .getY (),
333+ origin .getZ () + cos * innerRadius );
308334
309335 int deg = (int ) Math .round (Math .toDegrees (angle )) % 360 ;
310336
@@ -327,34 +353,63 @@ private void renderCircle(Render3DEvent event, double radius, BlockPos origin, F
327353
328354 for (int s = 0 ; s < segments ; s ++) {
329355 int next = (s + 1 ) % segments ;
330- event .renderer .line (
331- pts [s ].x , pts [s ].y , pts [s ].z ,
332- pts [next ].x , pts [next ].y , pts [next ].z ,
333- cols [next ]);
356+
357+ event .renderer .triangles .ensureTriCapacity ();
358+
359+ int outer1 = event .renderer .triangles
360+ .vec3 (outerPts [s ].x , outerPts [s ].y , outerPts [s ].z )
361+ .color (cols [s ])
362+ .next ();
363+
364+ int outer2 = event .renderer .triangles
365+ .vec3 (outerPts [next ].x , outerPts [next ].y , outerPts [next ].z )
366+ .color (cols [next ])
367+ .next ();
368+
369+ int inner1 = event .renderer .triangles
370+ .vec3 (innerPts [s ].x , innerPts [s ].y , innerPts [s ].z )
371+ .color (cols [s ])
372+ .next ();
373+
374+ int inner2 = event .renderer .triangles
375+ .vec3 (innerPts [next ].x , innerPts [next ].y , innerPts [next ].z )
376+ .color (cols [next ])
377+ .next ();
378+
379+ event .renderer .triangles .triangle (outer1 , outer2 , inner1 );
380+ event .renderer .triangles .triangle (inner1 , outer2 , inner2 );
334381 }
335382 }
336383
337384 private void renderSphere (Render3DEvent event , double radius , int gradation , FoundSensor sensor ) {
338385 boolean advanced = advancedView .get ();
339386 boolean both = sensor .hasRedstoneOutput () && sensor .shriekerInRange ();
340387
341- for (float alpha = 0.0f ; alpha < Math .PI ; alpha += Math .PI / gradation ) {
342- for (float beta = 0.0f ; beta < 2.0 * Math .PI ; beta += Math .PI / gradation ) {
343- double x1 = sensor .pos .getX () + radius * Math .cos (beta ) * Math .sin (alpha );
344- double y1 = sensor .pos .getY () + radius * Math .sin (beta ) * Math .sin (alpha );
345- double z1 = sensor .pos .getZ () + radius * Math .cos (alpha );
388+ double cx = sensor .pos .getX ();
389+ double cy = sensor .pos .getY ();
390+ double cz = sensor .pos .getZ ();
346391
347- double sin = Math .sin (alpha + Math .PI / gradation );
348- double x2 = sensor .pos .getX () + radius * Math .cos (beta ) * sin ;
349- double y2 = sensor .pos .getY () + radius * Math .sin (beta ) * sin ;
350- double z2 = sensor .pos .getZ () + radius * Math .cos (alpha + Math .PI / gradation );
392+ int horizontalSteps = Math .max (8 , gradation );
393+ int verticalSteps = Math .max (16 , gradation * 2 );
351394
352- SettingColor color ;
395+ for (int hor = 0 ; hor < horizontalSteps ; hor ++) {
396+ double theta1 = Math .PI * hor / horizontalSteps ;
397+ double theta2 = Math .PI * (hor + 1 ) / horizontalSteps ;
353398
399+ for (int vert = 0 ; vert < verticalSteps ; vert ++) {
400+ double phi1 = 2.0 * Math .PI * vert / verticalSteps ;
401+ double phi2 = 2.0 * Math .PI * (vert + 1 ) / verticalSteps ;
402+
403+ Vec3d p1 = spherePoint (cx , cy , cz , radius , theta1 , phi1 );
404+ Vec3d p2 = spherePoint (cx , cy , cz , radius , theta1 , phi2 );
405+ Vec3d p3 = spherePoint (cx , cy , cz , radius , theta2 , phi2 );
406+ Vec3d p4 = spherePoint (cx , cy , cz , radius , theta2 , phi1 );
407+
408+ SettingColor color ;
354409 if (!advanced ) {
355410 color = shapeColor .get ();
356411 } else if (both ) {
357- int segmentIndex = ( int ) ( alpha / ( Math . PI / gradation ) + beta / ( Math . PI / gradation )) ;
412+ int segmentIndex = hor + vert ;
358413 color = (segmentIndex % 2 == 0 ) ? redstoneColor .get () : shriekerColor .get ();
359414 } else if (sensor .hasRedstoneOutput ()) {
360415 color = redstoneColor .get ();
@@ -364,11 +419,29 @@ private void renderSphere(Render3DEvent event, double radius, int gradation, Fou
364419 color = shapeColor .get ();
365420 }
366421
367- event .renderer .line (x1 , y1 , z1 , x2 , y2 , z2 , color );
422+ event .renderer .triangles .ensureQuadCapacity ();
423+
424+ int i1 = event .renderer .triangles .vec3 (p1 .x , p1 .y , p1 .z ).color (color ).next ();
425+ int i2 = event .renderer .triangles .vec3 (p2 .x , p2 .y , p2 .z ).color (color ).next ();
426+ int i3 = event .renderer .triangles .vec3 (p3 .x , p3 .y , p3 .z ).color (color ).next ();
427+ int i4 = event .renderer .triangles .vec3 (p4 .x , p4 .y , p4 .z ).color (color ).next ();
428+
429+ event .renderer .triangles .triangle (i1 , i2 , i3 );
430+ event .renderer .triangles .triangle (i1 , i3 , i4 );
368431 }
369432 }
370433 }
371434
435+ private Vec3d spherePoint (double cx , double cy , double cz , double r , double theta , double phi ) {
436+ double sinTheta = Math .sin (theta );
437+
438+ double x = cx + r * sinTheta * Math .cos (phi );
439+ double y = cy + r * Math .cos (theta );
440+ double z = cz + r * sinTheta * Math .sin (phi );
441+
442+ return new Vec3d (x , y , z );
443+ }
444+
372445 private record FoundSensor (SensorType sensorType , BlockPos pos , boolean hasRedstoneOutput ,
373446 boolean shriekerInRange ) {
374447 }
0 commit comments