Skip to content

Commit b596b22

Browse files
committed
render chain even if the other side is out of render distance
1 parent accee4a commit b596b22

File tree

2 files changed

+125
-58
lines changed

2 files changed

+125
-58
lines changed

src/main/java/com/simibubi/create/content/kinetics/chainConveyor/ChainConveyorBlockEntity.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -509,8 +509,7 @@ private void tickBoxVisuals(ChainConveyorPackage box) {
509509
physicsData.yaw = AngleHelper.angleLerp(.25, physicsData.yaw, box.yaw);
510510
}
511511

512-
private void calculateConnectionStats(BlockPos connection) {
513-
boolean reversed = getSpeed() < 0;
512+
public static ConnectionStats calculateConnectionStats(BlockPos connection, BlockPos worldPosition, boolean reversed) {
514513
float offBranchDistance = 35f;
515514
float direction = Mth.RAD_TO_DEG * (float) Mth.atan2(connection.getX(), connection.getZ());
516515
float angle = wrapAngle(direction - offBranchDistance * (reversed ? -1 : 1));
@@ -525,7 +524,12 @@ private void calculateConnectionStats(BlockPos connection) {
525524
.add(0, 6 / 16f, 0);
526525

527526
float length = (float) start.distanceTo(end);
528-
connectionStats.put(connection, new ConnectionStats(angle, length, start, end));
527+
return new ConnectionStats(angle, length, start, end);
528+
}
529+
530+
private void calculateConnectionStats(BlockPos connection) {
531+
boolean reversed = getSpeed() < 0;
532+
connectionStats.put(connection, calculateConnectionStats(connection, worldPosition, reversed));
529533
}
530534

531535
public boolean addConnectionTo(BlockPos target) {
@@ -737,7 +741,7 @@ protected void read(CompoundTag compound, HolderLookup.Provider registries, bool
737741
invalidateRenderBoundingBox();
738742
}
739743

740-
public float wrapAngle(float angle) {
744+
public static float wrapAngle(float angle) {
741745
angle %= 360;
742746
if (angle < 0)
743747
angle += 360;

src/main/java/com/simibubi/create/content/kinetics/chainConveyor/ChainConveyorRenderer.java

Lines changed: 117 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
import java.util.List;
44
import java.util.Map.Entry;
55

6+
import net.minecraft.client.multiplayer.ClientLevel;
7+
import net.minecraft.core.SectionPos;
8+
import net.minecraft.world.level.chunk.ChunkAccess;
9+
10+
import net.minecraft.world.level.chunk.LevelChunk;
11+
import net.minecraft.world.level.chunk.status.ChunkStatus;
12+
613
import org.joml.FrustumIntersection;
714
import org.joml.Matrix4f;
815

@@ -51,7 +58,7 @@ public ChainConveyorRenderer(Context context) {
5158

5259
@Override
5360
protected void renderSafe(ChainConveyorBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
54-
int light, int overlay) {
61+
int light, int overlay) {
5562
super.renderSafe(be, partialTicks, ms, buffer, light, overlay);
5663
BlockPos pos = be.getBlockPos();
5764

@@ -81,7 +88,7 @@ protected void renderSafe(ChainConveyorBlockEntity be, float partialTicks, PoseS
8188
}
8289

8390
private void renderBox(ChainConveyorBlockEntity be, PoseStack ms, MultiBufferSource buffer, int overlay,
84-
BlockPos pos, ChainConveyorPackage box, float partialTicks, FrustumIntersection frustum, Vec3 camPos) {
91+
BlockPos pos, ChainConveyorPackage box, float partialTicks, FrustumIntersection frustum, Vec3 camPos) {
8592
if (box.worldPosition == null)
8693
return;
8794
if (box.item == null || box.item.isEmpty())
@@ -93,7 +100,10 @@ private void renderBox(ChainConveyorBlockEntity be, PoseStack ms, MultiBufferSou
93100

94101
Vec3 position = physicsData.prevPos.lerp(physicsData.pos, partialTicks);
95102
Vec3 targetPosition = physicsData.prevTargetPos.lerp(physicsData.targetPos, partialTicks);
96-
if (frustum != null && !frustum.testSphere((float) (targetPosition.x - camPos.x), (float) (targetPosition.y - camPos.y), (float) (targetPosition.z - camPos.z), 1))
103+
if (frustum != null && !frustum.testSphere(
104+
(float) (targetPosition.x - camPos.x),
105+
(float) (targetPosition.y - camPos.y),
106+
(float) (targetPosition.z - camPos.z), 1))
97107
return;
98108

99109
float yaw = AngleHelper.angleLerp(partialTicks, physicsData.prevYaw, physicsData.yaw);
@@ -125,7 +135,7 @@ private void renderBox(ChainConveyorBlockEntity be, PoseStack ms, MultiBufferSou
125135
zRot = Mth.clamp(zRot, -25, 25);
126136
xRot = Mth.clamp(xRot, -25, 25);
127137

128-
for (SuperByteBuffer buf : new SuperByteBuffer[] { rigBuffer, boxBuffer }) {
138+
for (SuperByteBuffer buf : new SuperByteBuffer[]{rigBuffer, boxBuffer}) {
129139
buf.translate(offset);
130140
buf.translate(0, 10 / 16f, 0);
131141
buf.rotateYDegrees(yaw);
@@ -221,7 +231,12 @@ public static Vector3f calculateLODCut(Vec3 start, Vec3 end, Vec3 cameraPos) {
221231
}
222232

223233
private void renderChains(ChainConveyorBlockEntity be, PoseStack ms, MultiBufferSource buffer, int light,
224-
int overlay, FrustumIntersection frustum, Vec3 camPos, boolean renderCentre) {
234+
int overlay, FrustumIntersection frustum, Vec3 camPos, boolean renderCentre) {
235+
if (frustum != null) {
236+
float renderDistance = Minecraft.getInstance().gameRenderer.getRenderDistance();
237+
if (camPos.distanceToSqr(be.getBlockPos().getCenter()) > renderDistance * renderDistance)
238+
return;
239+
}
225240
float time = AnimationTickHolder.getRenderTime(be.getLevel()) / (360f / Math.abs(be.getSpeed()));
226241
time %= 1;
227242
if (time < 0)
@@ -234,8 +249,15 @@ private void renderChains(ChainConveyorBlockEntity be, PoseStack ms, MultiBuffer
234249
if (stats == null)
235250
continue;
236251

237-
Vec3 diff = stats.end()
238-
.subtract(stats.start());
252+
Level level = be.getLevel();
253+
BlockPos tilePos = be.getBlockPos();
254+
BlockPos targetPos = tilePos.offset(blockPos);
255+
256+
Vec3 start = stats.start();
257+
Vec3 end = stats.end();
258+
259+
Vec3 diff = end
260+
.subtract(start);
239261
double yaw = (float) Mth.RAD_TO_DEG * Mth.atan2(diff.x, diff.z);
240262
if (!VisualizationManager.supportsVisualization(be.getLevel()) && renderCentre) {
241263
SuperByteBuffer guard =
@@ -248,59 +270,100 @@ private void renderChains(ChainConveyorBlockEntity be, PoseStack ms, MultiBuffer
248270
.overlay(overlay)
249271
.renderInto(ms, buffer.getBuffer(RenderType.cutoutMipped()));
250272
}
251-
if (frustum != null && !frustum.testLineSegment((float) (stats.start().x - camPos.x), (float) (stats.start().y - camPos.y), (float) (stats.start().z - camPos.z),
252-
(float) (stats.end().x - camPos.x), (float) (stats.end().y - camPos.y), (float) (stats.end().z - camPos.z))) {
253-
continue;
273+
if (frustum == null || frustum.testLineSegment((float) (start.x - camPos.x), (float) (start.y - camPos.y), (float) (start.z - camPos.z),
274+
(float) (end.x - camPos.x), (float) (end.y - camPos.y), (float) (end.z - camPos.z))) {
275+
double pitch = (float) Mth.RAD_TO_DEG * Mth.atan2(diff.y, diff.multiply(1, 0, 1)
276+
.length());
277+
278+
int light1 = LightTexture.pack(level.getBrightness(LightLayer.BLOCK, tilePos),
279+
level.getBrightness(LightLayer.SKY, tilePos));
280+
int light2 = LightTexture.pack(level.getBrightness(LightLayer.BLOCK, targetPos),
281+
level.getBrightness(LightLayer.SKY, targetPos));
282+
283+
Vec3 startOffset = start.subtract(Vec3.atCenterOf(tilePos));
284+
285+
ms.pushPose();
286+
var chain = TransformStack.of(ms);
287+
chain.center();
288+
chain.translate(startOffset);
289+
chain.rotateYDegrees((float) yaw);
290+
chain.rotateXDegrees(90 - (float) pitch);
291+
chain.rotateYDegrees(45);
292+
chain.translate(0, 8 / 16f, 0);
293+
chain.uncenter();
294+
295+
if (frustum != null) {
296+
renderChainWithLod(ms, buffer, animation, light1, light2, camPos, start, end, chain);
297+
} else {
298+
renderChain(ms, buffer, animation, 0, stats.chainLength(), light1, light2, false);
299+
}
300+
ms.popPose();
254301
}
255302

256-
double pitch = (float) Mth.RAD_TO_DEG * Mth.atan2(diff.y, diff.multiply(1, 0, 1)
257-
.length());
303+
if (frustum == null)
304+
continue;
258305

259-
Level level = be.getLevel();
260-
BlockPos tilePos = be.getBlockPos();
306+
float renderDistance = Minecraft.getInstance().gameRenderer.getRenderDistance();
307+
if (camPos.distanceToSqr(targetPos.getCenter()) <= renderDistance * renderDistance)
308+
continue;
261309

262-
int light1 = LightTexture.pack(level.getBrightness(LightLayer.BLOCK, tilePos),
263-
level.getBrightness(LightLayer.SKY, tilePos));
264-
int light2 = LightTexture.pack(level.getBrightness(LightLayer.BLOCK, tilePos.offset(blockPos)),
265-
level.getBrightness(LightLayer.SKY, tilePos.offset(blockPos)));
266-
267-
Vec3 startOffset = stats.start().subtract(Vec3.atCenterOf(tilePos));
268-
269-
ms.pushPose();
270-
var chain = TransformStack.of(ms);
271-
chain.center();
272-
chain.translate(startOffset);
273-
chain.rotateYDegrees((float) yaw);
274-
chain.rotateXDegrees(90 - (float) pitch);
275-
chain.rotateYDegrees(45);
276-
chain.translate(0, 8 / 16f, 0);
277-
chain.uncenter();
278-
279-
if (frustum != null) {
280-
Vector3f length = calculateLODCut(stats.start(), stats.end(), camPos);
281-
if (length.x > 1e-6f) {
282-
renderChain(ms, buffer, animation, 0, length.x, light1, light2, true);
283-
}
310+
boolean reversed = be.getSpeed() < 0;
311+
ConnectionStats virtualStats = ChainConveyorBlockEntity.calculateConnectionStats(
312+
blockPos.multiply(-1),
313+
targetPos,
314+
reversed
315+
);
316+
317+
start = virtualStats.start();
318+
end = virtualStats.end();
319+
320+
if (frustum.testLineSegment((float) (start.x - camPos.x), (float) (start.y - camPos.y), (float) (start.z - camPos.z),
321+
(float) (end.x - camPos.x), (float) (end.y - camPos.y), (float) (end.z - camPos.z))) {
322+
diff = end.subtract(start);
323+
yaw = (float) Mth.RAD_TO_DEG * Mth.atan2(diff.x, diff.z);
324+
double pitch = (float) Mth.RAD_TO_DEG * Mth.atan2(diff.y, diff.multiply(1, 0, 1).length());
325+
Vec3 startOffset = start.subtract(Vec3.atCenterOf(tilePos));
326+
327+
ms.pushPose();
328+
var chain = TransformStack.of(ms);
329+
chain.center();
330+
chain.translate(startOffset);
331+
chain.rotateYDegrees((float) yaw);
332+
chain.rotateXDegrees(90 - (float) pitch);
333+
chain.rotateYDegrees(45);
334+
chain.translate(0, 8 / 16f, 0);
335+
chain.uncenter();
336+
337+
int light1 = LightTexture.pack(level.getBrightness(LightLayer.BLOCK, tilePos),
338+
level.getBrightness(LightLayer.SKY, tilePos));
339+
340+
renderChainWithLod(ms, buffer, animation, light1, light1, camPos, start, end, chain);
341+
ms.popPose();
342+
}
284343

285-
if (length.y > 1e-6f) {
286-
chain.translate(0, length.x, 0);
287-
renderChain(ms, buffer, animation, length.x, length.y, light1, light2, false);
288-
}
344+
}
345+
}
289346

290-
if (length.z > 1e-6f) {
291-
chain.translate(0, length.y, 0);
292-
renderChain(ms, buffer, animation, 0, length.z, light1, light2, true);
293-
}
294-
} else {
295-
renderChain(ms, buffer, animation, 0, stats.chainLength(), light1, light2, false);
296-
}
347+
public static void renderChainWithLod(PoseStack ms, MultiBufferSource buffer, float animation, int light1,
348+
int light2, Vec3 camPos, Vec3 chainStart, Vec3 chainEnd, TransformStack chain) {
349+
Vector3f length = calculateLODCut(chainStart, chainEnd, camPos);
350+
if (length.x > 1e-6f) {
351+
renderChain(ms, buffer, animation, 0, length.x, light1, light2, true);
352+
}
353+
354+
if (length.y > 1e-6f) {
355+
chain.translate(0, length.x, 0);
356+
renderChain(ms, buffer, animation, length.x, length.y, light1, light2, false);
357+
}
297358

298-
ms.popPose();
359+
if (length.z > 1e-6f) {
360+
chain.translate(0, length.y, 0);
361+
renderChain(ms, buffer, animation, 0, length.z, light1, light2, true);
299362
}
300363
}
301364

302365
public static void renderChain(PoseStack ms, MultiBufferSource buffer, float animation, float start, float length, int light1,
303-
int light2, boolean far) {
366+
int light2, boolean far) {
304367
float radius = far ? 1f / 16f : 1.5f / 16f;
305368
float maxV = far ? 0 : animation - start;
306369
float minV = far ? 1 / 16f : maxV - length;
@@ -317,8 +380,8 @@ public static void renderChain(PoseStack ms, MultiBufferSource buffer, float ani
317380
}
318381

319382
private static void renderPart(PoseStack pPoseStack, VertexConsumer pConsumer, float pMaxY, float pX0, float pZ0,
320-
float pX1, float pZ1, float pX2, float pZ2, float pX3, float pZ3, float pMinU, float pMaxU, float pMinV,
321-
float pMaxV, int light1, int light2, boolean far) {
383+
float pX1, float pZ1, float pX2, float pZ2, float pX3, float pZ3, float pMinU, float pMaxU, float pMinV,
384+
float pMaxV, int light1, int light2, boolean far) {
322385
PoseStack.Pose posestack$pose = pPoseStack.last();
323386
Matrix4f matrix4f = posestack$pose.pose();
324387

@@ -334,16 +397,16 @@ private static void renderPart(PoseStack pPoseStack, VertexConsumer pConsumer, f
334397
}
335398

336399
private static void renderQuad(Matrix4f pPose, PoseStack.Pose pNormal, VertexConsumer pConsumer, float pMinY, float pMaxY,
337-
float pMinX, float pMinZ, float pMaxX, float pMaxZ, float pMinU, float pMaxU, float pMinV, float pMaxV,
338-
int light1, int light2) {
400+
float pMinX, float pMinZ, float pMaxX, float pMaxZ, float pMinU, float pMaxU, float pMinV, float pMaxV,
401+
int light1, int light2) {
339402
addVertex(pPose, pNormal, pConsumer, pMaxY, pMinX, pMinZ, pMaxU, pMinV, light2);
340403
addVertex(pPose, pNormal, pConsumer, pMinY, pMinX, pMinZ, pMaxU, pMaxV, light1);
341404
addVertex(pPose, pNormal, pConsumer, pMinY, pMaxX, pMaxZ, pMinU, pMaxV, light1);
342405
addVertex(pPose, pNormal, pConsumer, pMaxY, pMaxX, pMaxZ, pMinU, pMinV, light2);
343406
}
344407

345408
private static void addVertex(Matrix4f pPose, PoseStack.Pose pNormal, VertexConsumer pConsumer, float pY, float pX,
346-
float pZ, float pU, float pV, int light) {
409+
float pZ, float pU, float pV, int light) {
347410
pConsumer.addVertex(pPose, pX, pY, pZ)
348411
.setColor(1.0f, 1.0f, 1.0f, 1.0f)
349412
.setUv(pU, pV)

0 commit comments

Comments
 (0)