From 346a305f1d4eb1beae4f50ed8f4ff2eea12c5979 Mon Sep 17 00:00:00 2001 From: ah-OOG-ah <75745146+ah-OOG-ah@users.noreply.github.com> Date: Wed, 28 Feb 2024 23:39:51 -0500 Subject: [PATCH] Refactor Quad, BlockPos, and QuadProvider API Also optimize static models --- build.gradle.kts | 4 + .../gtnewhorizons/angelica/api/BlockPos.java | 49 +++ .../angelica/api/MutableBlockPos.java | 8 + .../angelica/api/QuadProvider.java | 22 +- .../gtnewhorizons/angelica/api/QuadView.java | 22 ++ .../client/renderer/CapturingTessellator.java | 21 +- .../angelica/common/BlockTest.java | 10 +- .../angelica/compat/mojang/BlockPos.java | 102 ------ .../angelica/compat/mojang/BlockPosImpl.java | 70 ++++ .../angelica/compat/mojang/Camera.java | 2 +- .../mojang/ChunkOcclusionDataBuilder.java | 4 +- .../angelica/compat/mojang/ChunkPos.java | 2 +- .../compat/mojang/ChunkSectionPos.java | 2 +- .../angelica/compat/mojang/VertexFormat.java | 4 +- .../angelica/compat/nd/IWriteQuads.java | 4 +- .../angelica/compat/nd/Quad.java | 218 ------------ .../compat/nd/writers/ItemVBOQuadWriter.java | 8 +- .../PositionColorTextureQuadWriter.java | 8 +- .../compat/nd/writers/PositionQuadWriter.java | 8 +- .../PositionTextureColorQuadWriter.java | 8 +- .../nd/writers/PositionTextureQuadWriter.java | 8 +- .../angelica/glsm/TessellatorManager.java | 9 +- .../early/angelica/models/MixinBlockAir.java | 15 +- .../angelica/models/MixinBlockLeaves.java | 14 +- .../angelica/models/MixinBlockStone.java | 10 +- .../angelica/models/MixinBlockWorkbench.java | 10 +- .../angelica/models/CubeModel.java | 19 +- .../angelica/models/GeometryHelper.java | 2 +- .../angelica/models/NdQuadBuilder.java | 55 ++- .../angelica/models/json/JsonModel.java | 31 +- .../client/model/light/EntityLighter.java | 4 +- .../client/model/light/LightPipeline.java | 4 +- .../model/light/cache/HashLightDataCache.java | 2 +- .../model/light/data/LightDataAccess.java | 8 +- .../model/light/flat/FlatLightPipeline.java | 6 +- .../client/model/light/smooth/AoFaceData.java | 4 +- .../light/smooth/SmoothLightPipeline.java | 20 +- .../mods/sodium/client/model/quad/Quad.java | 335 ++++++++++++++++++ .../render/chunk/ChunkRenderContainer.java | 6 +- .../chunk/cull/graph/ChunkGraphCuller.java | 4 +- .../chunk/cull/graph/ChunkGraphNode.java | 4 +- .../chunk/tasks/ChunkRenderRebuildTask.java | 14 +- .../ChunkRenderTranslucencySortTask.java | 6 +- .../render/entity/EntityLightSampler.java | 6 +- .../render/occlusion/BlockOcclusionCache.java | 8 +- .../client/render/pipeline/BlockRenderer.java | 27 +- .../client/render/pipeline/FluidRenderer.java | 12 +- .../world/cloned/ClonedChunkSection.java | 1 - .../mods/sodium/common/util/WorldUtil.java | 6 +- 49 files changed, 701 insertions(+), 525 deletions(-) create mode 100644 src/main/java/com/gtnewhorizons/angelica/api/BlockPos.java create mode 100644 src/main/java/com/gtnewhorizons/angelica/api/MutableBlockPos.java create mode 100644 src/main/java/com/gtnewhorizons/angelica/api/QuadView.java delete mode 100644 src/main/java/com/gtnewhorizons/angelica/compat/mojang/BlockPos.java create mode 100644 src/main/java/com/gtnewhorizons/angelica/compat/mojang/BlockPosImpl.java delete mode 100644 src/main/java/com/gtnewhorizons/angelica/compat/nd/Quad.java create mode 100644 src/main/java/me/jellysquid/mods/sodium/client/model/quad/Quad.java diff --git a/build.gradle.kts b/build.gradle.kts index bfac615a9..383a5782b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,6 +2,10 @@ plugins { id("com.gtnewhorizons.gtnhconvention") } +minecraft { + extraRunJvmArguments.add("-Dangelica.enableTestBlocks=true") +} + tasks.test { useJUnitPlatform() testLogging { diff --git a/src/main/java/com/gtnewhorizons/angelica/api/BlockPos.java b/src/main/java/com/gtnewhorizons/angelica/api/BlockPos.java new file mode 100644 index 000000000..519b1e669 --- /dev/null +++ b/src/main/java/com/gtnewhorizons/angelica/api/BlockPos.java @@ -0,0 +1,49 @@ +package com.gtnewhorizons.angelica.api; + +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; +import net.minecraft.util.MathHelper; +import net.minecraftforge.common.util.ForgeDirection; + +import java.math.RoundingMode; + +import static com.google.common.math.IntMath.log2; + +public interface BlockPos { + + int SIZE_BITS_X = 1 + log2(MathHelper.roundUpToPowerOfTwo(30000000), RoundingMode.UNNECESSARY); + int SIZE_BITS_Z = SIZE_BITS_X; + int SIZE_BITS_Y = 64 - SIZE_BITS_X - SIZE_BITS_Z; + long BITS_X = (1L << SIZE_BITS_X) - 1L; + long BITS_Y = (1L << SIZE_BITS_Y) - 1L; + long BITS_Z = (1L << SIZE_BITS_Z) - 1L; + int BIT_SHIFT_Z = SIZE_BITS_Y; + int BIT_SHIFT_X = SIZE_BITS_Y + SIZE_BITS_Z; + + int getX(); + int getY(); + int getZ(); + BlockPosImpl offset(ForgeDirection d); + BlockPosImpl down(); + BlockPosImpl up(); + long asLong(); + + static long asLong(int x, int y, int z) { + long l = 0L; + l |= ((long) x & BITS_X) << BIT_SHIFT_X; + l |= ((long) y & BITS_Y) << 0; + l |= ((long) z & BITS_Z) << BIT_SHIFT_Z; + return l; + } + + public static int unpackLongX(long packedPos) { + return (int)(packedPos << 64 - BIT_SHIFT_X - SIZE_BITS_X >> 64 - SIZE_BITS_X); + } + + public static int unpackLongY(long packedPos) { + return (int)(packedPos << 64 - SIZE_BITS_Y >> 64 - SIZE_BITS_Y); + } + + public static int unpackLongZ(long packedPos) { + return (int)(packedPos << 64 - BIT_SHIFT_Z - SIZE_BITS_Z >> 64 - SIZE_BITS_Z); + } +} diff --git a/src/main/java/com/gtnewhorizons/angelica/api/MutableBlockPos.java b/src/main/java/com/gtnewhorizons/angelica/api/MutableBlockPos.java new file mode 100644 index 000000000..4f0be4291 --- /dev/null +++ b/src/main/java/com/gtnewhorizons/angelica/api/MutableBlockPos.java @@ -0,0 +1,8 @@ +package com.gtnewhorizons.angelica.api; + +public interface MutableBlockPos extends BlockPos { + + MutableBlockPos set(int x, int y, int z); + + MutableBlockPos set(long packedPos); +} diff --git a/src/main/java/com/gtnewhorizons/angelica/api/QuadProvider.java b/src/main/java/com/gtnewhorizons/angelica/api/QuadProvider.java index 16af94ef3..503e4c6df 100644 --- a/src/main/java/com/gtnewhorizons/angelica/api/QuadProvider.java +++ b/src/main/java/com/gtnewhorizons/angelica/api/QuadProvider.java @@ -1,14 +1,12 @@ package com.gtnewhorizons.angelica.api; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; -import com.gtnewhorizons.angelica.compat.nd.Quad; -import com.gtnewhorizons.angelica.utils.ObjectPooler; import net.minecraft.block.Block; import net.minecraft.world.IBlockAccess; import net.minecraftforge.common.util.ForgeDirection; import java.util.List; import java.util.Random; +import java.util.function.Supplier; public interface QuadProvider { @@ -23,9 +21,23 @@ public interface QuadProvider { */ default int getColor(IBlockAccess world, BlockPos pos, Block block, int meta, Random random) { - final int cin = block.colorMultiplier(world, pos.x, pos.y, pos.z); + final int cin = block.colorMultiplier(world, pos.getX(), pos.getY(), pos.getZ()); return (0xFF << 24) | ((cin & B_MASK) << 16) | (cin & G_MASK) | ((cin & R_MASK) >>> 16); } - List getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, ObjectPooler quadPool); + /** + * If you need to allocate new quads, set this to true. If true, the quads returned by {@link #getQuads} are + * recycled, and you should not keep a reference to them. Example: stone can return a static list every time, but a + * modded block which adds or removes quads based on location would need dynamic quads. + */ + default boolean isDynamic() { + return false; + } + + /** + * Provide quads to render. If you need new quads, they should be obtained with the passed supplier and + * {@link #isDynamic} overridden to return true. If so, all quads in the list are recycled and references to them + * should not be kept. + */ + List getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier quadPool); } diff --git a/src/main/java/com/gtnewhorizons/angelica/api/QuadView.java b/src/main/java/com/gtnewhorizons/angelica/api/QuadView.java new file mode 100644 index 000000000..71b808230 --- /dev/null +++ b/src/main/java/com/gtnewhorizons/angelica/api/QuadView.java @@ -0,0 +1,22 @@ +package com.gtnewhorizons.angelica.api; + +import me.jellysquid.mods.sodium.client.model.quad.ModelQuadViewMutable; +import me.jellysquid.mods.sodium.client.render.pipeline.BlockRenderer; +import net.minecraftforge.common.util.ForgeDirection; + +import javax.annotation.Nullable; + +public interface QuadView extends ModelQuadViewMutable { + + boolean isShade(); + boolean isDeleted(); + ForgeDirection getFace(); + void copyFrom(QuadView src); + void setRaw(int[] data, boolean shade, @Nullable ForgeDirection face, int colorIndex, int flags); + int[] getRawVertexes(); + + /** + * Present for compatibility with the Tesselator, not recommended for general use. + */ + void setState(int[] rawBuffer, int offset, BlockRenderer.Flags flags, int drawMode, float offsetX, float offsetY, float offsetZ); +} diff --git a/src/main/java/com/gtnewhorizons/angelica/client/renderer/CapturingTessellator.java b/src/main/java/com/gtnewhorizons/angelica/client/renderer/CapturingTessellator.java index a0316b29a..ca6700ecf 100644 --- a/src/main/java/com/gtnewhorizons/angelica/client/renderer/CapturingTessellator.java +++ b/src/main/java/com/gtnewhorizons/angelica/client/renderer/CapturingTessellator.java @@ -1,8 +1,9 @@ package com.gtnewhorizons.angelica.client.renderer; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; +import com.gtnewhorizons.angelica.api.QuadView; +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; import com.gtnewhorizons.angelica.compat.mojang.VertexFormat; -import com.gtnewhorizons.angelica.compat.nd.Quad; +import me.jellysquid.mods.sodium.client.model.quad.Quad; import com.gtnewhorizons.angelica.glsm.stacks.Vector3dStack; import com.gtnewhorizons.angelica.mixins.interfaces.ITessellatorInstance; import com.gtnewhorizons.angelica.utils.ObjectPooler; @@ -39,15 +40,15 @@ public class CapturingTessellator extends Tessellator implements ITessellatorIns private static final MethodHandle sRawBufferSize; private static final MethodHandle gRawBufferSize; private final BlockRenderer.Flags FLAGS = new BlockRenderer.Flags(true, true, true, true); - private final ObjectPooler quadBuf = new ObjectPooler<>(Quad::new); - private final List collectedQuads = new ObjectArrayList<>(); + private final ObjectPooler quadBuf = new ObjectPooler<>(Quad::new); + private final List collectedQuads = new ObjectArrayList<>(); // Any offset we need to the Tesselator's offset! - private final BlockPos offset = new BlockPos(); + private final BlockPosImpl offset = new BlockPosImpl(); private final Vector3dStack storedTranslation = new Vector3dStack(); - public void setOffset(BlockPos pos) { + public void setOffset(BlockPosImpl pos) { this.offset.set(pos); } public void resetOffset() { @@ -93,10 +94,10 @@ public int draw() { for(int quadI = 0; quadI < this.vertexCount / verticesPerPrimitive; quadI++) { - final Quad quad = quadBuf.getInstance(); + final QuadView quad = quadBuf.getInstance(); quad.setState(this.rawBuffer, quadI * (verticesPerPrimitive * 8), FLAGS, this.drawMode, -offset.x, -offset.y, -offset.z); - if(quad.deleted) { + if(quad.isDeleted()) { quadBuf.releaseInstance(quad); } else { this.collectedQuads.add(quad); @@ -115,7 +116,7 @@ public void discard() { } - public List getQuads() { + public List getQuads() { return collectedQuads; } @@ -127,7 +128,7 @@ public void clearQuads() { this.collectedQuads.clear(); } - public static ByteBuffer quadsToBuffer(List quads, VertexFormat format) { + public static ByteBuffer quadsToBuffer(List quads, VertexFormat format) { if(!format.canWriteQuads()) { throw new IllegalStateException("Vertex format has no quad writer: " + format); } diff --git a/src/main/java/com/gtnewhorizons/angelica/common/BlockTest.java b/src/main/java/com/gtnewhorizons/angelica/common/BlockTest.java index bea74d72e..ff629a9ea 100644 --- a/src/main/java/com/gtnewhorizons/angelica/common/BlockTest.java +++ b/src/main/java/com/gtnewhorizons/angelica/common/BlockTest.java @@ -1,12 +1,11 @@ package com.gtnewhorizons.angelica.common; +import com.gtnewhorizons.angelica.api.BlockPos; import com.gtnewhorizons.angelica.api.QuadProvider; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; -import com.gtnewhorizons.angelica.compat.nd.Quad; +import com.gtnewhorizons.angelica.api.QuadView; import com.gtnewhorizons.angelica.models.json.JsonModel; import com.gtnewhorizons.angelica.models.json.Loader; import com.gtnewhorizons.angelica.models.json.Variant; -import com.gtnewhorizons.angelica.utils.ObjectPooler; import it.unimi.dsi.fastutil.objects.ObjectImmutableList; import net.minecraft.block.Block; import net.minecraft.block.material.Material; @@ -19,6 +18,7 @@ import java.util.List; import java.util.Random; +import java.util.function.Supplier; public class BlockTest extends Block implements QuadProvider { @@ -48,7 +48,7 @@ public class BlockTest extends Block implements QuadProvider { false ), }; - private static final List EMPTY = ObjectImmutableList.of(); + private static final List EMPTY = ObjectImmutableList.of(); private static final JsonModel[] model = new JsonModel[4]; public BlockTest() { @@ -78,7 +78,7 @@ public void registerBlockIcons(IIconRegister reg) { } @Override - public List getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, ObjectPooler quadPool) { + public List getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier quadPool) { if (meta < 2 || meta > 5) meta = 2; diff --git a/src/main/java/com/gtnewhorizons/angelica/compat/mojang/BlockPos.java b/src/main/java/com/gtnewhorizons/angelica/compat/mojang/BlockPos.java deleted file mode 100644 index a5e503275..000000000 --- a/src/main/java/com/gtnewhorizons/angelica/compat/mojang/BlockPos.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.gtnewhorizons.angelica.compat.mojang; - -import net.minecraft.util.MathHelper; -import net.minecraft.world.ChunkPosition; -import net.minecraftforge.common.util.ForgeDirection; -import org.joml.Vector3i; - -import java.math.RoundingMode; - -import static com.google.common.math.IntMath.log2; - -// Should we keep this? -public class BlockPos extends Vector3i { - - private static final int SIZE_BITS_X = 1 + log2(MathHelper.roundUpToPowerOfTwo(30000000), RoundingMode.UNNECESSARY); - private static final int SIZE_BITS_Z = SIZE_BITS_X; - private static final int SIZE_BITS_Y = 64 - SIZE_BITS_X - SIZE_BITS_Z; - private static final long BITS_X = (1L << SIZE_BITS_X) - 1L; - private static final long BITS_Y = (1L << SIZE_BITS_Y) - 1L; - private static final long BITS_Z = (1L << SIZE_BITS_Z) - 1L; - private static final int BIT_SHIFT_Z = SIZE_BITS_Y; - private static final int BIT_SHIFT_X = SIZE_BITS_Y + SIZE_BITS_Z; - - public BlockPos() { - super(); - } - public BlockPos(int x, int y, int z) { - super(x, y, z); - } - - public BlockPos(ChunkPosition chunkPosition) { - super(chunkPosition.chunkPosX, chunkPosition.chunkPosY, chunkPosition.chunkPosZ); - } - - public int getX() { - return this.x; - } - public int getY() { - return this.y; - } - public int getZ() { - return this.z; - } - - public BlockPos set(int x, int y, int z) { - super.set(x, y, z); - return this; - } - - /** - * This method does NOT mutate the BlockPos - */ - public BlockPos offset(ForgeDirection d) { - return new BlockPos(this.x + d.offsetX, this.y + d.offsetY, this.z + d.offsetZ); - } - - /** - * This method does NOT mutate the BlockPos - */ - public BlockPos down() { - return offset(ForgeDirection.DOWN); - } - - /** - * This method does NOT mutate the BlockPos - */ - public BlockPos up() { - return offset(ForgeDirection.UP); - } - - public long asLong() { - return asLong(this.x, this.y, this.z); - } - - public static long asLong(int x, int y, int z) { - long l = 0L; - l |= ((long)x & BITS_X) << BIT_SHIFT_X; - l |= ((long)y & BITS_Y) << 0; - l |= ((long)z & BITS_Z) << BIT_SHIFT_Z; - return l; - } - - public BlockPos set(long packedPos) { - return set(unpackLongX(packedPos), unpackLongY(packedPos), unpackLongZ(packedPos)); - } - - public static int unpackLongX(long packedPos) { - return (int)(packedPos << 64 - BIT_SHIFT_X - SIZE_BITS_X >> 64 - SIZE_BITS_X); - } - - public static int unpackLongY(long packedPos) { - return (int)(packedPos << 64 - SIZE_BITS_Y >> 64 - SIZE_BITS_Y); - } - - public static int unpackLongZ(long packedPos) { - return (int)(packedPos << 64 - BIT_SHIFT_Z - SIZE_BITS_Z >> 64 - SIZE_BITS_Z); - } - - public static class Mutable extends BlockPos { - - } -} diff --git a/src/main/java/com/gtnewhorizons/angelica/compat/mojang/BlockPosImpl.java b/src/main/java/com/gtnewhorizons/angelica/compat/mojang/BlockPosImpl.java new file mode 100644 index 000000000..803ba32f2 --- /dev/null +++ b/src/main/java/com/gtnewhorizons/angelica/compat/mojang/BlockPosImpl.java @@ -0,0 +1,70 @@ +package com.gtnewhorizons.angelica.compat.mojang; + +import com.gtnewhorizons.angelica.api.BlockPos; +import com.gtnewhorizons.angelica.api.MutableBlockPos; +import net.minecraft.world.ChunkPosition; +import net.minecraftforge.common.util.ForgeDirection; +import org.joml.Vector3i; + +import static com.gtnewhorizons.angelica.api.BlockPos.unpackLongX; +import static com.gtnewhorizons.angelica.api.BlockPos.unpackLongY; +import static com.gtnewhorizons.angelica.api.BlockPos.unpackLongZ; + +// Should we keep this? +public class BlockPosImpl extends Vector3i implements MutableBlockPos { + + public BlockPosImpl() { + super(); + } + public BlockPosImpl(int x, int y, int z) { + super(x, y, z); + } + + public BlockPosImpl(ChunkPosition chunkPosition) { + super(chunkPosition.chunkPosX, chunkPosition.chunkPosY, chunkPosition.chunkPosZ); + } + + @Override + public int getX() { + return this.x; + } + @Override + public int getY() { + return this.y; + } + @Override + public int getZ() { + return this.z; + } + + @Override + public BlockPosImpl offset(ForgeDirection d) { + return new BlockPosImpl(this.x + d.offsetX, this.y + d.offsetY, this.z + d.offsetZ); + } + + @Override + public BlockPosImpl down() { + return offset(ForgeDirection.DOWN); + } + + @Override + public BlockPosImpl up() { + return offset(ForgeDirection.UP); + } + + @Override + public long asLong() { + return BlockPos.asLong(this.x, this.y, this.z); + } + + @Override + public BlockPosImpl set(int x, int y, int z) { + super.set(x, y, z); + return this; + } + + @Override + public BlockPosImpl set(long packedPos) { + return set(unpackLongX(packedPos), unpackLongY(packedPos), unpackLongZ(packedPos)); + } +} diff --git a/src/main/java/com/gtnewhorizons/angelica/compat/mojang/Camera.java b/src/main/java/com/gtnewhorizons/angelica/compat/mojang/Camera.java index b5ab03fa1..6d5004c4a 100644 --- a/src/main/java/com/gtnewhorizons/angelica/compat/mojang/Camera.java +++ b/src/main/java/com/gtnewhorizons/angelica/compat/mojang/Camera.java @@ -13,7 +13,7 @@ @Getter public class Camera { final Vector3d pos = new Vector3d(); - final BlockPos.Mutable blockPos = new BlockPos.Mutable(); + final BlockPosImpl blockPos = new BlockPosImpl(); float pitch; float yaw; EntityLivingBase entity; diff --git a/src/main/java/com/gtnewhorizons/angelica/compat/mojang/ChunkOcclusionDataBuilder.java b/src/main/java/com/gtnewhorizons/angelica/compat/mojang/ChunkOcclusionDataBuilder.java index e4e1eb7a4..ac21baa21 100644 --- a/src/main/java/com/gtnewhorizons/angelica/compat/mojang/ChunkOcclusionDataBuilder.java +++ b/src/main/java/com/gtnewhorizons/angelica/compat/mojang/ChunkOcclusionDataBuilder.java @@ -36,12 +36,12 @@ public class ChunkOcclusionDataBuilder { } private int openCount = 4096; - public void markClosed(BlockPos pos) { + public void markClosed(BlockPosImpl pos) { this.closed.set(pack(pos), true); --this.openCount; } - private static int pack(BlockPos pos) { + private static int pack(BlockPosImpl pos) { return pack(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15); } diff --git a/src/main/java/com/gtnewhorizons/angelica/compat/mojang/ChunkPos.java b/src/main/java/com/gtnewhorizons/angelica/compat/mojang/ChunkPos.java index 95813a5f8..9558e261f 100644 --- a/src/main/java/com/gtnewhorizons/angelica/compat/mojang/ChunkPos.java +++ b/src/main/java/com/gtnewhorizons/angelica/compat/mojang/ChunkPos.java @@ -12,7 +12,7 @@ public ChunkPos(int x, int z) { this.z = z; } - public ChunkPos(BlockPos pos) { + public ChunkPos(BlockPosImpl pos) { this.x = pos.getX() >> 4; this.z = pos.getZ() >> 4; } diff --git a/src/main/java/com/gtnewhorizons/angelica/compat/mojang/ChunkSectionPos.java b/src/main/java/com/gtnewhorizons/angelica/compat/mojang/ChunkSectionPos.java index fbae02513..d17742b8b 100644 --- a/src/main/java/com/gtnewhorizons/angelica/compat/mojang/ChunkSectionPos.java +++ b/src/main/java/com/gtnewhorizons/angelica/compat/mojang/ChunkSectionPos.java @@ -19,7 +19,7 @@ public static ChunkSectionPos from(int x, int y, int z) { return new ChunkSectionPos(x, y, z); } - public static ChunkSectionPos from(BlockPos pos) { + public static ChunkSectionPos from(BlockPosImpl pos) { return new ChunkSectionPos(getSectionCoord(pos.getX()), getSectionCoord(pos.getY()), getSectionCoord(pos.getZ())); } diff --git a/src/main/java/com/gtnewhorizons/angelica/compat/mojang/VertexFormat.java b/src/main/java/com/gtnewhorizons/angelica/compat/mojang/VertexFormat.java index ddbca0929..732202e74 100644 --- a/src/main/java/com/gtnewhorizons/angelica/compat/mojang/VertexFormat.java +++ b/src/main/java/com/gtnewhorizons/angelica/compat/mojang/VertexFormat.java @@ -1,8 +1,8 @@ package com.gtnewhorizons.angelica.compat.mojang; import com.google.common.collect.ImmutableList; +import com.gtnewhorizons.angelica.api.QuadView; import com.gtnewhorizons.angelica.compat.nd.IWriteQuads; -import com.gtnewhorizons.angelica.compat.nd.Quad; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import lombok.Getter; @@ -79,7 +79,7 @@ public boolean canWriteQuads() { return quadWriter != null; } - public void writeQuad(Quad quad, ByteBuffer byteBuffer) { + public void writeQuad(QuadView quad, ByteBuffer byteBuffer) { if(quadWriter == null) { throw new IllegalStateException("No quad writer set"); } diff --git a/src/main/java/com/gtnewhorizons/angelica/compat/nd/IWriteQuads.java b/src/main/java/com/gtnewhorizons/angelica/compat/nd/IWriteQuads.java index b33d71b08..2a3bde9fb 100644 --- a/src/main/java/com/gtnewhorizons/angelica/compat/nd/IWriteQuads.java +++ b/src/main/java/com/gtnewhorizons/angelica/compat/nd/IWriteQuads.java @@ -1,7 +1,9 @@ package com.gtnewhorizons.angelica.compat.nd; +import com.gtnewhorizons.angelica.api.QuadView; + import java.nio.ByteBuffer; public interface IWriteQuads { - void writeQuad(Quad quad, ByteBuffer buf); + void writeQuad(QuadView quad, ByteBuffer buf); } diff --git a/src/main/java/com/gtnewhorizons/angelica/compat/nd/Quad.java b/src/main/java/com/gtnewhorizons/angelica/compat/nd/Quad.java deleted file mode 100644 index f19d91522..000000000 --- a/src/main/java/com/gtnewhorizons/angelica/compat/nd/Quad.java +++ /dev/null @@ -1,218 +0,0 @@ -package com.gtnewhorizons.angelica.compat.nd; - -import lombok.Getter; -import me.jellysquid.mods.sodium.client.model.quad.ModelQuadView; -import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFacing; -import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFlags; -import me.jellysquid.mods.sodium.client.render.pipeline.BlockRenderer; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraftforge.common.util.ForgeDirection; -import org.joml.Vector3f; -import org.lwjgl.opengl.GL11; - -import javax.annotation.Nullable; -import java.util.Locale; - -public class Quad implements ModelQuadView { - // Adapted from Neodymium - - private final static int DEFAULT_BRIGHTNESS = 15 << 20 | 15 << 4; - private final static int DEFAULT_COLOR = 0xFFFFFFFF; - - public float[] xs = new float[4]; - public float[] ys = new float[4]; - public float[] zs = new float[4]; - public float[] us = new float[4]; - public float[] vs = new float[4]; - public int[] cs = new int[4]; - public int[] ns = new int[4]; - public int[] bs = new int[4]; - - public boolean deleted; - - private final Vector3f vectorA = new Vector3f(), vectorB = new Vector3f(), vectorC = new Vector3f(); - - @Getter - private boolean shade; - private int cachedFlags; - @Getter - private ForgeDirection face; - private int colorIndex = -1; - - public int[] getColors() { - return this.cs; - } - - /** Returns the face, forced to take one of 6 directions to mirror the behavior of baked quads in 1.16.5. */ - @Override - public ForgeDirection getLightFace() { - return this.face != ForgeDirection.UNKNOWN ? this.face : ForgeDirection.UP; - } - - @Override - public float getX(int idx) { - return xs[idx]; - } - - @Override - public float getY(int idx) { - return ys[idx]; - } - - @Override - public float getZ(int idx) { - return zs[idx]; - } - - @Override - public int getColor(int idx) { - return cs[idx]; - } - - @Override - public float getTexU(int idx) { - return us[idx]; - } - - @Override - public float getTexV(int idx) { - return vs[idx]; - } - - @Override - public int getFlags() { - return this.cachedFlags; - } - - @Override - public int getLight(int idx) { - return bs[idx]; - } - - @Override - public int getNormal(int idx) { - return ns[idx]; - } - - @Override - public int getColorIndex() { - return colorIndex; - } - - @Override - public TextureAtlasSprite rubidium$getSprite() { - return null; - } - - public void copyFrom(Quad quad) { - - System.arraycopy(quad.xs, 0, this.xs, 0, 4); - System.arraycopy(quad.ys, 0, this.ys, 0, 4); - System.arraycopy(quad.zs, 0, this.zs, 0, 4); - - System.arraycopy(quad.us, 0, this.us, 0, 4); - System.arraycopy(quad.vs, 0, this.vs, 0, 4); - - System.arraycopy(quad.cs, 0, this.cs, 0, 4); - System.arraycopy(quad.ns, 0, this.ns, 0, 4); - System.arraycopy(quad.bs, 0, this.bs, 0, 4); - - this.deleted = quad.deleted; - this.shade = quad.shade; - this.cachedFlags = quad.cachedFlags; - this.face = quad.face; - this.colorIndex = quad.colorIndex; - } - - public void setRaw(int[] data, boolean shade, @Nullable ForgeDirection face, int colorIndex, int flags) { - - int i = 0; - for(int vi = 0; vi < 4; vi++) { - - xs[vi] = Float.intBitsToFloat(data[i + 0]); - ys[vi] = Float.intBitsToFloat(data[i + 1]); - zs[vi] = Float.intBitsToFloat(data[i + 2]); - - us[vi] = Float.intBitsToFloat(data[i + 3]); - vs[vi] = Float.intBitsToFloat(data[i + 4]); - - cs[vi] = data[i + 5]; - ns[vi] = data[i + 6]; - bs[vi] = data[i + 7]; - - i += 8; - } - - this.shade = shade; - this.deleted = false; - this.face = face; - this.colorIndex = colorIndex; - this.cachedFlags = flags; - } - - private void read(int[] rawBuffer, int offset, float offsetX, float offsetY, float offsetZ, int drawMode, BlockRenderer.Flags flags) { - final int vertices = drawMode == GL11.GL_TRIANGLES ? 3 : 4; - int i = offset; - for(int vi = 0; vi < vertices; vi++) { - - xs[vi] = Float.intBitsToFloat(rawBuffer[i + 0]) + offsetX; - ys[vi] = Float.intBitsToFloat(rawBuffer[i + 1]) + offsetY; - zs[vi] = Float.intBitsToFloat(rawBuffer[i + 2]) + offsetZ; - - us[vi] = Float.intBitsToFloat(rawBuffer[i + 3]); - vs[vi] = Float.intBitsToFloat(rawBuffer[i + 4]); - - cs[vi] = flags.hasColor ? rawBuffer[i + 5] : DEFAULT_COLOR; - ns[vi] = flags.hasNormals ? rawBuffer[i + 6] : 0; - bs[vi] = flags.hasBrightness ? rawBuffer[i + 7] : DEFAULT_BRIGHTNESS; - - i += 8; - } - - // sus - this.shade = flags.hasBrightness; - - if(vertices == 3) { - - // Quadrangulate! - xs[3] = xs[2]; - ys[3] = ys[2]; - zs[3] = zs[2]; - - us[3] = us[2]; - vs[3] = vs[2]; - - bs[3] = bs[2]; - cs[3] = cs[2]; - ns[3] = ns[2]; - } - } - - public void setState(int[] rawBuffer, int offset, BlockRenderer.Flags flags, int drawMode, float offsetX, float offsetY, float offsetZ) { - deleted = false; - - read(rawBuffer, offset, offsetX, offsetY, offsetZ, drawMode, flags); - - if(xs[0] == xs[1] && xs[1] == xs[2] && xs[2] == xs[3] && ys[0] == ys[1] && ys[1] == ys[2] && ys[2] == ys[3]) { - // ignore empty quads (e.g. alpha pass of EnderIO item conduits) - deleted = true; - return; - } - - vectorA.set(xs[1] - xs[0], ys[1] - ys[0], zs[1] - zs[0]); - vectorB.set(xs[2] - xs[1], ys[2] - ys[1], zs[2] - zs[1]); - vectorA.cross(vectorB, vectorC); - - this.face = ModelQuadFacing.toDirection(ModelQuadFacing.fromVector(vectorC)); - this.cachedFlags = ModelQuadFlags.getQuadFlags(this); - } - - public static boolean isValid(Quad q) { - return q != null && !q.deleted; - } - - @Override - public String toString() { - return String.format(Locale.ENGLISH, "%s[(%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f)]", deleted ? "XXX " : "", xs[0], ys[0], zs[0], xs[1], ys[1], zs[1], xs[2], ys[2], zs[2], xs[3], ys[3], zs[3]); - } -} diff --git a/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/ItemVBOQuadWriter.java b/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/ItemVBOQuadWriter.java index d13b10866..880b0d211 100644 --- a/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/ItemVBOQuadWriter.java +++ b/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/ItemVBOQuadWriter.java @@ -1,7 +1,7 @@ package com.gtnewhorizons.angelica.compat.nd.writers; +import com.gtnewhorizons.angelica.api.QuadView; import com.gtnewhorizons.angelica.compat.nd.IWriteQuads; -import com.gtnewhorizons.angelica.compat.nd.Quad; import java.nio.ByteBuffer; @@ -17,7 +17,7 @@ public void init(boolean direct) { this.direct = direct; } @Override - public void writeQuad(Quad quad, ByteBuffer buf) { + public void writeQuad(QuadView quad, ByteBuffer buf) { if(direct) { writeQuadDirect(quad, buf); } else { @@ -25,11 +25,11 @@ public void writeQuad(Quad quad, ByteBuffer buf) { } } - protected void writeQuadDirect(Quad quad, ByteBuffer buf) { + protected void writeQuadDirect(QuadView quad, ByteBuffer buf) { throw new UnsupportedOperationException("Direct mode not supported yet"); } - protected void writeQuadIndirect(Quad quad, ByteBuffer buf) { + protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) { for(int idx = 0; idx < 4; ++idx) { // Position buf.putFloat(quad.getX(idx)); diff --git a/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/PositionColorTextureQuadWriter.java b/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/PositionColorTextureQuadWriter.java index f0159efb5..31d653af5 100644 --- a/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/PositionColorTextureQuadWriter.java +++ b/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/PositionColorTextureQuadWriter.java @@ -1,7 +1,7 @@ package com.gtnewhorizons.angelica.compat.nd.writers; +import com.gtnewhorizons.angelica.api.QuadView; import com.gtnewhorizons.angelica.compat.nd.IWriteQuads; -import com.gtnewhorizons.angelica.compat.nd.Quad; import java.nio.ByteBuffer; @@ -17,7 +17,7 @@ public void init(boolean direct) { this.direct = direct; } @Override - public void writeQuad(Quad quad, ByteBuffer buf) { + public void writeQuad(QuadView quad, ByteBuffer buf) { if(direct) { writeQuadDirect(quad, buf); } else { @@ -25,11 +25,11 @@ public void writeQuad(Quad quad, ByteBuffer buf) { } } - protected void writeQuadDirect(Quad quad, ByteBuffer buf) { + protected void writeQuadDirect(QuadView quad, ByteBuffer buf) { throw new UnsupportedOperationException("Direct mode not supported yet"); } - protected void writeQuadIndirect(Quad quad, ByteBuffer buf) { + protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) { for(int idx = 0; idx < 4; ++idx) { // Position buf.putFloat(quad.getX(idx)); diff --git a/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/PositionQuadWriter.java b/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/PositionQuadWriter.java index cf3e25eef..bb85baef1 100644 --- a/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/PositionQuadWriter.java +++ b/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/PositionQuadWriter.java @@ -1,7 +1,7 @@ package com.gtnewhorizons.angelica.compat.nd.writers; +import com.gtnewhorizons.angelica.api.QuadView; import com.gtnewhorizons.angelica.compat.nd.IWriteQuads; -import com.gtnewhorizons.angelica.compat.nd.Quad; import java.nio.ByteBuffer; @@ -17,7 +17,7 @@ public void init(boolean direct) { this.direct = direct; } @Override - public void writeQuad(Quad quad, ByteBuffer buf) { + public void writeQuad(QuadView quad, ByteBuffer buf) { if(direct) { writeQuadDirect(quad, buf); } else { @@ -25,11 +25,11 @@ public void writeQuad(Quad quad, ByteBuffer buf) { } } - protected void writeQuadDirect(Quad quad, ByteBuffer buf) { + protected void writeQuadDirect(QuadView quad, ByteBuffer buf) { throw new UnsupportedOperationException("Direct mode not supported yet"); } - protected void writeQuadIndirect(Quad quad, ByteBuffer buf) { + protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) { for(int idx = 0; idx < 4; ++idx) { // Position buf.putFloat(quad.getX(idx)); diff --git a/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/PositionTextureColorQuadWriter.java b/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/PositionTextureColorQuadWriter.java index b9c3c6cc5..cb13e663e 100644 --- a/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/PositionTextureColorQuadWriter.java +++ b/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/PositionTextureColorQuadWriter.java @@ -1,7 +1,7 @@ package com.gtnewhorizons.angelica.compat.nd.writers; +import com.gtnewhorizons.angelica.api.QuadView; import com.gtnewhorizons.angelica.compat.nd.IWriteQuads; -import com.gtnewhorizons.angelica.compat.nd.Quad; import java.nio.ByteBuffer; @@ -17,7 +17,7 @@ public void init(boolean direct) { this.direct = direct; } @Override - public void writeQuad(Quad quad, ByteBuffer buf) { + public void writeQuad(QuadView quad, ByteBuffer buf) { if(direct) { writeQuadDirect(quad, buf); } else { @@ -25,11 +25,11 @@ public void writeQuad(Quad quad, ByteBuffer buf) { } } - protected void writeQuadDirect(Quad quad, ByteBuffer buf) { + protected void writeQuadDirect(QuadView quad, ByteBuffer buf) { throw new UnsupportedOperationException("Direct mode not supported yet"); } - protected void writeQuadIndirect(Quad quad, ByteBuffer buf) { + protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) { for(int idx = 0; idx < 4; ++idx) { // Position buf.putFloat(quad.getX(idx)); diff --git a/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/PositionTextureQuadWriter.java b/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/PositionTextureQuadWriter.java index ce44c9e64..d15c888f0 100644 --- a/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/PositionTextureQuadWriter.java +++ b/src/main/java/com/gtnewhorizons/angelica/compat/nd/writers/PositionTextureQuadWriter.java @@ -1,7 +1,7 @@ package com.gtnewhorizons.angelica.compat.nd.writers; +import com.gtnewhorizons.angelica.api.QuadView; import com.gtnewhorizons.angelica.compat.nd.IWriteQuads; -import com.gtnewhorizons.angelica.compat.nd.Quad; import java.nio.ByteBuffer; @@ -17,7 +17,7 @@ public void init(boolean direct) { this.direct = direct; } @Override - public void writeQuad(Quad quad, ByteBuffer buf) { + public void writeQuad(QuadView quad, ByteBuffer buf) { if(direct) { writeQuadDirect(quad, buf); } else { @@ -25,11 +25,11 @@ public void writeQuad(Quad quad, ByteBuffer buf) { } } - protected void writeQuadDirect(Quad quad, ByteBuffer buf) { + protected void writeQuadDirect(QuadView quad, ByteBuffer buf) { throw new UnsupportedOperationException("Direct mode not supported yet"); } - protected void writeQuadIndirect(Quad quad, ByteBuffer buf) { + protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) { for(int idx = 0; idx < 4; ++idx) { // Position buf.putFloat(quad.getX(idx)); diff --git a/src/main/java/com/gtnewhorizons/angelica/glsm/TessellatorManager.java b/src/main/java/com/gtnewhorizons/angelica/glsm/TessellatorManager.java index ded870301..472b8fe5e 100644 --- a/src/main/java/com/gtnewhorizons/angelica/glsm/TessellatorManager.java +++ b/src/main/java/com/gtnewhorizons/angelica/glsm/TessellatorManager.java @@ -1,16 +1,15 @@ package com.gtnewhorizons.angelica.glsm; +import com.gtnewhorizons.angelica.api.QuadView; import com.gtnewhorizons.angelica.client.renderer.CapturingTessellator; import com.gtnewhorizons.angelica.compat.mojang.VertexBuffer; import com.gtnewhorizons.angelica.compat.mojang.VertexFormat; -import com.gtnewhorizons.angelica.compat.nd.Quad; import net.minecraft.client.renderer.Tessellator; +import org.lwjgl.opengl.GL11; import java.nio.ByteBuffer; import java.util.List; -import org.lwjgl.opengl.GL11; - @SuppressWarnings("unused") public class TessellatorManager { private static final ThreadLocal capturingTessellator = ThreadLocal.withInitial(CapturingTessellator::new); @@ -51,7 +50,7 @@ public static void startCapturing() { * Stop the CapturingTessellator and return the pooled quads. The quads are valid until clearQuads() is * called on the CapturingTesselator, which must be done before starting capturing again. */ - public static List stopCapturingToPooledQuads() { + public static List stopCapturingToPooledQuads() { if(!currentlyCapturing.get()) throw new IllegalStateException("Tried to stop capturing when not capturing!"); currentlyCapturing.set(false); final CapturingTessellator tess = capturingTessellator.get(); @@ -59,7 +58,7 @@ public static List stopCapturingToPooledQuads() { // Be sure we got all the quads if(tess.isDrawing) tess.draw(); - final List quads = tess.getQuads(); + final List quads = tess.getQuads(); tess.discard(); tess.restoreTranslation(); diff --git a/src/main/java/com/gtnewhorizons/angelica/mixins/early/angelica/models/MixinBlockAir.java b/src/main/java/com/gtnewhorizons/angelica/mixins/early/angelica/models/MixinBlockAir.java index 0f411cfe7..c70764fc4 100644 --- a/src/main/java/com/gtnewhorizons/angelica/mixins/early/angelica/models/MixinBlockAir.java +++ b/src/main/java/com/gtnewhorizons/angelica/mixins/early/angelica/models/MixinBlockAir.java @@ -1,25 +1,28 @@ package com.gtnewhorizons.angelica.mixins.early.angelica.models; +import com.gtnewhorizons.angelica.api.BlockPos; import com.gtnewhorizons.angelica.api.QuadProvider; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; -import com.gtnewhorizons.angelica.compat.nd.Quad; -import com.gtnewhorizons.angelica.utils.ObjectPooler; +import com.gtnewhorizons.angelica.api.QuadView; import it.unimi.dsi.fastutil.objects.ObjectImmutableList; import net.minecraft.block.Block; import net.minecraft.block.BlockAir; import net.minecraft.world.IBlockAccess; import net.minecraftforge.common.util.ForgeDirection; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import java.util.List; import java.util.Random; +import java.util.function.Supplier; @Mixin(BlockAir.class) public abstract class MixinBlockAir implements QuadProvider { - private static List quads = ObjectImmutableList.of(); + @Unique + private static final List angelica$EMPTY = ObjectImmutableList.of(); - public List getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, ObjectPooler quadPool) { - return quads; + @Override + public List getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier quadPool) { + return angelica$EMPTY; } } diff --git a/src/main/java/com/gtnewhorizons/angelica/mixins/early/angelica/models/MixinBlockLeaves.java b/src/main/java/com/gtnewhorizons/angelica/mixins/early/angelica/models/MixinBlockLeaves.java index 412c24a1c..5888ed254 100644 --- a/src/main/java/com/gtnewhorizons/angelica/mixins/early/angelica/models/MixinBlockLeaves.java +++ b/src/main/java/com/gtnewhorizons/angelica/mixins/early/angelica/models/MixinBlockLeaves.java @@ -1,9 +1,8 @@ package com.gtnewhorizons.angelica.mixins.early.angelica.models; +import com.gtnewhorizons.angelica.api.BlockPos; import com.gtnewhorizons.angelica.api.QuadProvider; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; -import com.gtnewhorizons.angelica.compat.nd.Quad; -import com.gtnewhorizons.angelica.utils.ObjectPooler; +import com.gtnewhorizons.angelica.api.QuadView; import net.minecraft.block.Block; import net.minecraft.block.BlockLeaves; import net.minecraft.block.material.Material; @@ -13,13 +12,20 @@ import java.util.List; import java.util.Random; +import java.util.function.Supplier; import static com.gtnewhorizons.angelica.models.CubeModel.INSTANCE; @Mixin(BlockLeaves.class) public abstract class MixinBlockLeaves extends Block implements QuadProvider { - public List getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, ObjectPooler quadPool) { + @Override + public boolean isDynamic() { + return true; + } + + @Override + public List getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier quadPool) { return INSTANCE.get().getQuads(world, pos, block, meta, dir, random, color, quadPool); } diff --git a/src/main/java/com/gtnewhorizons/angelica/mixins/early/angelica/models/MixinBlockStone.java b/src/main/java/com/gtnewhorizons/angelica/mixins/early/angelica/models/MixinBlockStone.java index 2e953fc7f..4fdf6aa17 100644 --- a/src/main/java/com/gtnewhorizons/angelica/mixins/early/angelica/models/MixinBlockStone.java +++ b/src/main/java/com/gtnewhorizons/angelica/mixins/early/angelica/models/MixinBlockStone.java @@ -1,10 +1,9 @@ package com.gtnewhorizons.angelica.mixins.early.angelica.models; +import com.gtnewhorizons.angelica.api.BlockPos; import com.gtnewhorizons.angelica.api.QuadProvider; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; -import com.gtnewhorizons.angelica.compat.nd.Quad; +import com.gtnewhorizons.angelica.api.QuadView; import com.gtnewhorizons.angelica.models.VanillaModels; -import com.gtnewhorizons.angelica.utils.ObjectPooler; import net.minecraft.block.Block; import net.minecraft.block.BlockStone; import net.minecraft.world.IBlockAccess; @@ -13,12 +12,13 @@ import java.util.List; import java.util.Random; +import java.util.function.Supplier; @Mixin(BlockStone.class) public abstract class MixinBlockStone implements QuadProvider { - // TODO: Use modern model API - public List getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, ObjectPooler quadPool) { + @Override + public List getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier quadPool) { return VanillaModels.stoneModel.getQuads(world, pos, block, meta, dir, random, color, quadPool); } } diff --git a/src/main/java/com/gtnewhorizons/angelica/mixins/early/angelica/models/MixinBlockWorkbench.java b/src/main/java/com/gtnewhorizons/angelica/mixins/early/angelica/models/MixinBlockWorkbench.java index a24e7fcbf..fb6159b68 100644 --- a/src/main/java/com/gtnewhorizons/angelica/mixins/early/angelica/models/MixinBlockWorkbench.java +++ b/src/main/java/com/gtnewhorizons/angelica/mixins/early/angelica/models/MixinBlockWorkbench.java @@ -1,10 +1,9 @@ package com.gtnewhorizons.angelica.mixins.early.angelica.models; +import com.gtnewhorizons.angelica.api.BlockPos; import com.gtnewhorizons.angelica.api.QuadProvider; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; -import com.gtnewhorizons.angelica.compat.nd.Quad; +import com.gtnewhorizons.angelica.api.QuadView; import com.gtnewhorizons.angelica.models.CubeModel; -import com.gtnewhorizons.angelica.utils.ObjectPooler; import net.minecraft.block.Block; import net.minecraft.block.BlockWorkbench; import net.minecraft.world.IBlockAccess; @@ -13,12 +12,13 @@ import java.util.List; import java.util.Random; +import java.util.function.Supplier; @Mixin(BlockWorkbench.class) public class MixinBlockWorkbench implements QuadProvider { - // TODO: Use modern model API - public List getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, ObjectPooler quadPool) { + @Override + public List getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier quadPool) { return CubeModel.INSTANCE.get().getQuads(world, pos, block, meta, dir, random, color, quadPool); } } diff --git a/src/main/java/com/gtnewhorizons/angelica/models/CubeModel.java b/src/main/java/com/gtnewhorizons/angelica/models/CubeModel.java index 02f236f91..d7d8fa78d 100644 --- a/src/main/java/com/gtnewhorizons/angelica/models/CubeModel.java +++ b/src/main/java/com/gtnewhorizons/angelica/models/CubeModel.java @@ -1,9 +1,8 @@ package com.gtnewhorizons.angelica.models; +import com.gtnewhorizons.angelica.api.BlockPos; import com.gtnewhorizons.angelica.api.QuadProvider; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; -import com.gtnewhorizons.angelica.compat.nd.Quad; -import com.gtnewhorizons.angelica.utils.ObjectPooler; +import com.gtnewhorizons.angelica.api.QuadView; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectImmutableList; import net.minecraft.block.Block; @@ -13,6 +12,7 @@ import java.util.List; import java.util.Random; +import java.util.function.Supplier; public class CubeModel implements QuadProvider { @@ -23,8 +23,8 @@ public class CubeModel implements QuadProvider { public static final ThreadLocal INSTANCE = ThreadLocal.withInitial(CubeModel::new); private final NdQuadBuilder builder = new NdQuadBuilder(); - private static final List EMPTY = ObjectImmutableList.of(); - private final List ONE = new ObjectArrayList<>(1); + private static final List EMPTY = ObjectImmutableList.of(); + private final List ONE = new ObjectArrayList<>(1); public CubeModel() { @@ -32,7 +32,12 @@ public CubeModel() { } @Override - public List getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, ObjectPooler quadPool) { + public boolean isDynamic() { + return true; + } + + @Override + public List getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier quadPool) { if (dir == ForgeDirection.UNKNOWN) return EMPTY; @@ -43,7 +48,7 @@ public List getQuads(IBlockAccess world, BlockPos pos, Block block, int me this.builder.color(color, color, color, color); - ONE.set(0, this.builder.build(quadPool.getInstance())); + ONE.set(0, this.builder.build(quadPool.get())); return ONE; } } diff --git a/src/main/java/com/gtnewhorizons/angelica/models/GeometryHelper.java b/src/main/java/com/gtnewhorizons/angelica/models/GeometryHelper.java index 2b7e8697e..7785ecd9a 100644 --- a/src/main/java/com/gtnewhorizons/angelica/models/GeometryHelper.java +++ b/src/main/java/com/gtnewhorizons/angelica/models/GeometryHelper.java @@ -1,7 +1,7 @@ package com.gtnewhorizons.angelica.models; import com.gtnewhorizons.angelica.compat.mojang.Axis; -import com.gtnewhorizons.angelica.compat.nd.Quad; +import me.jellysquid.mods.sodium.client.model.quad.Quad; import net.minecraftforge.common.util.ForgeDirection; import org.joml.Vector3f; diff --git a/src/main/java/com/gtnewhorizons/angelica/models/NdQuadBuilder.java b/src/main/java/com/gtnewhorizons/angelica/models/NdQuadBuilder.java index c87eaedfb..699d25074 100644 --- a/src/main/java/com/gtnewhorizons/angelica/models/NdQuadBuilder.java +++ b/src/main/java/com/gtnewhorizons/angelica/models/NdQuadBuilder.java @@ -1,6 +1,7 @@ package com.gtnewhorizons.angelica.models; -import com.gtnewhorizons.angelica.compat.nd.Quad; +import com.gtnewhorizons.angelica.api.QuadView; +import me.jellysquid.mods.sodium.client.model.quad.Quad; import lombok.Getter; import me.jellysquid.mods.sodium.client.model.quad.ModelQuadView; import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFlags; @@ -16,18 +17,6 @@ public class NdQuadBuilder implements ModelQuadView { - // x, y, z, u, v, color, normal, lightmap - public static final int INTS_PER_VERTEX = 8; - public static final int QUAD_STRIDE = INTS_PER_VERTEX * 4; - public static final int X_INDEX = 0; - public static final int Y_INDEX = 1; - public static final int Z_INDEX = 2; - public static final int U_INDEX = 3; - public static final int V_INDEX = 4; - public static final int COLOR_INDEX = 5; - public static final int NORMAL_INDEX = 6; - public static final int LIGHTMAP_INDEX = 7; - /** * Causes texture to appear with no rotation. * Pass in bakeFlags parameter to {@link #spriteBake(IIcon, int)}. @@ -99,7 +88,7 @@ public class NdQuadBuilder implements ModelQuadView { private ForgeDirection lightFace = ForgeDirection.UP; // It's called a header, but because I'm lazy it's at the end // The header is an int with flags -------- -------- -------- -GGGNNNN, then an int for the normal - private final int[] data = new int[QUAD_STRIDE]; + private final int[] data = new int[Quad.QUAD_STRIDE]; private int geometryFlags = 0; private boolean isGeometryInvalid = true; private int tag = 0; @@ -111,7 +100,7 @@ public class NdQuadBuilder implements ModelQuadView { /** * Dumps to {@param out} and returns it. */ - public Quad build(Quad out) { + public QuadView build(QuadView out) { // FRAPI does this late, but we need to do it before baking to Nd quads this.computeGeometry(); @@ -137,7 +126,7 @@ public void clear() { * Set vertex color in ARGB format (0xAARRGGBB). */ public void color(int vertexIndex, int color) { - data[vertexIndex * INTS_PER_VERTEX + COLOR_INDEX] = color; + data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.COLOR_INDEX] = color; } /** @@ -247,18 +236,18 @@ public ForgeDirection nominalFace() { */ public void pos(int vertexIndex, float x, float y, float z) { - data[vertexIndex * INTS_PER_VERTEX + X_INDEX] = Float.floatToRawIntBits(x); - data[vertexIndex * INTS_PER_VERTEX + Y_INDEX] = Float.floatToRawIntBits(y); - data[vertexIndex * INTS_PER_VERTEX + Z_INDEX] = Float.floatToRawIntBits(z); + data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.X_INDEX] = Float.floatToRawIntBits(x); + data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.Y_INDEX] = Float.floatToRawIntBits(y); + data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.Z_INDEX] = Float.floatToRawIntBits(z); isGeometryInvalid = true; } public Vector3f pos(int vertexIndex) { return new Vector3f( - Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + X_INDEX]), - Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + Y_INDEX]), - Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + Z_INDEX]) + Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.X_INDEX]), + Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.Y_INDEX]), + Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.Z_INDEX]) ); } @@ -266,7 +255,7 @@ public Vector3f pos(int vertexIndex) { * Convenience: access x, y, z by index 0-2. */ float posByIndex(int vertexIndex, int coordinateIndex) { - return Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + X_INDEX + coordinateIndex]); + return Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.X_INDEX + coordinateIndex]); } /** @@ -365,48 +354,48 @@ public void tag(int tag) { */ public void uv(int vertexIndex, float u, float v) { - data[vertexIndex * INTS_PER_VERTEX + U_INDEX] = Float.floatToRawIntBits(u); - data[vertexIndex * INTS_PER_VERTEX + V_INDEX] = Float.floatToRawIntBits(v); + data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.U_INDEX] = Float.floatToRawIntBits(u); + data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.V_INDEX] = Float.floatToRawIntBits(v); } @Override public float getX(int vertexIndex) { - return Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + X_INDEX]); + return Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.X_INDEX]); } @Override public float getY(int vertexIndex) { - return Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + Y_INDEX]); + return Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.Y_INDEX]); } @Override public float getZ(int vertexIndex) { - return Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + Z_INDEX]); + return Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.Z_INDEX]); } @Override public float getTexU(int vertexIndex) { - return Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + U_INDEX]); + return Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.U_INDEX]); } @Override public float getTexV(int vertexIndex) { - return Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + V_INDEX]); + return Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.V_INDEX]); } @Override public int getColor(int vertexIndex) { - return this.data[vertexIndex * INTS_PER_VERTEX + COLOR_INDEX]; + return this.data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.COLOR_INDEX]; } @Override public int getNormal(int vertexIndex) { - return this.data[vertexIndex * INTS_PER_VERTEX + NORMAL_INDEX]; + return this.data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.NORMAL_INDEX]; } @Override public int getLight(int vertexIndex) { - return this.data[vertexIndex * INTS_PER_VERTEX + LIGHTMAP_INDEX]; + return this.data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.LIGHTMAP_INDEX]; } @Override diff --git a/src/main/java/com/gtnewhorizons/angelica/models/json/JsonModel.java b/src/main/java/com/gtnewhorizons/angelica/models/json/JsonModel.java index 163ab989d..d9514f560 100644 --- a/src/main/java/com/gtnewhorizons/angelica/models/json/JsonModel.java +++ b/src/main/java/com/gtnewhorizons/angelica/models/json/JsonModel.java @@ -6,13 +6,13 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; +import com.gtnewhorizons.angelica.api.BlockPos; import com.gtnewhorizons.angelica.api.QuadProvider; +import com.gtnewhorizons.angelica.api.QuadView; import com.gtnewhorizons.angelica.compat.mojang.Axis; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; -import com.gtnewhorizons.angelica.compat.nd.Quad; +import me.jellysquid.mods.sodium.client.model.quad.Quad; import com.gtnewhorizons.angelica.models.NdQuadBuilder; import com.gtnewhorizons.angelica.utils.DirUtil; -import com.gtnewhorizons.angelica.utils.ObjectPooler; import it.unimi.dsi.fastutil.Function; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -32,6 +32,7 @@ import java.util.List; import java.util.Map; import java.util.Random; +import java.util.function.Supplier; import static com.gtnewhorizons.angelica.utils.JsonUtil.*; import static me.jellysquid.mods.sodium.common.util.DirectionUtil.ALL_DIRECTIONS; @@ -47,9 +48,9 @@ public class JsonModel implements QuadProvider { private final Map display; private final Map textures; private List elements; - private List allQuadStore = new ObjectArrayList<>(); - private final Map> sidedQuadStore = new Object2ObjectOpenHashMap<>(); - private static final List EMPTY = ObjectImmutableList.of(); + private List allQuadStore = new ObjectArrayList<>(); + private final Map> sidedQuadStore = new Object2ObjectOpenHashMap<>(); + private static final List EMPTY = ObjectImmutableList.of(); JsonModel(@Nullable ResourceLocation parentId, boolean useAO, Map display, Map textures, List elements) { this.parentId = parentId; @@ -136,7 +137,7 @@ public void bake(Variant v) { builder.mat.setAO(this.useAO); // Bake and add it - final Quad q = builder.build(new Quad()); + final QuadView q = builder.build(new Quad()); this.allQuadStore.add(q); this.sidedQuadStore.computeIfAbsent(f.getCullFace(), o -> new ObjectArrayList<>()).add(q); @@ -147,7 +148,7 @@ public void bake(Variant v) { this.allQuadStore = new ObjectImmutableList<>(this.allQuadStore); for (ForgeDirection f : ALL_DIRECTIONS) { - List l = this.sidedQuadStore.computeIfAbsent(f, o -> EMPTY); + List l = this.sidedQuadStore.computeIfAbsent(f, o -> EMPTY); if (!l.isEmpty()) this.sidedQuadStore.put(f, new ObjectImmutableList<>(l)); } @@ -158,19 +159,9 @@ public List getParents() { } @Override - public List getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, ObjectPooler quadPool) { + public List getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier quadPool) { - final List src = this.sidedQuadStore.getOrDefault(dir, EMPTY); - final List ret = new ObjectArrayList<>(src.size()); - - //noinspection ForLoopReplaceableByForEach - for (int i = 0; i < src.size(); ++i) { - final Quad q = quadPool.getInstance(); - q.copyFrom(src.get(i)); - ret.add(q); - } - - return ret; + return this.sidedQuadStore.getOrDefault(dir, EMPTY); } public void resolveParents(Function modelLoader) { diff --git a/src/main/java/me/jellysquid/mods/sodium/client/model/light/EntityLighter.java b/src/main/java/me/jellysquid/mods/sodium/client/model/light/EntityLighter.java index 6c419bd29..892202096 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/model/light/EntityLighter.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/model/light/EntityLighter.java @@ -1,6 +1,6 @@ package me.jellysquid.mods.sodium.client.model.light; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; import net.minecraft.util.MathHelper; import net.minecraft.entity.Entity; import net.minecraft.world.EnumSkyBlock; @@ -46,7 +46,7 @@ public static int getBlendedLight(Entity entity, float tickDelta) { double sl = 0; double bl = 0; - BlockPos.Mutable pos = new BlockPos.Mutable(); + BlockPosImpl pos = new BlockPosImpl(); // Iterate over every block in the sampling volume for (int bX = bMinX; bX < bMaxX; bX++) { diff --git a/src/main/java/me/jellysquid/mods/sodium/client/model/light/LightPipeline.java b/src/main/java/me/jellysquid/mods/sodium/client/model/light/LightPipeline.java index e81603d2c..a7e75eff5 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/model/light/LightPipeline.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/model/light/LightPipeline.java @@ -1,6 +1,6 @@ package me.jellysquid.mods.sodium.client.model.light; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; import me.jellysquid.mods.sodium.client.model.light.data.QuadLightData; import me.jellysquid.mods.sodium.client.model.quad.ModelQuadView; import net.minecraftforge.common.util.ForgeDirection; @@ -18,5 +18,5 @@ public interface LightPipeline { * @param face The pre-computed facing vector of the quad * @param shade True if the block is shaded by ambient occlusion */ - void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, ForgeDirection cullFace, ForgeDirection face, boolean shade); + void calculate(ModelQuadView quad, BlockPosImpl pos, QuadLightData out, ForgeDirection cullFace, ForgeDirection face, boolean shade); } diff --git a/src/main/java/me/jellysquid/mods/sodium/client/model/light/cache/HashLightDataCache.java b/src/main/java/me/jellysquid/mods/sodium/client/model/light/cache/HashLightDataCache.java index 275886426..70c07b0af 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/model/light/cache/HashLightDataCache.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/model/light/cache/HashLightDataCache.java @@ -1,6 +1,6 @@ package me.jellysquid.mods.sodium.client.model.light.cache; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; +import com.gtnewhorizons.angelica.api.BlockPos; import it.unimi.dsi.fastutil.longs.Long2LongLinkedOpenHashMap; import me.jellysquid.mods.sodium.client.model.light.data.LightDataAccess; import me.jellysquid.mods.sodium.client.world.WorldSlice; diff --git a/src/main/java/me/jellysquid/mods/sodium/client/model/light/data/LightDataAccess.java b/src/main/java/me/jellysquid/mods/sodium/client/model/light/data/LightDataAccess.java index f4cd5c773..50dd2ff6a 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/model/light/data/LightDataAccess.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/model/light/data/LightDataAccess.java @@ -1,6 +1,6 @@ package me.jellysquid.mods.sodium.client.model.light.data; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; import me.jellysquid.mods.sodium.client.util.StateUtil; import me.jellysquid.mods.sodium.client.world.WorldSlice; import net.minecraft.block.Block; @@ -22,7 +22,7 @@ * You can use the various static pack/unpack methods to extract these values in a usable format. */ public abstract class LightDataAccess { - private final BlockPos.Mutable pos = new BlockPos.Mutable(); + private final BlockPosImpl pos = new BlockPosImpl(); protected WorldSlice world; public long get(int x, int y, int z, ForgeDirection d1, ForgeDirection d2) { @@ -33,11 +33,11 @@ public long get(int x, int y, int z, ForgeDirection dir) { return this.get(x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ); } - public long get(BlockPos pos, ForgeDirection dir) { + public long get(BlockPosImpl pos, ForgeDirection dir) { return this.get(pos.x, pos.y, pos.z, dir); } - public long get(BlockPos pos) { + public long get(BlockPosImpl pos) { return this.get(pos.x, pos.y, pos.getZ()); } diff --git a/src/main/java/me/jellysquid/mods/sodium/client/model/light/flat/FlatLightPipeline.java b/src/main/java/me/jellysquid/mods/sodium/client/model/light/flat/FlatLightPipeline.java index 5d85b4f23..2aa628247 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/model/light/flat/FlatLightPipeline.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/model/light/flat/FlatLightPipeline.java @@ -1,6 +1,6 @@ package me.jellysquid.mods.sodium.client.model.light.flat; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; import com.gtnewhorizons.angelica.config.AngelicaConfig; import me.jellysquid.mods.sodium.client.model.light.LightPipeline; import me.jellysquid.mods.sodium.client.model.light.data.LightDataAccess; @@ -27,7 +27,7 @@ public FlatLightPipeline(LightDataAccess lightCache) { } @Override - public void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, ForgeDirection cullFace, ForgeDirection face, boolean shade) { + public void calculate(ModelQuadView quad, BlockPosImpl pos, QuadLightData out, ForgeDirection cullFace, ForgeDirection face, boolean shade) { int lightmap; // To match vanilla behavior, use the cull face if it exists/is available @@ -57,7 +57,7 @@ public void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, Forge * behind tinted glass. {@link LightDataAccess} cannot efficiently store lightmaps computed with * inconsistent values so this method exists to mirror vanilla behavior as closely as possible. */ - private int getOffsetLightmap(BlockPos pos, ForgeDirection face) { + private int getOffsetLightmap(BlockPosImpl pos, ForgeDirection face) { int lightmap = LightDataAccess.unpackLM(this.lightCache.get(pos, face)); // If the block light is not 15 (max)... if ((lightmap & 0xF0) != 0xF0) { diff --git a/src/main/java/me/jellysquid/mods/sodium/client/model/light/smooth/AoFaceData.java b/src/main/java/me/jellysquid/mods/sodium/client/model/light/smooth/AoFaceData.java index a6edf74e1..de5842b00 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/model/light/smooth/AoFaceData.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/model/light/smooth/AoFaceData.java @@ -1,6 +1,6 @@ package me.jellysquid.mods.sodium.client.model.light.smooth; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; import me.jellysquid.mods.sodium.client.model.light.data.LightDataAccess; import net.minecraftforge.common.util.ForgeDirection; @@ -18,7 +18,7 @@ class AoFaceData { private int flags; - public void initLightData(LightDataAccess cache, BlockPos pos, ForgeDirection direction, boolean offset) { + public void initLightData(LightDataAccess cache, BlockPosImpl pos, ForgeDirection direction, boolean offset) { final int x = pos.x; final int y = pos.y; final int z = pos.z; diff --git a/src/main/java/me/jellysquid/mods/sodium/client/model/light/smooth/SmoothLightPipeline.java b/src/main/java/me/jellysquid/mods/sodium/client/model/light/smooth/SmoothLightPipeline.java index dbc6ef5c4..eacc1b449 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/model/light/smooth/SmoothLightPipeline.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/model/light/smooth/SmoothLightPipeline.java @@ -1,7 +1,7 @@ package me.jellysquid.mods.sodium.client.model.light.smooth; import com.google.common.math.DoubleMath; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; import com.gtnewhorizons.angelica.config.AngelicaConfig; import me.jellysquid.mods.sodium.client.model.light.LightPipeline; import me.jellysquid.mods.sodium.client.model.light.data.LightDataAccess; @@ -69,7 +69,7 @@ public SmoothLightPipeline(LightDataAccess cache) { } @Override - public void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, ForgeDirection cullFace, ForgeDirection face, boolean shade) { + public void calculate(ModelQuadView quad, BlockPosImpl pos, QuadLightData out, ForgeDirection cullFace, ForgeDirection face, boolean shade) { this.updateCachedData(pos.asLong()); int flags = quad.getFlags(); @@ -101,7 +101,7 @@ public void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, Forge * have two contributing sides. * Flags: IS_ALIGNED, !IS_PARTIAL */ - private void applyAlignedFullFace(AoNeighborInfo neighborInfo, BlockPos pos, ForgeDirection dir, QuadLightData out) { + private void applyAlignedFullFace(AoNeighborInfo neighborInfo, BlockPosImpl pos, ForgeDirection dir, QuadLightData out) { AoFaceData faceData = this.getCachedFaceData(pos, dir, true); neighborInfo.mapCorners(faceData.lm, faceData.ao, out.lm, out.br); } @@ -110,7 +110,7 @@ private void applyAlignedFullFace(AoNeighborInfo neighborInfo, BlockPos pos, For * Calculates the light data for a grid-aligned quad that does not cover the entire block volume's face. * Flags: IS_ALIGNED, IS_PARTIAL */ - private void applyAlignedPartialFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPos pos, ForgeDirection dir, QuadLightData out) { + private void applyAlignedPartialFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPosImpl pos, ForgeDirection dir, QuadLightData out) { for (int i = 0; i < 4; i++) { // Clamp the vertex positions to the block's boundaries to prevent weird errors in lighting float cx = clamp(quad.getX(i)); @@ -124,13 +124,13 @@ private void applyAlignedPartialFace(AoNeighborInfo neighborInfo, ModelQuadView } /** - * This method is the same as {@link #applyNonParallelFace(AoNeighborInfo, ModelQuadView, BlockPos, ForgeDirection, + * This method is the same as {@link #applyNonParallelFace(AoNeighborInfo, ModelQuadView, BlockPosImpl, ForgeDirection, * QuadLightData)} but with the check for a depth of approximately 0 removed. If the quad is parallel but not * aligned, all of its vertices will have the same depth and this depth must be approximately greater than 0, * meaning the check for 0 will always return false. * Flags: !IS_ALIGNED, IS_PARALLEL */ - private void applyParallelFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPos pos, ForgeDirection dir, QuadLightData out) { + private void applyParallelFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPosImpl pos, ForgeDirection dir, QuadLightData out) { for (int i = 0; i < 4; i++) { // Clamp the vertex positions to the block's boundaries to prevent weird errors in lighting float cx = clamp(quad.getX(i)); @@ -157,7 +157,7 @@ private void applyParallelFace(AoNeighborInfo neighborInfo, ModelQuadView quad, /** * Flags: !IS_ALIGNED, !IS_PARALLEL */ - private void applyNonParallelFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPos pos, ForgeDirection dir, QuadLightData out) { + private void applyNonParallelFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPosImpl pos, ForgeDirection dir, QuadLightData out) { for (int i = 0; i < 4; i++) { // Clamp the vertex positions to the block's boundaries to prevent weird errors in lighting float cx = clamp(quad.getX(i)); @@ -182,7 +182,7 @@ private void applyNonParallelFace(AoNeighborInfo neighborInfo, ModelQuadView qua } } - private void applyAlignedPartialFaceVertex(BlockPos pos, ForgeDirection dir, float[] w, int i, QuadLightData out, boolean offset) { + private void applyAlignedPartialFaceVertex(BlockPosImpl pos, ForgeDirection dir, float[] w, int i, QuadLightData out, boolean offset) { AoFaceData faceData = this.getCachedFaceData(pos, dir, offset); if (!faceData.hasUnpackedLightData()) { @@ -197,7 +197,7 @@ private void applyAlignedPartialFaceVertex(BlockPos pos, ForgeDirection dir, flo out.lm[i] = getLightMapCoord(sl, bl); } - private void applyInsetPartialFaceVertex(BlockPos pos, ForgeDirection dir, float n1d, float n2d, float[] w, int i, QuadLightData out) { + private void applyInsetPartialFaceVertex(BlockPosImpl pos, ForgeDirection dir, float n1d, float n2d, float[] w, int i, QuadLightData out) { AoFaceData n1 = this.getCachedFaceData(pos, dir, false); if (!n1.hasUnpackedLightData()) { @@ -235,7 +235,7 @@ private void applySidedBrightness(QuadLightData out, ForgeDirection face, boolea /** * Returns the cached data for a given facing or calculates it if it hasn't been cached. */ - private AoFaceData getCachedFaceData(BlockPos pos, ForgeDirection face, boolean offset) { + private AoFaceData getCachedFaceData(BlockPosImpl pos, ForgeDirection face, boolean offset) { AoFaceData data = this.cachedFaceData[offset ? face.ordinal() : face.ordinal() + 6]; if (!data.hasLightData()) { diff --git a/src/main/java/me/jellysquid/mods/sodium/client/model/quad/Quad.java b/src/main/java/me/jellysquid/mods/sodium/client/model/quad/Quad.java new file mode 100644 index 000000000..feb4475b0 --- /dev/null +++ b/src/main/java/me/jellysquid/mods/sodium/client/model/quad/Quad.java @@ -0,0 +1,335 @@ +package me.jellysquid.mods.sodium.client.model.quad; + +import com.gtnewhorizons.angelica.api.QuadView; +import lombok.Getter; +import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFacing; +import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFlags; +import me.jellysquid.mods.sodium.client.render.pipeline.BlockRenderer; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraftforge.common.util.ForgeDirection; +import org.joml.Vector3f; +import org.lwjgl.opengl.GL11; + +import javax.annotation.Nullable; +import java.util.Locale; + +/** + * Roughly equivalent to 16.5's BakedQuadView and BakedQuadMixin + */ +public class Quad implements QuadView { + // Adapted from Neodymium + + public static final int INTS_PER_VERTEX = 8; + public static final int QUAD_STRIDE = INTS_PER_VERTEX * 4; + public static final int X_INDEX = 0; + public static final int Y_INDEX = 1; + public static final int Z_INDEX = 2; + public static final int U_INDEX = 3; + public static final int V_INDEX = 4; + public static final int COLOR_INDEX = 5; + public static final int NORMAL_INDEX = 6; + public static final int LIGHTMAP_INDEX = 7; + + private final static int DEFAULT_LIGHTMAP = 15 << 20 | 15 << 4; + private final static int DEFAULT_COLOR = 0xFFFFFFFF; + + private final int[] data = new int[QUAD_STRIDE]; + + @Getter + private boolean deleted; + + private final Vector3f vectorA = new Vector3f(), vectorB = new Vector3f(), vectorC = new Vector3f(); + + @Getter + private boolean shade; + private int cachedFlags; + @Getter + private ForgeDirection face; + private int colorIndex = -1; + private TextureAtlasSprite sprite = null; + + /** Returns the face, forced to take one of 6 directions to mirror the behavior of baked quads in 1.16.5. */ + @Override + public ForgeDirection getLightFace() { + return this.face != ForgeDirection.UNKNOWN ? this.face : ForgeDirection.UP; + } + + @Override + public float getX(int idx) { + return Float.intBitsToFloat(this.data[idx * INTS_PER_VERTEX + X_INDEX]); + } + + @Override + public float getY(int idx) { + return Float.intBitsToFloat(this.data[idx * INTS_PER_VERTEX + Y_INDEX]); + } + + @Override + public float getZ(int idx) { + return Float.intBitsToFloat(this.data[idx * INTS_PER_VERTEX + Z_INDEX]); + } + + @Override + public float getTexU(int idx) { + return Float.intBitsToFloat(this.data[idx * INTS_PER_VERTEX + U_INDEX]); + } + + @Override + public float getTexV(int idx) { + return Float.intBitsToFloat(this.data[idx * INTS_PER_VERTEX + V_INDEX]); + } + + @Override + public int getColor(int idx) { + return this.data[idx * INTS_PER_VERTEX + COLOR_INDEX]; + } + + @Override + public int getLight(int idx) { + return this.data[idx * INTS_PER_VERTEX + LIGHTMAP_INDEX]; + } + + @Override + public int getNormal(int idx) { + return this.data[idx * INTS_PER_VERTEX + NORMAL_INDEX]; + } + + @Override + public int getFlags() { + return this.cachedFlags; + } + + @Override + public int getColorIndex() { + return this.colorIndex; + } + + @Override + public TextureAtlasSprite rubidium$getSprite() { + return this.sprite; + } + + @Override + public void setX(int idx, float x) { + this.data[idx * INTS_PER_VERTEX + X_INDEX] = Float.floatToRawIntBits(x); + } + + @Override + public void setY(int idx, float y) { + this.data[idx * INTS_PER_VERTEX + Y_INDEX] = Float.floatToRawIntBits(y); + } + + @Override + public void setZ(int idx, float z) { + this.data[idx * INTS_PER_VERTEX + Z_INDEX] = Float.floatToRawIntBits(z); + } + + @Override + public void setTexU(int idx, float u) { + this.data[idx * INTS_PER_VERTEX + U_INDEX] = Float.floatToRawIntBits(u); + } + + @Override + public void setTexV(int idx, float v) { + this.data[idx * INTS_PER_VERTEX + V_INDEX] = Float.floatToRawIntBits(v); + } + + @Override + public void setColor(int idx, int c) { + this.data[idx * INTS_PER_VERTEX + COLOR_INDEX] = c; + } + + @Override + public void setLight(int idx, int l) { + this.data[idx * INTS_PER_VERTEX + LIGHTMAP_INDEX] = l; + } + + @Override + public void setNormal(int idx, int n) { + this.data[idx * INTS_PER_VERTEX + NORMAL_INDEX] = n; + } + + @Override + public void setFlags(int flags) { + this.cachedFlags = flags; + } + + @Override + public void setColorIndex(int i) { + this.colorIndex = i; + } + + @Override + public void setSprite(TextureAtlasSprite sprite) { + this.sprite = sprite; + } + + @Override + public int[] getRawVertexes() { + return this.data; + } + + /** + * Convenience: access x, y, z by index 0-2. + */ + private float posByIndex(int vertexIndex, int coordinateIndex) { + return Float.intBitsToFloat(this.data[vertexIndex * INTS_PER_VERTEX + coordinateIndex]); + } + + /** + * Convenience: access x, y, z by index 0-2. + */ + private void setPosByIndex(int vertexIndex, int coordinateIndex, float val) { + this.data[vertexIndex * INTS_PER_VERTEX + coordinateIndex] = Float.floatToRawIntBits(val); + } + + /** + * Offset all xs, ys, or zs by index 0-2. + */ + private void offsetPos(int idx, float offset) { + this.setPosByIndex(0, idx, this.posByIndex(0, idx) + offset); + this.setPosByIndex(1, idx, this.posByIndex(1, idx) + offset); + this.setPosByIndex(2, idx, this.posByIndex(2, idx) + offset); + this.setPosByIndex(3, idx, this.posByIndex(3, idx) + offset); + } + + private void clearColors() { + this.setColor(0, DEFAULT_COLOR); + this.setColor(1, DEFAULT_COLOR); + this.setColor(2, DEFAULT_COLOR); + this.setColor(3, DEFAULT_COLOR); + } + + private void clearNormals() { + this.setNormal(0, 0); + this.setNormal(1, 0); + this.setNormal(2, 0); + this.setNormal(3, 0); + } + + private void clearLight() { + this.setLight(0, DEFAULT_LIGHTMAP); + this.setLight(1, DEFAULT_LIGHTMAP); + this.setLight(2, DEFAULT_LIGHTMAP); + this.setLight(3, DEFAULT_LIGHTMAP); + } + + private boolean isEmpty() { + return this.getX(0) == this.getX(1) + && this.getX(1) == this.getX(2) + && this.getX(2) == this.getX(3) + && this.getY(0) == this.getY(1) + && this.getY(1) == this.getY(2) + && this.getY(2) == this.getY(3); + } + + private void calcNormal() { + this.vectorA.set( + this.getX(1) - this.getX(0), + this.getY(1) - this.getY(0), + this.getZ(1) - this.getZ(0) + ); + this.vectorB.set( + this.getX(2) - this.getX(1), + this.getY(2) - this.getY(1), + this.getZ(2) - this.getZ(1) + ); + this.vectorA.cross(this.vectorB, this.vectorC); + } + + @Override + public void copyFrom(QuadView quad) { + + System.arraycopy(quad.getRawVertexes(), 0, this.data, 0, QUAD_STRIDE); + + this.deleted = quad.isDeleted(); + this.shade = quad.isShade(); + this.face = quad.getFace(); + this.colorIndex = quad.getColorIndex(); + this.cachedFlags = quad.getFlags(); + this.sprite = quad.rubidium$getSprite(); + } + + /** + * Unlike setState, setRaw assumes your quad is valid and does not compute normals, clear color/normal/lightmap + * values, or quadrangulate. Basically the same as copyFrom but without an input quad. + */ + public void setRaw(int[] data, boolean shade, @Nullable ForgeDirection face, int colorIndex, int flags) { + + System.arraycopy(data, 0, this.data, 0, QUAD_STRIDE); + + this.deleted = false; + this.shade = shade; + this.face = face; + this.colorIndex = colorIndex; + this.cachedFlags = flags; + } + + private void read(int[] rawBuffer, int offset, float offsetX, float offsetY, float offsetZ, int drawMode, BlockRenderer.Flags flags) { + System.arraycopy(rawBuffer, offset, this.data, 0, QUAD_STRIDE); + + if (offsetX != 0) this.offsetPos(0, offsetX); + if (offsetY != 0) this.offsetPos(1, offsetY); + if (offsetZ != 0) this.offsetPos(2, offsetZ); + + if (!flags.hasColor) this.clearColors(); + if (!flags.hasNormals) this.clearNormals(); + if (!flags.hasBrightness) this.clearLight(); + + // sus + this.shade = flags.hasBrightness; + + if (drawMode == GL11.GL_TRIANGLES) { + + // Quadrangulate! + this.setX(3, this.getX(2)); + this.setY(3, this.getY(2)); + this.setZ(3, this.getZ(2)); + + this.setTexU(3, this.getTexU(2)); + this.setTexV(3, this.getTexV(2)); + + this.setLight(3, this.getLight(2)); + this.setColor(3, this.getColor(2)); + this.setNormal(3, this.getNormal(2)); + } + } + + @Override + public void setState(int[] rawBuffer, int offset, BlockRenderer.Flags flags, int drawMode, float offsetX, float offsetY, float offsetZ) { + this.deleted = false; + + read(rawBuffer, offset, offsetX, offsetY, offsetZ, drawMode, flags); + + if (this.isEmpty()) { + // ignore empty quads (e.g. alpha pass of EnderIO item conduits) + this.deleted = true; + return; + } + + this.calcNormal(); + this.face = ModelQuadFacing.toDirection(ModelQuadFacing.fromVector(this.vectorC)); + this.cachedFlags = ModelQuadFlags.getQuadFlags(this); + } + + @Override + public String toString() { + return String.format( + Locale.ENGLISH, + "%s[(%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f)]", + this.deleted ? "XXX " : "", + this.getX(0), + this.getY(0), + this.getZ(0), + this.getX(1), + this.getY(1), + this.getZ(1), + this.getX(2), + this.getY(2), + this.getZ(2), + this.getX(3), + this.getY(3), + this.getZ(3) + ); + } +} diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderContainer.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderContainer.java index 5b4d7c320..d00172bb3 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderContainer.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderContainer.java @@ -1,6 +1,6 @@ package me.jellysquid.mods.sodium.client.render.chunk; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; import com.gtnewhorizons.angelica.compat.mojang.ChunkSectionPos; import com.gtnewhorizons.angelica.utils.AnimationsRenderUtils; import lombok.Getter; @@ -265,8 +265,8 @@ private double getCenterZ() { return this.getOriginZ() + 8.0D; } - public BlockPos getRenderOrigin() { - return new BlockPos(this.getRenderX(), this.getRenderY(), this.getRenderZ()); + public BlockPosImpl getRenderOrigin() { + return new BlockPosImpl(this.getRenderX(), this.getRenderY(), this.getRenderZ()); } public void setGraphicsState(BlockRenderPass pass, T state) { diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/cull/graph/ChunkGraphCuller.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/cull/graph/ChunkGraphCuller.java index ad8c891d6..0fbdef2b3 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/cull/graph/ChunkGraphCuller.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/cull/graph/ChunkGraphCuller.java @@ -1,6 +1,6 @@ package me.jellysquid.mods.sodium.client.render.chunk.cull.graph; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; import com.gtnewhorizons.angelica.compat.mojang.Camera; import com.gtnewhorizons.angelica.compat.mojang.ChunkOcclusionData; import com.gtnewhorizons.angelica.compat.mojang.ChunkSectionPos; @@ -77,7 +77,7 @@ private void initSearch(Camera camera, FrustumExtended frustum, int frame, boole this.visible.clear(); - BlockPos origin = camera.getBlockPos(); + BlockPosImpl origin = camera.getBlockPos(); int chunkX = origin.getX() >> 4; int chunkY = origin.getY() >> 4; diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/cull/graph/ChunkGraphNode.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/cull/graph/ChunkGraphNode.java index 688898e9b..a2f5bdbfd 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/cull/graph/ChunkGraphNode.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/cull/graph/ChunkGraphNode.java @@ -1,6 +1,6 @@ package me.jellysquid.mods.sodium.client.render.chunk.cull.graph; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; import com.gtnewhorizons.angelica.compat.mojang.ChunkOcclusionData; import me.jellysquid.mods.sodium.client.render.chunk.data.ChunkRenderData; import me.jellysquid.mods.sodium.client.util.math.FrustumExtended; @@ -146,7 +146,7 @@ public int getOriginZ() { * @return The squared distance from the center of this chunk in the world to the center of the block position * given by {@param pos} */ - public double getSquaredDistance(BlockPos pos) { + public double getSquaredDistance(BlockPosImpl pos) { return this.getSquaredDistance(pos.x + 0.5D, pos.y + 0.5D, pos.z + 0.5D); } diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/tasks/ChunkRenderRebuildTask.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/tasks/ChunkRenderRebuildTask.java index 8f68f6dbf..a2538a746 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/tasks/ChunkRenderRebuildTask.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/tasks/ChunkRenderRebuildTask.java @@ -1,6 +1,6 @@ package me.jellysquid.mods.sodium.client.render.chunk.tasks; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; import com.gtnewhorizons.angelica.compat.mojang.ChunkOcclusionDataBuilder; import com.gtnewhorizons.angelica.config.AngelicaConfig; import com.gtnewhorizons.angelica.mixins.interfaces.ITexturesCache; @@ -48,7 +48,7 @@ public class ChunkRenderRebuildTask extends ChunkRenderBuildTask { private final ChunkRenderContainer render; - private final BlockPos offset; + private final BlockPosImpl offset; private final ChunkRenderContext context; @@ -56,7 +56,7 @@ public class ChunkRenderRebuildTask extends ChunkR private final boolean translucencySorting; - public ChunkRenderRebuildTask(ChunkRenderContainer render, ChunkRenderContext context, BlockPos offset) { + public ChunkRenderRebuildTask(ChunkRenderContainer render, ChunkRenderContext context, BlockPosImpl offset) { this.render = render; this.offset = offset; this.context = context; @@ -121,8 +121,8 @@ public ChunkBuildResult performBuild(ChunkRenderCacheLocal cache, ChunkBuildB final int baseY = this.render.getOriginY(); final int baseZ = this.render.getOriginZ(); - final BlockPos pos = new BlockPos(); - final BlockPos renderOffset = this.offset; + final BlockPosImpl pos = new BlockPosImpl(); + final BlockPosImpl renderOffset = this.offset; final LongArrayFIFOQueue mainThreadBlocks = new LongArrayFIFOQueue(); boolean hasMainThreadBlocks = false; @@ -240,11 +240,11 @@ public ChunkBuildResult performBuild(ChunkRenderCacheLocal cache, ChunkBuildB */ private void performMainBuild(ChunkRenderCacheLocal cache, ChunkBuildBuffers buffers, CancellationSource cancellationSource, ChunkRenderBounds.Builder bounds, ChunkRenderData.Builder renderData, LongArrayFIFOQueue mainThreadBlocks) { final WorldSlice slice = cache.getWorldSlice(); - final BlockPos pos = new BlockPos(); + final BlockPosImpl pos = new BlockPosImpl(); final int baseX = this.render.getOriginX(); final int baseY = this.render.getOriginY(); final int baseZ = this.render.getOriginZ(); - final BlockPos renderOffset = this.offset; + final BlockPosImpl renderOffset = this.offset; final RenderBlocks rb = new RenderBlocks(slice.getWorld()); while(!mainThreadBlocks.isEmpty()) { final long longPos = mainThreadBlocks.dequeueLong(); diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/tasks/ChunkRenderTranslucencySortTask.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/tasks/ChunkRenderTranslucencySortTask.java index a98c4b0bd..6a959af3c 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/tasks/ChunkRenderTranslucencySortTask.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/tasks/ChunkRenderTranslucencySortTask.java @@ -1,6 +1,6 @@ package me.jellysquid.mods.sodium.client.render.chunk.tasks; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; import me.jellysquid.mods.sodium.client.gl.buffer.VertexData; import me.jellysquid.mods.sodium.client.gl.util.BufferSlice; import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFacing; @@ -32,10 +32,10 @@ public class ChunkRenderTranslucencySortTask exten private static final BlockRenderPass[] NO_PASSES = new BlockRenderPass[0]; private final ChunkRenderContainer render; - private final BlockPos offset; + private final BlockPosImpl offset; private final Vector3d camera; - public ChunkRenderTranslucencySortTask(ChunkRenderContainer render, BlockPos offset, Vector3d camera) { + public ChunkRenderTranslucencySortTask(ChunkRenderContainer render, BlockPosImpl offset, Vector3d camera) { this.render = render; this.offset = offset; this.camera = camera; diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/entity/EntityLightSampler.java b/src/main/java/me/jellysquid/mods/sodium/client/render/entity/EntityLightSampler.java index afad9c830..7549c1e62 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/entity/EntityLightSampler.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/entity/EntityLightSampler.java @@ -1,10 +1,10 @@ package me.jellysquid.mods.sodium.client.render.entity; import net.minecraft.entity.Entity; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; public interface EntityLightSampler { - int bridge$getBlockLight(T entity, BlockPos pos); + int bridge$getBlockLight(T entity, BlockPosImpl pos); - int bridge$getSkyLight(T entity, BlockPos pos); + int bridge$getSkyLight(T entity, BlockPosImpl pos); } diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/occlusion/BlockOcclusionCache.java b/src/main/java/me/jellysquid/mods/sodium/client/render/occlusion/BlockOcclusionCache.java index 32fe42d8d..dc30536c1 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/occlusion/BlockOcclusionCache.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/occlusion/BlockOcclusionCache.java @@ -1,6 +1,6 @@ package me.jellysquid.mods.sodium.client.render.occlusion; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; import it.unimi.dsi.fastutil.objects.Object2ByteLinkedOpenHashMap; import net.minecraft.block.Block; import net.minecraft.world.IBlockAccess; @@ -11,7 +11,7 @@ public class BlockOcclusionCache { private final Object2ByteLinkedOpenHashMap map; private final CachedOcclusionShapeTest cachedTest = new CachedOcclusionShapeTest(); - private final BlockPos cpos = new BlockPos(); + private final BlockPosImpl cpos = new BlockPosImpl(); public BlockOcclusionCache() { this.map = new Object2ByteLinkedOpenHashMap<>(2048, 0.5F); @@ -26,11 +26,11 @@ public BlockOcclusionCache() { * @param facing The facing direction of the side to check * @return True if the block side facing {@param dir} is not occluded, otherwise false */ - public boolean shouldDrawSide(Block block, int meta, IBlockAccess view, BlockPos pos, ForgeDirection facing) { + public boolean shouldDrawSide(Block block, int meta, IBlockAccess view, BlockPosImpl pos, ForgeDirection facing) { if (facing == ForgeDirection.UNKNOWN) return true; - BlockPos adjPos = this.cpos; + BlockPosImpl adjPos = this.cpos; adjPos.set(pos.getX() + facing.offsetX, pos.getY() + facing.offsetY, pos.getZ() + facing.offsetZ); Block adjState = view.getBlock(adjPos.x, adjPos.y, adjPos.z); diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/pipeline/BlockRenderer.java b/src/main/java/me/jellysquid/mods/sodium/client/render/pipeline/BlockRenderer.java index b5c498130..4aa493468 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/pipeline/BlockRenderer.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/pipeline/BlockRenderer.java @@ -1,9 +1,10 @@ package me.jellysquid.mods.sodium.client.render.pipeline; import com.gtnewhorizons.angelica.api.QuadProvider; +import com.gtnewhorizons.angelica.api.QuadView; import com.gtnewhorizons.angelica.client.renderer.CapturingTessellator; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; -import com.gtnewhorizons.angelica.compat.nd.Quad; +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; +import me.jellysquid.mods.sodium.client.model.quad.Quad; import com.gtnewhorizons.angelica.config.AngelicaConfig; import com.gtnewhorizons.angelica.glsm.TessellatorManager; import com.gtnewhorizons.angelica.utils.ObjectPooler; @@ -43,7 +44,7 @@ public class BlockRenderer { private final LightPipelineProvider lighters; private final BlockOcclusionCache occlusionCache; - private final ObjectPooler quadPool = new ObjectPooler<>(Quad::new); + private final ObjectPooler quadPool = new ObjectPooler<>(Quad::new); // TODO: Use modern model API, and store them here @@ -54,7 +55,7 @@ public BlockRenderer(LightPipelineProvider lighters) { this.occlusionCache = new BlockOcclusionCache(); } - public boolean renderModel(IBlockAccess world, RenderBlocks renderBlocks, Block block, int meta, BlockPos pos, ChunkModelBuffers buffers, boolean cull, long seed) { + public boolean renderModel(IBlockAccess world, RenderBlocks renderBlocks, Block block, int meta, BlockPosImpl pos, ChunkModelBuffers buffers, boolean cull, long seed) { final LightMode mode = this.getLightingMode(block); final LightPipeline lighter = this.lighters.getLighter(mode); @@ -69,18 +70,18 @@ public boolean renderModel(IBlockAccess world, RenderBlocks renderBlocks, Block for (ForgeDirection dir : ForgeDirection.values()) { this.random.setSeed(seed); - List quads = null; + List quads; if (!cull || this.occlusionCache.shouldDrawSide(block, meta, world, pos, dir)) { - quads = qBlock.getQuads(world, pos, block, meta, dir, random, color, this.quadPool); + quads = qBlock.getQuads(world, pos, block, meta, dir, random, color, this.quadPool::getInstance); if (quads.isEmpty()) continue; this.renderQuadList(pos, lighter, buffers, quads, ModelQuadFacing.fromDirection(dir), true); rendered = true; - } - if (quads != null) - for (Quad q : quads) this.quadPool.releaseInstance(q); + if (qBlock.isDynamic()) + for (QuadView q : quads) this.quadPool.releaseInstance(q); + } } } else { @@ -92,7 +93,7 @@ public boolean renderModel(IBlockAccess world, RenderBlocks renderBlocks, Block tess.setOffset(pos); renderBlocks.renderBlockByRenderType(block, pos.x, pos.y, pos.z); - final List quads = TessellatorManager.stopCapturingToPooledQuads(); + final List quads = TessellatorManager.stopCapturingToPooledQuads(); tess.resetOffset(); for (ModelQuadFacing facing : ModelQuadFacing.VALUES) { @@ -109,7 +110,7 @@ public boolean renderModel(IBlockAccess world, RenderBlocks renderBlocks, Block return rendered; } - private void renderQuadList(BlockPos pos, LightPipeline lighter, ChunkModelBuffers buffers, List quads, ModelQuadFacing facing, boolean useSodiumLight) { + private void renderQuadList(BlockPosImpl pos, LightPipeline lighter, ChunkModelBuffers buffers, List quads, ModelQuadFacing facing, boolean useSodiumLight) { final ForgeDirection cullFace = ModelQuadFacing.toDirection(facing); final ModelVertexSink sink = buffers.getSink(facing); @@ -120,7 +121,7 @@ private void renderQuadList(BlockPos pos, LightPipeline lighter, ChunkModelBuffe // This is a very hot allocation, iterate over it manually // noinspection ForLoopReplaceableByForEach for (int i = 0, quadsSize = quads.size(); i < quadsSize; i++) { - final Quad quad = quads.get(i); + final QuadView quad = quads.get(i); // If we aren't using sodium light (i.e. it's the CapturingTesselator) // manually filter quads by side @@ -138,7 +139,7 @@ private void renderQuadList(BlockPos pos, LightPipeline lighter, ChunkModelBuffe sink.flush(); } - private void renderQuad(ModelVertexSink sink, Quad quad, QuadLightData light, ChunkRenderData.Builder renderData, boolean useSodiumLight) { + private void renderQuad(ModelVertexSink sink, QuadView quad, QuadLightData light, ChunkRenderData.Builder renderData, boolean useSodiumLight) { final ModelQuadOrientation order = (useSodiumLight || this.useSeparateAo) ? ModelQuadOrientation.orient(light.br) : ModelQuadOrientation.NORMAL; diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/pipeline/FluidRenderer.java b/src/main/java/me/jellysquid/mods/sodium/client/render/pipeline/FluidRenderer.java index 111415ca7..c55770b73 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/pipeline/FluidRenderer.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/pipeline/FluidRenderer.java @@ -1,6 +1,6 @@ package me.jellysquid.mods.sodium.client.render.pipeline; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; import com.gtnewhorizons.angelica.config.AngelicaConfig; import me.jellysquid.mods.sodium.client.model.light.LightMode; import me.jellysquid.mods.sodium.client.model.light.LightPipeline; @@ -38,7 +38,7 @@ public class FluidRenderer { private static final float EPSILON = 0.001f; private final LightPipelineProvider lpp; - private final BlockPos.Mutable scratchPos = new BlockPos.Mutable(); + private final BlockPosImpl scratchPos = new BlockPosImpl(); private final ModelQuadViewMutable quad = new ModelQuad(); @@ -69,7 +69,7 @@ private boolean isFluidOccluded(IBlockAccess world, int x, int y, int z, ForgeDi } private boolean isSideExposed(IBlockAccess world, int x, int y, int z, ForgeDirection dir, float height) { - BlockPos pos = this.scratchPos.set(x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ); + BlockPosImpl pos = this.scratchPos.set(x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ); Block block = world.getBlock(pos.x, pos.y, pos.z); if (block.getMaterial().isOpaque()) { @@ -87,7 +87,7 @@ private boolean isSideExposed(IBlockAccess world, int x, int y, int z, ForgeDire return true; } - public boolean render(IBlockAccess world, WorldSlice slice, Block block, BlockPos pos, ChunkModelBuffers buffers) { + public boolean render(IBlockAccess world, WorldSlice slice, Block block, BlockPosImpl pos, ChunkModelBuffers buffers) { this.useSeparateAo = AngelicaConfig.enableIris && BlockRenderingSettings.INSTANCE.shouldUseSeparateAo(); int posX = pos.x; @@ -349,7 +349,7 @@ public boolean render(IBlockAccess world, WorldSlice slice, Block block, BlockPo return rendered; } - private void calculateQuadColors(ModelQuadView quad, BlockPos pos, LightPipeline lighter, ForgeDirection dir, float brightness, boolean colorized, WorldSlice slice) { + private void calculateQuadColors(ModelQuadView quad, BlockPosImpl pos, LightPipeline lighter, ForgeDirection dir, float brightness, boolean colorized, WorldSlice slice) { QuadLightData light = this.quadLightData; lighter.calculate(quad, pos, light, null, dir, false); @@ -437,7 +437,7 @@ private float getCornerHeight(IBlockAccess world, int x, int y, int z, Fluid flu return 1.0F; } - BlockPos pos = this.scratchPos.set(x2, y, z2); + BlockPosImpl pos = this.scratchPos.set(x2, y, z2); block = world.getBlock(pos.x, pos.y, pos.z); int meta = world.getBlockMetadata(pos.x, pos.y, pos.z); diff --git a/src/main/java/me/jellysquid/mods/sodium/client/world/cloned/ClonedChunkSection.java b/src/main/java/me/jellysquid/mods/sodium/client/world/cloned/ClonedChunkSection.java index 209735442..533628c55 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/world/cloned/ClonedChunkSection.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/world/cloned/ClonedChunkSection.java @@ -3,7 +3,6 @@ import com.falsepattern.endlessids.mixin.helpers.ChunkBiomeHook; import com.gtnewhorizons.angelica.compat.ExtendedBlockStorageExt; import com.gtnewhorizons.angelica.compat.ModStatus; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; import com.gtnewhorizons.angelica.compat.mojang.ChunkSectionPos; import it.unimi.dsi.fastutil.shorts.Short2ObjectMap; import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap; diff --git a/src/main/java/me/jellysquid/mods/sodium/common/util/WorldUtil.java b/src/main/java/me/jellysquid/mods/sodium/common/util/WorldUtil.java index f7ce2e49b..9d2d81d3f 100644 --- a/src/main/java/me/jellysquid/mods/sodium/common/util/WorldUtil.java +++ b/src/main/java/me/jellysquid/mods/sodium/common/util/WorldUtil.java @@ -1,6 +1,6 @@ package me.jellysquid.mods.sodium.common.util; -import com.gtnewhorizons.angelica.compat.mojang.BlockPos; +import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl; import net.minecraft.block.Block; import net.minecraft.block.BlockLiquid; import net.minecraft.block.material.Material; @@ -70,7 +70,7 @@ public static Vector3d getVelocity(IBlockAccess world, int x, int y, int z, Bloc * Returns true if any block in a 3x3x3 cube is not the same fluid and not an opaque full cube. * Equivalent to FluidState::method_15756 in modern. */ - public static boolean method_15756(IBlockAccess world, BlockPos pos, Fluid fluid) { + public static boolean method_15756(IBlockAccess world, BlockPosImpl pos, Fluid fluid) { for (int i = 0; i < 2; ++i) { for (int j = 0; j < 2; ++j) { Block block = world.getBlock(pos.x, pos.y, pos.z); @@ -126,7 +126,7 @@ public static boolean isEmptyOrSame(Fluid fluid, Fluid otherFluid) { /** * Equivalent to method_15749 in 1.16.5 */ - public static boolean method_15749(IBlockAccess world, Fluid thiz, BlockPos pos, ForgeDirection dir) { + public static boolean method_15749(IBlockAccess world, Fluid thiz, BlockPosImpl pos, ForgeDirection dir) { Block b = world.getBlock(pos.x, pos.y, pos.z); Fluid f = getFluid(b); if (f == thiz) {