33import java .util .List ;
44import 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+
613import org .joml .FrustumIntersection ;
714import 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