|
1 | 1 | package io.github.opencubicchunks.cubicchunks.mixin.core.client.renderer.chunk; |
2 | 2 |
|
3 | | -import javax.annotation.Nullable; |
4 | | - |
5 | | -import io.github.opencubicchunks.cc_core.api.CubePos; |
6 | 3 | import io.github.opencubicchunks.cc_core.utils.Coords; |
7 | | -import io.github.opencubicchunks.cubicchunks.client.renderer.cube.CubicRenderRegionCache; |
8 | | -import io.github.opencubicchunks.cubicchunks.client.renderer.cube.RenderCube; |
9 | | -import io.github.opencubicchunks.cubicchunks.client.renderer.cube.RenderCubeRegion; |
10 | | -import io.github.opencubicchunks.cubicchunks.client.renderer.cube.RenderRegionCacheCubeInfo; |
| 4 | +import io.github.opencubicchunks.cubicchunks.CanBeCubic; |
| 5 | +import io.github.opencubicchunks.cubicchunks.client.renderer.chunk.CCSectionCopy; |
11 | 6 | import io.github.opencubicchunks.cubicchunks.world.level.CubicLevel; |
12 | | -import io.github.opencubicchunks.cubicchunks.world.level.cube.LevelCube; |
13 | | -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; |
14 | | -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; |
15 | | -import net.minecraft.client.renderer.chunk.RenderChunk; |
16 | | -import net.minecraft.client.renderer.chunk.RenderChunkRegion; |
17 | 7 | import net.minecraft.client.renderer.chunk.RenderRegionCache; |
| 8 | +import net.minecraft.client.renderer.chunk.RenderSectionRegion; |
| 9 | +import net.minecraft.client.renderer.chunk.SectionCopy; |
18 | 10 | import net.minecraft.client.renderer.chunk.SectionRenderDispatcher; |
19 | 11 | import net.minecraft.core.SectionPos; |
20 | 12 | import net.minecraft.world.level.Level; |
21 | | -import net.minecraft.world.level.chunk.LevelChunk; |
22 | 13 | import org.spongepowered.asm.mixin.Mixin; |
23 | | -import org.spongepowered.asm.mixin.Shadow; |
| 14 | +import org.spongepowered.asm.mixin.injection.At; |
| 15 | +import org.spongepowered.asm.mixin.injection.Inject; |
| 16 | +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; |
24 | 17 |
|
| 18 | +// TODO rewrite javadoc for 1.21.6 |
25 | 19 | /** |
26 | | - * The vanilla {@link RenderRegionCache} caches {@link LevelChunk}s and {@link RenderChunk}s while rebuilding |
| 20 | + * The vanilla {@link RenderRegionCache} caches {@link SectionCopy}s while rebuilding |
27 | 21 | * {@link SectionRenderDispatcher.RenderSection}s |
28 | | - * and has a method for creating a {@link RenderChunkRegion} for a given {@link SectionPos}. |
| 22 | + * and has a method for creating a {@link RenderSectionRegion} for a given {@link SectionPos}. |
29 | 23 | * <p/> |
30 | | - * We modify it by additionally caching {@link LevelCube}s and {@link RenderCube}s, and adding an equivalent method to create a |
31 | | - * {@link RenderCubeRegion} for a given {@link SectionPos}. |
| 24 | + * We simply modify it to get section data from cubes instead of chunks in cubic levels. |
32 | 25 | */ |
33 | 26 | @Mixin(RenderRegionCache.class) |
34 | | -public abstract class MixinRenderRegionCache implements CubicRenderRegionCache { |
35 | | - @Shadow private final Long2ObjectMap<RenderRegionCacheCubeInfo> chunkInfoCache = new Long2ObjectOpenHashMap<>(); |
36 | | - |
37 | | - // TODO can we possibly do this with DASM + mixin? probably not? |
38 | | - @Override public @Nullable RenderCubeRegion cc_createRegion(Level level, SectionPos sectionPos, boolean nullForEmpty) { |
39 | | - int centerCubeX = Coords.sectionToCube(sectionPos.getX()); |
40 | | - int centerCubeY = Coords.sectionToCube(sectionPos.getY()); |
41 | | - int centerCubeZ = Coords.sectionToCube(sectionPos.getZ()); |
42 | | - var centerCubeInfo = this.cc_getChunkInfo(level, centerCubeX, centerCubeY, centerCubeZ); |
43 | | -// if (nullForEmpty && centerCubeInfo.cube().isSectionEmpty(sectionPos.y())) { // TODO need a proper isSectionEmpty on CubeAccess |
44 | | -// return null; |
45 | | -// } |
46 | | - int cubeStartX = centerCubeX - 1; |
47 | | - int cubeStartY = centerCubeY - 1; |
48 | | - int cubeStartZ = centerCubeZ - 1; |
49 | | - int cubeEndX = centerCubeX + 1; |
50 | | - int cubeEndY = centerCubeY + 1; |
51 | | - int cubeEndZ = centerCubeZ + 1; |
52 | | - RenderCube[] renderCubes = new RenderCube[RenderCubeRegion.CUBE_COUNT]; |
53 | | - |
54 | | - for (int cubeX = cubeStartX; cubeX <= cubeEndX; ++cubeX) { |
55 | | - for (int cubeY = cubeStartY; cubeY <= cubeEndY; ++cubeY) { |
56 | | - for (int cubeZ = cubeStartZ; cubeZ <= cubeEndZ; ++cubeZ) { |
57 | | - int cubeIndex = RenderCubeRegion.index(cubeStartX, cubeStartY, cubeStartZ, cubeX, cubeY, cubeZ); |
58 | | - var cubeInfo = cubeX == centerCubeX && cubeY == centerCubeY && cubeZ == centerCubeZ ? centerCubeInfo |
59 | | - : this.cc_getChunkInfo(level, cubeX, cubeY, cubeZ); |
60 | | - renderCubes[cubeIndex] = cubeInfo.renderCube(); |
61 | | - } |
62 | | - } |
| 27 | +public abstract class MixinRenderRegionCache { |
| 28 | + // Note the order of the individual sectionPos axes is weird (x,z,y) due to it being based on usage order within the vanilla lambda |
| 29 | + // To avoid brittleness we ignore these parameters and use the captured sectionPos long instead. |
| 30 | + @Inject(method = "lambda$getSectionDataCopy$0", at = @At("HEAD"), cancellable = true) |
| 31 | + private static void cc_onGetSectionDataCopy( |
| 32 | + Level level, int unusedSectionX, int unusedSectionZ, int unusedSectionY, long sectionPosLong, CallbackInfoReturnable<SectionCopy> cir |
| 33 | + ) { |
| 34 | + if (((CanBeCubic) level).cc_isCubic()) { |
| 35 | + var sectionPos = SectionPos.of(sectionPosLong); |
| 36 | + var cube = ((CubicLevel) level).cc_getCube(Coords.sectionToCube(sectionPos.getX()), Coords.sectionToCube(sectionPos.getY()), |
| 37 | + Coords.sectionToCube(sectionPos.getZ())); |
| 38 | + cir.setReturnValue(CCSectionCopy.cc_create(cube, Coords.sectionToIndex(sectionPos.getX(), sectionPos.getY(), sectionPos.getZ()))); |
63 | 39 | } |
64 | | - |
65 | | - var modelDataManager = level.getModelDataManager().snapshotSectionRegion(cubeStartX, cubeStartY, cubeStartZ, cubeEndX, cubeEndY, cubeEndZ); |
66 | | - return new RenderCubeRegion(level, cubeStartX, cubeStartY, cubeStartZ, renderCubes, modelDataManager); |
67 | | - } |
68 | | - |
69 | | - private RenderRegionCacheCubeInfo cc_getChunkInfo(Level level, int cubeX, int cubeY, int cubeZ) { |
70 | | - return this.chunkInfoCache.computeIfAbsent(CubePos.asLong(cubeX, cubeY, cubeZ), cubePosLong -> new RenderRegionCacheCubeInfo( |
71 | | - ((CubicLevel) level).cc_getCube(CubePos.extractX(cubePosLong), CubePos.extractY(cubePosLong), CubePos.extractZ(cubePosLong)))); |
72 | 40 | } |
73 | 41 | } |
0 commit comments