Skip to content

Commit 4859124

Browse files
committed
Generify wire rendering; refactor
1 parent 35f0891 commit 4859124

16 files changed

Lines changed: 227 additions & 129 deletions

src/main/java/falseresync/vivatech/client/VivatechClient.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
import falseresync.vivatech.client.hud.VivatechHud;
66
import falseresync.vivatech.client.particle.VivatechParticleFactories;
77
import falseresync.vivatech.client.rendering.VivatechRendering;
8+
import falseresync.vivatech.client.wire.ClientWireManager;
9+
import falseresync.vivatech.client.wire.VivatechWireParameters;
810
import falseresync.vivatech.common.Vivatech;
911
import falseresync.vivatech.common.config.TranslatableEnum;
1012
import falseresync.vivatech.common.config.TranslatableEnumGuiProvider;
1113
import falseresync.vivatech.common.config.VivatechConfig;
1214
import falseresync.vivatech.network.VivatechClientReceivers;
1315
import me.shedaniel.autoconfig.AutoConfig;
1416
import net.fabricmc.api.ClientModInitializer;
15-
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientChunkEvents;
1617
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
1718
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
1819
import org.slf4j.LoggerFactory;
@@ -34,6 +35,7 @@ public void onInitializeClient() {
3435
VivatechParticleFactories.init();
3536
VivatechGui.init();
3637
VivatechKeybindings.init();
38+
VivatechWireParameters.registerAll();
3739
VivatechClientReceivers.registerAll();
3840
ClientPlayerInventoryEvents.init();
3941

src/main/java/falseresync/vivatech/client/rendering/RenderingUtil.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import net.minecraft.world.BlockRenderView;
2424
import net.minecraft.world.World;
2525
import org.jetbrains.annotations.Nullable;
26+
import org.joml.Matrix4f;
27+
import org.joml.Vector3f;
2628

2729
import java.util.Objects;
2830

@@ -111,4 +113,16 @@ public static void drawTexture(MatrixStack matrices, VertexConsumer buffer, int
111113
buffer.vertex(positionMatrix, x2, y2, z).texture(u2, v2).color(tint).overlay(overlay).light(light).normal(0, 1, 0);
112114
buffer.vertex(positionMatrix, x2, y1, z).texture(u2, v1).color(tint).overlay(overlay).light(light).normal(0, 1, 0);
113115
}
116+
117+
public static void drawQuad(VertexConsumer buffer, Matrix4f positionMatrix, Vector3f vUpLeft, Vector3f vDownLeft, Vector3f vDownRight, Vector3f vUpRight, float u1, float u2, float v1, float v2, int tint, int light, int overlay, Vector3f normal) {
118+
// Counter-clockwise https://stackoverflow.com/a/8142461
119+
setupVertex(vUpLeft, buffer, positionMatrix, u1, v1, tint, light, overlay, normal);
120+
setupVertex(vDownLeft, buffer, positionMatrix, u2, v1, tint, light, overlay, normal);
121+
setupVertex(vDownRight, buffer, positionMatrix, u2, v2, tint, light, overlay, normal);
122+
setupVertex(vUpRight, buffer, positionMatrix, u1, v2, tint, light, overlay, normal);
123+
}
124+
125+
public static void setupVertex(Vector3f vertex, VertexConsumer buffer, Matrix4f positionMatrix, float u, float v, int tint, int light, int overlay, Vector3f normal) {
126+
buffer.vertex(positionMatrix, vertex.x, vertex.y, vertex.z).texture(u, v).color(tint).light(light).overlay(overlay).normal(normal.x, normal.y, normal.z);
127+
}
114128
}

src/main/java/falseresync/vivatech/client/rendering/world/CometWarpBeaconRenderer.java

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ public class CometWarpBeaconRenderer implements WorldRenderEvents.AfterEntities
2929
private static final int TINT_BASE = Color.ofHsv(0f, 0f, 1, 0.5f).argb();
3030
private static final int TINT_CROWN = Color.WHITE.argb();
3131

32-
private static void drawBase(WorldRenderContext context, MatrixStack matrices, VertexConsumer buffer, int light, int overlay) {
32+
private static void drawBase(WorldRenderContext context, MatrixStack matrices, int light, int overlay) {
33+
var buffer = context.consumers().getBuffer(BASE_LAYER);
34+
3335
matrices.push();
3436
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90));
3537

@@ -59,6 +61,25 @@ private static void drawBasePart(MatrixStack matrices, VertexConsumer buffer, in
5961
matrices.pop();
6062
}
6163

64+
private static void drawCrown(WorldRenderContext context, MatrixStack matrices, int light, int overlay) {
65+
matrices.push();
66+
var adjustment = new Matrix4f()
67+
.rotateAround(RotationAxis.POSITIVE_X.rotationDegrees(180), 0, 0.5f, 0)
68+
.translate(0, 0.25f, -1)
69+
.scaleAround(0.5f, 0.5f, 0.5f, 0.5f);
70+
matrices.multiplyPositionMatrix(adjustment);
71+
72+
var perPanelAdjustment = new Matrix4f().rotateAround(RotationAxis.POSITIVE_Y.rotationDegrees(60), 0.5f, 0, 0.5f);
73+
var sprite = CROWN_TEX.getSprite();
74+
var buffer = CROWN_TEX.getVertexConsumer(context.consumers(), RenderLayer::getEntityTranslucentEmissive);
75+
for (int i = 0; i < 6; i++) {
76+
matrices.multiplyPositionMatrix(perPanelAdjustment);
77+
RenderingUtil.drawSprite(matrices, buffer, sprite, TINT_BASE, light, overlay, 0, 1, 0, 1, -0.365f);
78+
}
79+
80+
matrices.pop();
81+
}
82+
6283
@SuppressWarnings("DataFlowIssue")
6384
@Override
6485
public void afterEntities(WorldRenderContext context) {
@@ -90,26 +111,8 @@ public void afterEntities(WorldRenderContext context) {
90111
var translation = context.camera().getPos().relativize(Vec3d.of(anchor.pos()));
91112
matrices.translate(translation.x, translation.y, translation.z);
92113

93-
var buffer = context.consumers().getBuffer(BASE_LAYER);
94-
drawBase(context, matrices, buffer, light, overlay);
95-
96-
matrices.push();
97-
var adjustment = new Matrix4f()
98-
.rotateAround(RotationAxis.POSITIVE_X.rotationDegrees(180), 0, 0.5f, 0)
99-
.translate(0, 0.25f, -1)
100-
.scaleAround(0.5f, 0.5f, 0.5f, 0.5f);
101-
matrices.multiplyPositionMatrix(adjustment);
102-
103-
var perPanelAdjustment = new Matrix4f()
104-
.rotateAround(RotationAxis.POSITIVE_Y.rotationDegrees(60), 0.5f, 0, 0.5f);
105-
var sprite = CROWN_TEX.getSprite();
106-
var crownBuffer = CROWN_TEX.getVertexConsumer(context.consumers(), RenderLayer::getEntityTranslucentEmissive);
107-
for (int i = 0; i < 6; i++) {
108-
matrices.multiplyPositionMatrix(perPanelAdjustment);
109-
RenderingUtil.drawSprite(matrices, crownBuffer, sprite, TINT_BASE, light, overlay, 0, 1, 0, 1, -0.365f);
110-
}
111-
112-
matrices.pop();
114+
drawBase(context, matrices, light, overlay);
115+
drawCrown(context, matrices, light, overlay);
113116

114117
matrices.pop();
115118
}
Lines changed: 32 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,38 @@
11
package falseresync.vivatech.client.rendering.world;
22

33
import falseresync.vivatech.client.VivatechClient;
4+
import falseresync.vivatech.client.rendering.RenderingUtil;
5+
import falseresync.vivatech.client.wire.VivatechWireParameters;
6+
import falseresync.vivatech.client.wire.WireParameters;
47
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
58
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
69
import net.minecraft.client.render.*;
7-
import net.minecraft.client.texture.Sprite;
8-
import net.minecraft.client.texture.SpriteAtlasTexture;
9-
import net.minecraft.client.util.SpriteIdentifier;
1010
import net.minecraft.util.Colors;
11-
import net.minecraft.util.Util;
1211
import net.minecraft.util.math.BlockPos;
1312
import net.minecraft.util.math.Direction;
1413
import org.joml.Matrix4f;
1514
import org.joml.Vector3f;
1615

17-
import java.util.Random;
18-
import java.util.function.Function;
19-
20-
import static falseresync.vivatech.common.Vivatech.vtId;
21-
2216
public class WireRenderer implements WorldRenderEvents.AfterEntities {
23-
private static final Random RANDOM = new Random();
24-
private static final float SEGMENT_SIZE = 1 / 32f;
25-
private static final float SEGMENT_SHIFT = 1 / 64f;
26-
27-
private static final Vector3f VERTICAL_SEGMENT_NORMAL = Direction.NORTH.getUnitVector();
28-
private static final Vector3f VERTICAL_SEGMENT_SHIFT = new Vector3f(SEGMENT_SHIFT, 0, 0);
29-
private static final Vector3f NEG_VERTICAL_SEGMENT_SHIFT = new Vector3f(-SEGMENT_SHIFT, 0, 0);
30-
17+
private static final Vector3f VERTICAL_SEGMENT_NORMAL = Direction.NORTH.getUnitVector();//
3118
private static final Vector3f HORIZONTAL_SEGMENT_NORMAL = Direction.UP.getUnitVector();
32-
private static final Vector3f HORIZONTAL_SEGMENT_SHIFT = new Vector3f(0, SEGMENT_SHIFT, 0);
33-
private static final Vector3f NEG_HORIZONTAL_SEGMENT_SHIFT = new Vector3f(0, -SEGMENT_SHIFT, 0);
34-
3519
private static final int TINT = Colors.WHITE;
3620
private static final int OVERLAY = OverlayTexture.DEFAULT_UV;
3721

38-
private static final SpriteIdentifier SPRITE_ID = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, vtId("block/wire"));
39-
private Sprite sprite;
40-
private float[] defaultUv;
41-
private float segmentWidthOnAtlas;
42-
private float segmentHeightOnAtlas;
43-
private final Function<Integer, float[]> randomizedUv = Util.memoize(memoizationKey -> {
44-
var x = RANDOM.nextInt(8);
45-
var y = RANDOM.nextInt(8);
46-
return new float[] {
47-
defaultUv[0] + segmentWidthOnAtlas * x,
48-
defaultUv[0] + segmentWidthOnAtlas * (x + 1),
49-
defaultUv[2] + segmentHeightOnAtlas * y,
50-
defaultUv[2] + segmentHeightOnAtlas * (y + 1),
51-
};
52-
});
53-
5422
@Override
5523
public void afterEntities(WorldRenderContext context) {
5624
var wires = VivatechClient.getClientWireManager().getWires(context.world().getRegistryKey());
5725
if (wires.isEmpty()) {
5826
return;
5927
}
6028

61-
if (sprite == null) {
62-
sprite = SPRITE_ID.getSprite();
63-
defaultUv = new float[] {
64-
sprite.getMinU(), sprite.getMaxU(), sprite.getMinV(), sprite.getMaxV()
65-
};
66-
segmentWidthOnAtlas = (defaultUv[1] - defaultUv[0]) / 8f;
67-
segmentHeightOnAtlas = (defaultUv[3] - defaultUv[2]) / 8f;
68-
}
69-
7029
var matrices = context.matrixStack();
71-
var buffer = sprite.getTextureSpecificVertexConsumer(context.consumers().getBuffer(RenderLayer.getCutout()));
7230
var cameraPos = context.camera().getPos();
7331

7432
for (var wire : wires) {
33+
var parameters = VivatechWireParameters.get(wire);
34+
var buffer = parameters.getSprite().getTextureSpecificVertexConsumer(context.consumers().getBuffer(RenderLayer.getCutout()));
35+
7536
var wireEnd = wire.end().sub(wire.start(), new Vector3f());
7637
var light = WorldRenderer.getLightmapCoordinates(context.world(), BlockPos.ofFloored(wire.middle().x, wire.middle().y, wire.middle().z));
7738

@@ -84,25 +45,25 @@ public void afterEntities(WorldRenderContext context) {
8445
var direction = wireEnd.normalize(new Vector3f());
8546

8647
float length = wireEnd.length();
87-
int segmentCount = (int) (length / SEGMENT_SIZE);
48+
int segmentCount = (int) (length / parameters.getSegmentSize());
8849

8950
if (direction.x == 0 && direction.z == 0) {
90-
drawVerticalWire(wireEnd, segmentCount, buffer, positionMatrix, light);
51+
drawVerticalWire(parameters, wireEnd, segmentCount, buffer, positionMatrix, light);
9152
} else {
92-
drawHorizontalWire(direction, wireEnd, segmentCount, length, buffer, positionMatrix, light);
53+
drawHorizontalWire(parameters, direction, wireEnd, segmentCount, length, buffer, positionMatrix, light);
9354
}
9455

9556
matrices.pop();
9657
}
9758
}
9859

99-
private void drawVerticalWire(Vector3f wireEnd, int segmentCount, VertexConsumer buffer, Matrix4f positionMatrix, int light) {
60+
private void drawVerticalWire(WireParameters parameters, Vector3f wireEnd, int segmentCount, VertexConsumer buffer, Matrix4f positionMatrix, int light) {
10061
var tangent = new Vector3f(VERTICAL_SEGMENT_NORMAL);
101-
var tangentialHalfSize = tangent.mul(SEGMENT_SIZE / 2f, new Vector3f());
62+
var tangentialHalfSize = tangent.mul(parameters.getSegmentSize() / 2f, new Vector3f());
10263
var stepY = new Vector3f(0, wireEnd.y / segmentCount, 0);
10364

104-
var segmentAVertices = buildInitialSegmentVertices(tangentialHalfSize, VERTICAL_SEGMENT_SHIFT, stepY);
105-
var segmentBVertices = buildInitialSegmentVertices(tangentialHalfSize, NEG_VERTICAL_SEGMENT_SHIFT, stepY);
65+
var segmentAVertices = buildInitialSegmentVertices(tangentialHalfSize, new Vector3f(parameters.getSegmentSize() / 2, 0, 0), stepY);
66+
var segmentBVertices = buildInitialSegmentVertices(tangentialHalfSize, new Vector3f(-parameters.getSegmentSize() / 2, 0, 0), stepY);
10667

10768
for (int segmentNo = 0; segmentNo < segmentCount; segmentNo++) {
10869
for (var segmentVertex : segmentAVertices) {
@@ -112,51 +73,43 @@ private void drawVerticalWire(Vector3f wireEnd, int segmentCount, VertexConsumer
11273
segmentVertex.add(stepY);
11374
}
11475

115-
var uv = randomizedUv.apply(segmentNo);
76+
var uv = parameters.getUv(segmentNo);
11677
drawSegment(buffer, positionMatrix, segmentAVertices, uv, TINT, light, OVERLAY, VERTICAL_SEGMENT_NORMAL);
11778
drawSegment(buffer, positionMatrix, segmentBVertices, uv, TINT, light, OVERLAY, VERTICAL_SEGMENT_NORMAL);
11879
}
11980
}
12081

121-
private void drawHorizontalWire(Vector3f direction, Vector3f wireEnd, int segmentCount, float length, VertexConsumer buffer, Matrix4f positionMatrix, int light) {
82+
private void drawHorizontalWire(WireParameters parameters, Vector3f direction, Vector3f wireEnd, int segmentCount, float length, VertexConsumer buffer, Matrix4f positionMatrix, int light) {
12283
var tangent = new Vector3f(direction.x, 0, direction.z).normalize(new Vector3f()).cross(HORIZONTAL_SEGMENT_NORMAL);
123-
var tangentialHalfSize = tangent.mul(SEGMENT_SIZE / 2f, new Vector3f());
84+
var tangentialHalfSize = tangent.mul(parameters.getSegmentSize() / 2f, new Vector3f());
12485

125-
var stepXZ = direction.mul(SEGMENT_SIZE, new Vector3f());
86+
var stepXZ = direction.mul(parameters.getSegmentSize(), new Vector3f());
12687
float stepY = wireEnd.y / segmentCount;
12788

128-
var segmentAVertices = buildInitialSegmentVertices(tangentialHalfSize, HORIZONTAL_SEGMENT_SHIFT, stepXZ);
129-
var segmentBVertices = buildInitialSegmentVertices(tangentialHalfSize, NEG_HORIZONTAL_SEGMENT_SHIFT, stepXZ);
89+
var segmentAVertices = buildInitialSegmentVertices(tangentialHalfSize, new Vector3f(0, parameters.getSegmentSize() / 2, 0), stepXZ);
90+
var segmentBVertices = buildInitialSegmentVertices(tangentialHalfSize, new Vector3f(0, -parameters.getSegmentSize() / 2, 0), stepXZ);
13091

131-
var startY = getSaggedY(0, stepY, length);
92+
var startY = parameters.getSaggedY(0, stepY, length);
13293
for (int segmentNo = 0; segmentNo < segmentCount; segmentNo++) {
133-
var endY = getSaggedY(segmentNo + 1, stepY, length);
134-
advanceSegmentVertices(segmentAVertices, stepXZ, startY, endY, SEGMENT_SHIFT);
135-
advanceSegmentVertices(segmentBVertices, stepXZ, startY, endY, -SEGMENT_SHIFT);
94+
var endY = parameters.getSaggedY(segmentNo + 1, stepY, length);
95+
advanceSegmentVertices(segmentAVertices, stepXZ, startY, endY, parameters.getSegmentSize() / 2);
96+
advanceSegmentVertices(segmentBVertices, stepXZ, startY, endY, -parameters.getSegmentSize() / 2);
13697
startY = endY;
13798

138-
var uv = randomizedUv.apply(segmentNo);
99+
var uv = parameters.getUv(segmentNo);
139100
drawSegment(buffer, positionMatrix, segmentAVertices, uv, TINT, light, OVERLAY, HORIZONTAL_SEGMENT_NORMAL);
140101
drawSegment(buffer, positionMatrix, segmentBVertices, uv, TINT, light, OVERLAY, HORIZONTAL_SEGMENT_NORMAL);
141102
}
142103
}
143104

144-
private float getSaggedY(float segmentNo, float stepY, float length) {
145-
return (float) (stepY * segmentNo + getSaggingCoefficient(length) * (Math.pow(2 * (SEGMENT_SIZE * segmentNo) - length, 2) / Math.pow(length, 2) - 1));
146-
}
147-
148-
private float getSaggingCoefficient(float length) {
149-
return length < 5 ? 0.3f : 0.4f;
150-
}
151-
152-
private void advanceSegmentVertices(Vector3f[] segmentAVertices, Vector3f stepXZ, float startY, float endY, float segmentRot) {
105+
private void advanceSegmentVertices(Vector3f[] segmentAVertices, Vector3f stepXZ, float startY, float endY, float segmentShift) {
153106
for (var segmentVertex : segmentAVertices) {
154107
segmentVertex.add(stepXZ);
155108
}
156-
segmentAVertices[0].y = startY + segmentRot;
157-
segmentAVertices[1].y = startY - segmentRot;
158-
segmentAVertices[2].y = endY - segmentRot;
159-
segmentAVertices[3].y = endY + segmentRot;
109+
segmentAVertices[0].y = startY + segmentShift;
110+
segmentAVertices[1].y = startY - segmentShift;
111+
segmentAVertices[2].y = endY - segmentShift;
112+
segmentAVertices[3].y = endY + segmentShift;
160113
}
161114

162115
private Vector3f[] buildInitialSegmentVertices(Vector3f tangentialHalfSize, Vector3f segmentShift, Vector3f step) {
@@ -170,20 +123,8 @@ private Vector3f[] buildInitialSegmentVertices(Vector3f tangentialHalfSize, Vect
170123

171124
private void drawSegment(VertexConsumer buffer, Matrix4f positionMatrix, Vector3f[] vertices, float[] uv, int tint, int light, int overlay, Vector3f normal) {
172125
// Counter-clockwise - front-facing
173-
drawQuad(buffer, positionMatrix, vertices[0], vertices[1], vertices[2], vertices[3], uv[0], uv[1], uv[2], uv[3], tint, light, overlay, normal);
126+
RenderingUtil.drawQuad(buffer, positionMatrix, vertices[0], vertices[1], vertices[2], vertices[3], uv[0], uv[1], uv[2], uv[3], tint, light, overlay, normal);
174127
// Clockwise - rear-facing
175-
drawQuad(buffer, positionMatrix, vertices[0], vertices[3], vertices[2], vertices[1], uv[1], uv[0], uv[3], uv[2], tint, light, overlay, normal.negate(new Vector3f()));
176-
}
177-
178-
private void drawQuad(VertexConsumer buffer, Matrix4f positionMatrix, Vector3f vUpLeft, Vector3f vDownLeft, Vector3f vDownRight, Vector3f vUpRight, float u1, float u2, float v1, float v2, int tint, int light, int overlay, Vector3f normal) {
179-
// Counter-clockwise https://stackoverflow.com/a/8142461
180-
setupVertex(vUpLeft, buffer, positionMatrix, u1, v1, tint, light, overlay, normal);
181-
setupVertex(vDownLeft, buffer, positionMatrix, u2, v1, tint, light, overlay, normal);
182-
setupVertex(vDownRight, buffer, positionMatrix, u2, v2, tint, light, overlay, normal);
183-
setupVertex(vUpRight, buffer, positionMatrix, u1, v2, tint, light, overlay, normal);
184-
}
185-
186-
private void setupVertex(Vector3f vertex, VertexConsumer buffer, Matrix4f positionMatrix, float u, float v, int tint, int light, int overlay, Vector3f normal) {
187-
buffer.vertex(positionMatrix, vertex.x, vertex.y, vertex.z).texture(u, v).color(tint).light(light).overlay(overlay).normal(normal.x, normal.y, normal.z);
128+
RenderingUtil.drawQuad(buffer, positionMatrix, vertices[0], vertices[3], vertices[2], vertices[1], uv[1], uv[0], uv[3], uv[2], tint, light, overlay, normal.negate(new Vector3f()));
188129
}
189130
}

src/main/java/falseresync/vivatech/client/ClientWireManager.java renamed to src/main/java/falseresync/vivatech/client/wire/ClientWireManager.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package falseresync.vivatech.client;
1+
package falseresync.vivatech.client.wire;
22

33
import falseresync.vivatech.common.power.wire.Wire;
44
import falseresync.vivatech.network.c2s.RequestWiresC2SPayload;
@@ -37,11 +37,11 @@ public ClientWireManager(MinecraftClient client) {
3737
});
3838
}
3939

40-
public void onWiresAdded(RegistryKey<World> world, Set<Wire> wires) {
40+
public void addWires(RegistryKey<World> world, Set<Wire> wires) {
4141
trackers.get(world).wires.addAll(wires);
4242
}
4343

44-
public void onWiresRemoved(RegistryKey<World> world, Set<Wire> wires) {
44+
public void removeWires(RegistryKey<World> world, Set<Wire> wires) {
4545
trackers.get(world).wires.removeAll(wires);
4646
}
4747

0 commit comments

Comments
 (0)