11package io .github .opencubicchunks .cubicchunks .mixin .core .common .client .renderer ;
22
3+ import javax .annotation .Nullable ;
4+
5+ import com .llamalad7 .mixinextras .injector .wrapoperation .Operation ;
6+ import com .llamalad7 .mixinextras .injector .wrapoperation .WrapOperation ;
37import io .github .notstirred .dasm .api .annotations .Dasm ;
48import io .github .notstirred .dasm .api .annotations .redirect .redirects .AddMethodToSets ;
59import io .github .notstirred .dasm .api .annotations .redirect .redirects .AddTransformToSets ;
610import io .github .notstirred .dasm .api .annotations .selector .MethodSig ;
711import io .github .notstirred .dasm .api .annotations .selector .Ref ;
812import io .github .notstirred .dasm .api .annotations .transform .TransformFromMethod ;
913import io .github .opencubicchunks .cc_core .api .CubePos ;
10- import io .github .opencubicchunks .cc_core .world .level .CloPos ;
14+ import io .github .opencubicchunks .cc_core .utils .Coords ;
15+ import io .github .opencubicchunks .cubicchunks .CanBeCubic ;
16+ import io .github .opencubicchunks .cubicchunks .mixin .access .client .ViewAreaAccess ;
1117import io .github .opencubicchunks .cubicchunks .mixin .access .common .SectionOcclusionGraph$GraphEventsAccess ;
1218import io .github .opencubicchunks .cubicchunks .mixin .dasmsets .ChunkToCubeSet ;
19+ import io .github .opencubicchunks .cubicchunks .server .level .CloTrackingView ;
1320import net .minecraft .client .renderer .SectionOcclusionGraph ;
21+ import net .minecraft .client .renderer .ViewArea ;
22+ import net .minecraft .client .renderer .chunk .SectionRenderDispatcher ;
23+ import net .minecraft .core .BlockPos ;
24+ import net .minecraft .core .Direction ;
1425import org .spongepowered .asm .mixin .Mixin ;
26+ import org .spongepowered .asm .mixin .Shadow ;
27+ import org .spongepowered .asm .mixin .injection .At ;
28+ import org .spongepowered .asm .mixin .injection .Inject ;
29+ import org .spongepowered .asm .mixin .injection .callback .CallbackInfo ;
30+ import org .spongepowered .asm .mixin .injection .callback .CallbackInfoReturnable ;
1531
1632@ Dasm (ChunkToCubeSet .class )
1733@ Mixin (SectionOcclusionGraph .class )
1834public abstract class MixinSectionOcclusionGraph {
19- // TODO onChunkLoaded
20- // TODO addNeighbors
21- // TODO initializeQueueForFullUpdate
22- // TODO runUpdates ChunkPos.asLong
23- // TODO isInViewDistance
24- // TODO maybe getRelativeFrom? unsure
35+ private boolean cc_isCubic = false ;
36+ @ Shadow @ Nullable private ViewArea viewArea ;
37+
38+ @ Shadow protected abstract boolean isInViewDistance (BlockPos pos , BlockPos origin );
39+
40+ @ Inject (method = "waitAndReset" , at = @ At ("RETURN" ))
41+ private void cc_onWaitAndReset (@ Nullable ViewArea viewArea , CallbackInfo ci ) {
42+ cc_isCubic = viewArea != null && ((CanBeCubic ) viewArea .getLevelHeightAccessor ()).cc_isCubic ();
43+ }
2544
2645 @ AddTransformToSets (ChunkToCubeSet .class ) @ TransformFromMethod (@ MethodSig ("onChunkLoaded(Lnet/minecraft/world/level/ChunkPos;)V" ))
27- public native void cc_onCubeLoaded ();
46+ public native void cc_onCubeLoaded (CubePos cubePos );
2847
2948 @ AddMethodToSets (sets = ChunkToCubeSet .class , owner = @ Ref (SectionOcclusionGraph .class ), method = @ MethodSig ("addNeighbors(Lnet/minecraft/client/renderer/SectionOcclusionGraph$GraphEvents;Lnet/minecraft/world/level/ChunkPos;)V" ))
30- private void cc_addNeighbors (SectionOcclusionGraph .GraphEvents graphEvents , CloPos cubePos ) {
49+ private void cc_addNeighbors (SectionOcclusionGraph .GraphEvents graphEvents , CubePos cubePos ) {
3150 var access = ((SectionOcclusionGraph$GraphEventsAccess ) (Object ) graphEvents );
3251 access .cc_chunksWhichReceivedNeighbors ().add (CubePos .asLong (cubePos .getX () - 1 , cubePos .getY (), cubePos .getZ ()));
3352 access .cc_chunksWhichReceivedNeighbors ().add (CubePos .asLong (cubePos .getX (), cubePos .getY () - 1 , cubePos .getZ ()));
@@ -36,4 +55,43 @@ private void cc_addNeighbors(SectionOcclusionGraph.GraphEvents graphEvents, CloP
3655 access .cc_chunksWhichReceivedNeighbors ().add (CubePos .asLong (cubePos .getX (), cubePos .getY () + 1 , cubePos .getZ ()));
3756 access .cc_chunksWhichReceivedNeighbors ().add (CubePos .asLong (cubePos .getX (), cubePos .getY (), cubePos .getZ () + 1 ));
3857 }
58+
59+ @ WrapOperation (method = "initializeQueueForFullUpdate" , at = @ At (value = "INVOKE" , target = "Lnet/minecraft/client/renderer/ViewArea;getRenderSectionAt(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/client/renderer/chunk/SectionRenderDispatcher$RenderSection;" ))
60+ private @ Nullable SectionRenderDispatcher .RenderSection cc_onInitializeQueueForFullUpdate_getRenderSectionAt (ViewArea instance , BlockPos pos , Operation <SectionRenderDispatcher .RenderSection > original ) {
61+ var result = original .call (instance , pos );
62+ if (result == null && cc_isCubic ) {
63+ throw new IllegalStateException ("getRenderSectionAt should never return null in a cubic world" );
64+ }
65+ return result ;
66+ }
67+
68+ @ WrapOperation (method = "runUpdates" , at = @ At (value = "INVOKE" , target = "Lnet/minecraft/world/level/ChunkPos;asLong(Lnet/minecraft/core/BlockPos;)J" ))
69+ private long cc_onRunUpdates_chunkPosAsLong (BlockPos pos , Operation <Long > original ) {
70+ if (!cc_isCubic ) return original .call (pos );
71+ return CubePos .asLong (pos );
72+ }
73+
74+ @ Inject (method = "isInViewDistance" , at = @ At ("HEAD" ), cancellable = true )
75+ private void cc_onIsInViewDistance (BlockPos pos , BlockPos origin , CallbackInfoReturnable <Boolean > cir ) {
76+ if (!cc_isCubic ) return ;
77+ int posCubeX = Coords .blockToCube (pos .getX ());
78+ int posCubeY = Coords .blockToCube (pos .getY ());
79+ int posCubeZ = Coords .blockToCube (pos .getZ ());
80+ int originCubeX = Coords .blockToCube (origin .getX ());
81+ int originCubeY = Coords .blockToCube (origin .getY ());
82+ int originCubeZ = Coords .blockToCube (origin .getZ ());
83+ cir .setReturnValue (CloTrackingView .cc_isInViewDistance (posCubeX , posCubeY , posCubeZ , Coords .sectionToCubeRenderDistance (this .viewArea .getViewDistance ()), originCubeX , originCubeY , originCubeZ ));
84+ }
85+
86+ @ Inject (method = "getRelativeFrom" , at = @ At ("HEAD" ), cancellable = true )
87+ private void cc_onGetRelativeFrom (BlockPos pos , SectionRenderDispatcher .RenderSection section , Direction direction , CallbackInfoReturnable <SectionRenderDispatcher .RenderSection > cir ) {
88+ if (!cc_isCubic ) return ;
89+ // Same as vanilla logic but we don't manually check Y coordinates since that's handled by isInViewDistance now
90+ BlockPos relativeOrigin = section .getRelativeOrigin (direction );
91+ if (!this .isInViewDistance (pos , relativeOrigin )) {
92+ cir .setReturnValue (null );
93+ } else {
94+ cir .setReturnValue (((ViewAreaAccess ) this .viewArea ).cc_invokeGetRenderSectionAt (relativeOrigin ));
95+ }
96+ }
3997}
0 commit comments