From 7b25a3130bd9a21de23122a057f3fcb8edb4031d Mon Sep 17 00:00:00 2001 From: douira Date: Mon, 12 Aug 2024 16:55:22 +0200 Subject: [PATCH] Fix partition tree sorting on geometry with negative dot products and some refactors (#2655) * Remove vertex range because the vertex offset is never used, instead use integers and/or integer arrays. * Refactor use of default terrain render passes and material to use `#isTranslucent() instead of enum equality. * Fix partition algorithm interval encoding by using floatToComparableInt and generally fix floatToComparableInt to actually function correctly. * Remove use of -1 as null-like vertex count, refactor translucent data objects to just deal with vertex counts instead of the mesh object. --- .../sodium/client/gl/util/VertexRange.java | 4 -- .../render/chunk/DefaultChunkRenderer.java | 7 ++-- .../chunk/compile/ChunkBuildBuffers.java | 19 +++++----- .../compile/buffers/ChunkVertexConsumer.java | 34 ++++++++--------- .../chunk/compile/pipeline/BlockRenderer.java | 6 +-- .../tasks/ChunkBuilderMeshingTask.java | 9 ++--- .../chunk/data/BuiltSectionMeshParts.java | 11 +++--- .../chunk/data/SectionRenderDataStorage.java | 12 +----- .../render/chunk/region/RenderRegion.java | 2 +- .../chunk/region/RenderRegionManager.java | 2 +- .../TranslucentGeometryCollector.java | 38 +++++++++++++------ .../bsp_tree/InnerPartitionBSPNode.java | 9 ++++- .../data/AnyOrderData.java | 20 ++++------ .../data/DynamicBSPData.java | 11 ++---- .../translucent_sorting/data/DynamicData.java | 5 +-- .../data/DynamicTopoData.java | 10 ++--- .../data/MixedDirectionData.java | 12 +++--- .../data/PresentTranslucentData.java | 3 +- .../data/SplitDirectionData.java | 12 +++--- .../data/StaticNormalRelativeData.java | 35 +++++++---------- .../data/StaticTopoData.java | 10 ++--- .../data/TranslucentData.java | 14 ------- .../mods/sodium/client/util/MathUtil.java | 16 ++++---- 23 files changed, 132 insertions(+), 169 deletions(-) delete mode 100644 common/src/main/java/net/caffeinemc/mods/sodium/client/gl/util/VertexRange.java diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/util/VertexRange.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/util/VertexRange.java deleted file mode 100644 index 1520a6b6aa..0000000000 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/util/VertexRange.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.caffeinemc.mods.sodium.client.gl.util; - -public record VertexRange(int vertexStart, int vertexCount) { -} diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/DefaultChunkRenderer.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/DefaultChunkRenderer.java index a343f79a7f..51d630203b 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/DefaultChunkRenderer.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/DefaultChunkRenderer.java @@ -13,12 +13,11 @@ import net.caffeinemc.mods.sodium.client.model.quad.properties.ModelQuadFacing; import net.caffeinemc.mods.sodium.client.render.chunk.data.SectionRenderDataStorage; import net.caffeinemc.mods.sodium.client.render.chunk.data.SectionRenderDataUnsafe; -import net.caffeinemc.mods.sodium.client.render.chunk.lists.ChunkRenderListIterable; import net.caffeinemc.mods.sodium.client.render.chunk.lists.ChunkRenderList; +import net.caffeinemc.mods.sodium.client.render.chunk.lists.ChunkRenderListIterable; import net.caffeinemc.mods.sodium.client.render.chunk.region.RenderRegion; import net.caffeinemc.mods.sodium.client.render.chunk.shader.ChunkShaderBindingPoints; import net.caffeinemc.mods.sodium.client.render.chunk.shader.ChunkShaderInterface; -import net.caffeinemc.mods.sodium.client.render.chunk.terrain.DefaultTerrainRenderPasses; import net.caffeinemc.mods.sodium.client.render.chunk.terrain.TerrainRenderPass; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.SortBehavior; import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.ChunkMeshAttribute; @@ -26,6 +25,7 @@ import net.caffeinemc.mods.sodium.client.render.viewport.CameraTransform; import net.caffeinemc.mods.sodium.client.util.BitwiseMath; import org.lwjgl.system.MemoryUtil; + import java.util.Iterator; public class DefaultChunkRenderer extends ShaderChunkRenderer { @@ -100,8 +100,7 @@ public void render(ChunkRenderMatrices matrices, } private static boolean isTranslucentRenderPass(TerrainRenderPass renderPass) { - return renderPass == DefaultTerrainRenderPasses.TRANSLUCENT - && SodiumClientMod.options().performance.getSortBehavior() != SortBehavior.OFF; + return renderPass.isTranslucent() && SodiumClientMod.options().performance.getSortBehavior() != SortBehavior.OFF; } private static void fillCommandBuffer(MultiDrawBatch batch, diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/ChunkBuildBuffers.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/ChunkBuildBuffers.java index 9983b9ed6c..d506ba3237 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/ChunkBuildBuffers.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/ChunkBuildBuffers.java @@ -1,7 +1,6 @@ package net.caffeinemc.mods.sodium.client.render.chunk.compile; import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; -import net.caffeinemc.mods.sodium.client.gl.util.VertexRange; import net.caffeinemc.mods.sodium.client.model.quad.properties.ModelQuadFacing; import net.caffeinemc.mods.sodium.client.render.chunk.compile.buffers.BakedChunkModelBuilder; import net.caffeinemc.mods.sodium.client.render.chunk.compile.buffers.ChunkModelBuilder; @@ -61,11 +60,12 @@ public BuiltSectionMeshParts createMesh(TerrainRenderPass pass, boolean forceUna var builder = this.builders.get(pass); List vertexBuffers = new ArrayList<>(); - VertexRange[] vertexRanges = new VertexRange[ModelQuadFacing.COUNT]; + int[] vertexCounts = new int[ModelQuadFacing.COUNT]; - int vertexCount = 0; + int vertexSum = 0; for (ModelQuadFacing facing : ModelQuadFacing.VALUES) { + var ordinal = facing.ordinal(); var buffer = builder.getVertexBuffer(facing); if (buffer.isEmpty()) { @@ -73,29 +73,30 @@ public BuiltSectionMeshParts createMesh(TerrainRenderPass pass, boolean forceUna } vertexBuffers.add(buffer.slice()); + var bufferCount = buffer.count(); if (!forceUnassigned) { - vertexRanges[facing.ordinal()] = new VertexRange(vertexCount, buffer.count()); + vertexCounts[ordinal] = bufferCount; } - vertexCount += buffer.count(); + vertexSum += bufferCount; } - if (vertexCount == 0) { + if (vertexSum == 0) { return null; } if (forceUnassigned) { - vertexRanges[ModelQuadFacing.UNASSIGNED.ordinal()] = new VertexRange(0, vertexCount); + vertexCounts[ModelQuadFacing.UNASSIGNED.ordinal()] = vertexSum; } - var mergedBuffer = new NativeBuffer(vertexCount * this.vertexType.getVertexFormat().getStride()); + var mergedBuffer = new NativeBuffer(vertexSum * this.vertexType.getVertexFormat().getStride()); var mergedBufferBuilder = mergedBuffer.getDirectBuffer(); for (var buffer : vertexBuffers) { mergedBufferBuilder.put(buffer); } - return new BuiltSectionMeshParts(mergedBuffer, vertexRanges); + return new BuiltSectionMeshParts(mergedBuffer, vertexCounts); } public void destroy() { diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/ChunkVertexConsumer.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/ChunkVertexConsumer.java index 39fd9d8a21..e5d449f8c4 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/ChunkVertexConsumer.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/ChunkVertexConsumer.java @@ -1,17 +1,15 @@ package net.caffeinemc.mods.sodium.client.render.chunk.compile.buffers; import com.mojang.blaze3d.vertex.VertexConsumer; +import net.caffeinemc.mods.sodium.api.util.ColorABGR; +import net.caffeinemc.mods.sodium.api.util.ColorARGB; import net.caffeinemc.mods.sodium.api.util.NormI8; import net.caffeinemc.mods.sodium.client.model.quad.properties.ModelQuadFacing; -import net.caffeinemc.mods.sodium.client.render.chunk.terrain.material.DefaultMaterials; import net.caffeinemc.mods.sodium.client.render.chunk.terrain.material.Material; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.TranslucentGeometryCollector; import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.ChunkVertexEncoder; -import net.caffeinemc.mods.sodium.api.util.ColorABGR; -import net.caffeinemc.mods.sodium.api.util.ColorARGB; import net.caffeinemc.mods.sodium.client.render.texture.SpriteFinderCache; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.core.Direction; import org.jetbrains.annotations.NotNull; public class ChunkVertexConsumer implements VertexConsumer { @@ -129,8 +127,8 @@ public VertexConsumer potentiallyEndVertex() { ModelQuadFacing cullFace = ModelQuadFacing.fromPackedNormal(normal); - if (material == DefaultMaterials.TRANSLUCENT && collector != null) { - collector.appendQuad(normal, vertices, cullFace); + if (this.material.isTranslucent() && this.collector != null) { + this.collector.appendQuad(normal, this.vertices, cullFace); } this.modelBuilder.getVertexBuffer(cullFace).push(this.vertices, this.material); @@ -156,21 +154,21 @@ public VertexConsumer potentiallyEndVertex() { } private int calculateNormal() { - final float x0 = vertices[0].x; - final float y0 = vertices[0].y; - final float z0 = vertices[0].z; + final float x0 = this.vertices[0].x; + final float y0 = this.vertices[0].y; + final float z0 = this.vertices[0].z; - final float x1 = vertices[1].x; - final float y1 = vertices[1].y; - final float z1 = vertices[1].z; + final float x1 = this.vertices[1].x; + final float y1 = this.vertices[1].y; + final float z1 = this.vertices[1].z; - final float x2 = vertices[2].x; - final float y2 = vertices[2].y; - final float z2 = vertices[2].z; + final float x2 = this.vertices[2].x; + final float y2 = this.vertices[2].y; + final float z2 = this.vertices[2].z; - final float x3 = vertices[3].x; - final float y3 = vertices[3].y; - final float z3 = vertices[3].z; + final float x3 = this.vertices[3].x; + final float y3 = this.vertices[3].y; + final float z3 = this.vertices[3].z; final float dx0 = x2 - x0; final float dy0 = y2 - y0; diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java index 3016ad69db..df6851a805 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java @@ -1,5 +1,6 @@ package net.caffeinemc.mods.sodium.client.render.chunk.compile.pipeline; +import net.caffeinemc.mods.sodium.api.util.ColorARGB; import net.caffeinemc.mods.sodium.client.model.color.ColorProvider; import net.caffeinemc.mods.sodium.client.model.color.ColorProviderRegistry; import net.caffeinemc.mods.sodium.client.model.light.LightMode; @@ -20,7 +21,6 @@ import net.caffeinemc.mods.sodium.client.services.PlatformModelAccess; import net.caffeinemc.mods.sodium.client.services.SodiumModelData; import net.caffeinemc.mods.sodium.client.world.LevelSlice; -import net.caffeinemc.mods.sodium.api.util.ColorARGB; import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; import net.fabricmc.fabric.api.renderer.v1.material.ShadeMode; @@ -177,8 +177,8 @@ private void bufferQuad(MutableQuadViewImpl quad, float[] brightnesses, Material ModelQuadFacing normalFace = quad.normalFace(); - if (material == DefaultMaterials.TRANSLUCENT && collector != null) { - collector.appendQuad(quad.getFaceNormal(), vertices, normalFace); + if (material.isTranslucent() && this.collector != null) { + this.collector.appendQuad(quad.getFaceNormal(), vertices, normalFace); } ChunkMeshBufferBuilder vertexBuffer = modelBuilder.getVertexBuffer(normalFace); diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/tasks/ChunkBuilderMeshingTask.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/tasks/ChunkBuilderMeshingTask.java index ac36bd9841..6a523f90c9 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/tasks/ChunkBuilderMeshingTask.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/tasks/ChunkBuilderMeshingTask.java @@ -8,7 +8,6 @@ import net.caffeinemc.mods.sodium.client.render.chunk.compile.ChunkBuildOutput; import net.caffeinemc.mods.sodium.client.render.chunk.compile.executor.ChunkBuilder; import net.caffeinemc.mods.sodium.client.render.chunk.compile.pipeline.BlockRenderCache; -import net.caffeinemc.mods.sodium.client.render.chunk.compile.pipeline.BlockRenderContext; import net.caffeinemc.mods.sodium.client.render.chunk.compile.pipeline.BlockRenderer; import net.caffeinemc.mods.sodium.client.render.chunk.data.BuiltSectionInfo; import net.caffeinemc.mods.sodium.client.render.chunk.data.BuiltSectionMeshParts; @@ -20,7 +19,6 @@ import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.TranslucentGeometryCollector; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.data.PresentTranslucentData; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.data.TranslucentData; -import net.caffeinemc.mods.sodium.client.services.PlatformLevelAccess; import net.caffeinemc.mods.sodium.client.services.PlatformLevelRenderHooks; import net.caffeinemc.mods.sodium.client.util.task.CancellationToken; import net.caffeinemc.mods.sodium.client.world.LevelSlice; @@ -37,10 +35,10 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.FluidState; -import java.util.Map; - import org.joml.Vector3dc; +import java.util.Map; + /** * Rebuilds all the meshes of a chunk for each given render pass with non-occluded blocks. The result is then uploaded * to graphics memory on the main thread. @@ -160,8 +158,7 @@ public ChunkBuildOutput execute(ChunkBuildContext buildContext, CancellationToke for (TerrainRenderPass pass : DefaultTerrainRenderPasses.ALL) { // consolidate all translucent geometry into UNASSIGNED so that it's rendered // all together if it needs to share an index buffer between the directions - boolean isTranslucent = pass == DefaultTerrainRenderPasses.TRANSLUCENT; - BuiltSectionMeshParts mesh = buffers.createMesh(pass, isTranslucent && sortType.needsDirectionMixing); + BuiltSectionMeshParts mesh = buffers.createMesh(pass, pass.isTranslucent() && sortType.needsDirectionMixing); if (mesh != null) { meshes.put(pass, mesh); diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/data/BuiltSectionMeshParts.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/data/BuiltSectionMeshParts.java index c57e49964b..ec250afb86 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/data/BuiltSectionMeshParts.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/data/BuiltSectionMeshParts.java @@ -1,14 +1,13 @@ package net.caffeinemc.mods.sodium.client.render.chunk.data; -import net.caffeinemc.mods.sodium.client.gl.util.VertexRange; import net.caffeinemc.mods.sodium.client.util.NativeBuffer; public class BuiltSectionMeshParts { - private final VertexRange[] ranges; + private final int[] vertexCounts; private final NativeBuffer buffer; - public BuiltSectionMeshParts(NativeBuffer buffer, VertexRange[] ranges) { - this.ranges = ranges; + public BuiltSectionMeshParts(NativeBuffer buffer, int[] vertexCounts) { + this.vertexCounts = vertexCounts; this.buffer = buffer; } @@ -16,7 +15,7 @@ public NativeBuffer getVertexData() { return this.buffer; } - public VertexRange[] getVertexRanges() { - return this.ranges; + public int[] getVertexCounts() { + return this.vertexCounts; } } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/data/SectionRenderDataStorage.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/data/SectionRenderDataStorage.java index e677e36803..87f9998284 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/data/SectionRenderDataStorage.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/data/SectionRenderDataStorage.java @@ -1,7 +1,6 @@ package net.caffeinemc.mods.sodium.client.render.chunk.data; import net.caffeinemc.mods.sodium.client.gl.arena.GlBufferSegment; -import net.caffeinemc.mods.sodium.client.gl.util.VertexRange; import net.caffeinemc.mods.sodium.client.model.quad.properties.ModelQuadFacing; import net.caffeinemc.mods.sodium.client.render.chunk.region.RenderRegion; import org.jetbrains.annotations.NotNull; @@ -47,7 +46,7 @@ public SectionRenderDataStorage(boolean storesIndices) { } public void setVertexData(int localSectionIndex, - GlBufferSegment allocation, VertexRange[] ranges) { + GlBufferSegment allocation, int[] vertexCounts) { GlBufferSegment prev = this.vertexAllocations[localSectionIndex]; if (prev != null) { @@ -62,14 +61,7 @@ public void setVertexData(int localSectionIndex, int vertexOffset = allocation.getOffset(); for (int facingIndex = 0; facingIndex < ModelQuadFacing.COUNT; facingIndex++) { - VertexRange vertexRange = ranges[facingIndex]; - int vertexCount; - - if (vertexRange != null) { - vertexCount = vertexRange.vertexCount(); - } else { - vertexCount = 0; - } + int vertexCount = vertexCounts[facingIndex]; SectionRenderDataUnsafe.setVertexOffset(pMeshData, facingIndex, vertexOffset); SectionRenderDataUnsafe.setElementCount(pMeshData, facingIndex, (vertexCount >> 2) * 6); diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/region/RenderRegion.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/region/RenderRegion.java index b02b9acfe9..df6df676d4 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/region/RenderRegion.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/region/RenderRegion.java @@ -115,7 +115,7 @@ public SectionRenderDataStorage createStorage(TerrainRenderPass pass) { var storage = this.sectionRenderData.get(pass); if (storage == null) { - storage = new SectionRenderDataStorage(pass == DefaultTerrainRenderPasses.TRANSLUCENT); + storage = new SectionRenderDataStorage(pass.isTranslucent()); this.sectionRenderData.put(pass, storage); } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/region/RenderRegionManager.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/region/RenderRegionManager.java index 6bf8bb8810..71665e93a2 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/region/RenderRegionManager.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/region/RenderRegionManager.java @@ -124,7 +124,7 @@ private void uploadResults(CommandList commandList, RenderRegion region, Collect for (PendingSectionMeshUpload upload : uploads) { var storage = region.createStorage(upload.pass); storage.setVertexData(upload.section.getSectionIndex(), - upload.vertexUpload.getResult(), upload.meshData.getVertexRanges()); + upload.vertexUpload.getResult(), upload.meshData.getVertexCounts()); } } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/TranslucentGeometryCollector.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/TranslucentGeometryCollector.java index bbca024756..6edd1314e7 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/TranslucentGeometryCollector.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/TranslucentGeometryCollector.java @@ -35,8 +35,8 @@ * type is determined with a heuristic based on the collected metrics. This * determines if block face culling can be enabled. * - Now the {@link BuiltSectionMeshParts} is generated, which yields the vertex - * ranges. - * 3. The vertex ranges and the mesh parts object are used by the collector in + * counts. + * 3. The vertex counts and the mesh parts object are used by the collector in * the construction of the {@link TranslucentData} object. The data object * allocates memory for the index data and performs the first (and for static * sort types, only) sort. @@ -319,7 +319,7 @@ private static SortType filterSortType(SortType sortType) { * @return the required sort type to ensure this section always looks correct */ private SortType sortTypeHeuristic() { - if (this.quads.length == 0) { + if (this.quads.length <= 1) { return SortType.NONE; } @@ -461,21 +461,32 @@ public SortType finishRendering() { return this.sortType; } - private TranslucentData makeNewTranslucentData(BuiltSectionMeshParts translucentMesh, CombinedCameraPos cameraPos, + private static int ensureUnassignedVertexCount(int[] vertexCounts) { + int vertexCount = vertexCounts[ModelQuadFacing.UNASSIGNED.ordinal()]; + + if (vertexCount == 0) { + throw new IllegalStateException("No unassigned data in mesh"); + } + + return vertexCount; + } + + private TranslucentData makeNewTranslucentData(int[] vertexCounts, CombinedCameraPos cameraPos, TranslucentData oldData) { if (this.sortType == SortType.NONE) { - return AnyOrderData.fromMesh(translucentMesh, this.quads, this.sectionPos); + return AnyOrderData.fromMesh(vertexCounts, this.quads, this.sectionPos); } if (this.sortType == SortType.STATIC_NORMAL_RELATIVE) { var isDoubleUnaligned = this.alignedFacingBitmap == 0; - return StaticNormalRelativeData.fromMesh(translucentMesh, this.quads, this.sectionPos, isDoubleUnaligned); + return StaticNormalRelativeData.fromMesh(vertexCounts, this.quads, this.sectionPos, isDoubleUnaligned); } // from this point on we know the estimated sort type requires direction mixing // (no backface culling) and all vertices are in the UNASSIGNED direction. if (this.sortType == SortType.STATIC_TOPO) { - var result = StaticTopoData.fromMesh(translucentMesh, this.quads, this.sectionPos); + var vertexCount = ensureUnassignedVertexCount(vertexCounts); + var result = StaticTopoData.fromMesh(vertexCount, this.quads, this.sectionPos); if (result != null) { return result; } @@ -486,17 +497,18 @@ private TranslucentData makeNewTranslucentData(BuiltSectionMeshParts translucent this.sortType = filterSortType(this.sortType); if (this.sortType == SortType.NONE) { - return AnyOrderData.fromMesh(translucentMesh, this.quads, this.sectionPos); + return AnyOrderData.fromMesh(vertexCounts, this.quads, this.sectionPos); } if (this.sortType == SortType.DYNAMIC) { + var vertexCount = ensureUnassignedVertexCount(vertexCounts); try { return DynamicBSPData.fromMesh( - translucentMesh, cameraPos, this.quads, this.sectionPos, oldData); + vertexCount, cameraPos, this.quads, this.sectionPos, oldData); } catch (BSPBuildFailureException e) { var geometryPlanes = GeometryPlanes.fromQuadLists(this.sectionPos, this.quads); return DynamicTopoData.fromMesh( - translucentMesh, cameraPos, this.quads, this.sectionPos, + vertexCount, cameraPos, this.quads, this.sectionPos, geometryPlanes); } } @@ -524,6 +536,8 @@ public TranslucentData getTranslucentData( return NoData.forNoTranslucent(this.sectionPos); } + var vertexCounts = translucentMesh.getVertexCounts(); + // re-use the original translucent data if it's the same. This reduces the // amount of generated and uploaded index data when sections are rebuilt without // relevant changes to translucent geometry. Rebuilds happen when any part of @@ -534,7 +548,7 @@ public TranslucentData getTranslucentData( // doesn't matter if (this.sortType == SortType.NONE && oldData instanceof AnyOrderData oldAnyData && oldAnyData.getQuadCount() == this.quads.length - && Arrays.equals(oldAnyData.getVertexRanges(), translucentMesh.getVertexRanges())) { + && Arrays.equals(oldAnyData.getVertexCounts(), vertexCounts)) { return oldAnyData; } @@ -548,7 +562,7 @@ public TranslucentData getTranslucentData( } } - var newData = makeNewTranslucentData(translucentMesh, cameraPos, oldData); + var newData = makeNewTranslucentData(vertexCounts, cameraPos, oldData); if (newData instanceof PresentTranslucentData presentData) { presentData.setQuadHash(getQuadHash(this.quads)); } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/bsp_tree/InnerPartitionBSPNode.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/bsp_tree/InnerPartitionBSPNode.java index b51d8f3f1e..f56c9a501d 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/bsp_tree/InnerPartitionBSPNode.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/bsp_tree/InnerPartitionBSPNode.java @@ -183,12 +183,17 @@ static InnerPartitionBSPNode attemptNodeReuse(BSPWorkspace workspace, IntArrayLi return oldNode; } + /** + * Encoding with {@link MathUtil#floatToComparableInt(float)} is necessary here to ensure negative distances are not sorted backwards. Simply converting potentially negative floats to int bits using {@link Float#floatToRawIntBits(float)} would sort negative floats backwards amongst themselves. + *

+ * Note that negative floats convert to negative integers with this method which is ok, since it yields an overall negative long that gets sorted correctly before the longs that encode positive floats as distances. + */ private static long encodeIntervalPoint(float distance, int quadIndex, int type) { - return ((long) Float.floatToRawIntBits(distance) << 32) | ((long) type << 30) | quadIndex; + return ((long) MathUtil.floatToComparableInt(distance) << 32) | ((long) type << 30) | quadIndex; } private static float decodeDistance(long encoded) { - return Float.intBitsToFloat((int) (encoded >>> 32)); + return MathUtil.comparableIntToFloat((int) (encoded >>> 32)); } private static int decodeQuadIndex(long encoded) { diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/AnyOrderData.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/AnyOrderData.java index 7f108a8272..34f923ff02 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/AnyOrderData.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/AnyOrderData.java @@ -1,10 +1,7 @@ package net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.data; -import net.caffeinemc.mods.sodium.client.gl.util.VertexRange; -import net.caffeinemc.mods.sodium.client.render.chunk.data.BuiltSectionMeshParts; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.SortType; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.TQuad; -import net.caffeinemc.mods.sodium.client.util.NativeBuffer; import net.minecraft.core.SectionPos; /** @@ -24,8 +21,8 @@ public class AnyOrderData extends SplitDirectionData { private Sorter sorterOnce; - AnyOrderData(SectionPos sectionPos, VertexRange[] ranges, int quadCount) { - super(sectionPos, ranges, quadCount); + AnyOrderData(SectionPos sectionPos, int[] vertexCounts, int quadCount) { + super(sectionPos, vertexCounts, quadCount); } @Override @@ -46,20 +43,19 @@ public Sorter getSorter() { /** * Important: The vertex indexes must start at zero for each facing. */ - public static AnyOrderData fromMesh(BuiltSectionMeshParts translucentMesh, - TQuad[] quads, SectionPos sectionPos) { - var ranges = translucentMesh.getVertexRanges(); - var anyOrderData = new AnyOrderData(sectionPos, ranges, quads.length); + public static AnyOrderData fromMesh(int[] vertexCounts, + TQuad[] quads, SectionPos sectionPos) { + var anyOrderData = new AnyOrderData(sectionPos, vertexCounts, quads.length); var sorter = new StaticSorter(quads.length); anyOrderData.sorterOnce = sorter; var indexBuffer = sorter.getIntBuffer(); - for (var range : ranges) { - if (range == null) { + for (var vertexCount : vertexCounts) { + if (vertexCount <= 0) { continue; } - int count = TranslucentData.vertexCountToQuadCount(range.vertexCount()); + int count = TranslucentData.vertexCountToQuadCount(vertexCount); for (int i = 0; i < count; i++) { TranslucentData.writeQuadVertexIndexes(indexBuffer, i); } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/DynamicBSPData.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/DynamicBSPData.java index 062234e751..cfab09e721 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/DynamicBSPData.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/DynamicBSPData.java @@ -1,6 +1,5 @@ package net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.data; -import net.caffeinemc.mods.sodium.client.gl.util.VertexRange; import net.caffeinemc.mods.sodium.client.render.chunk.data.BuiltSectionMeshParts; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.TQuad; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.bsp_tree.BSPNode; @@ -20,8 +19,8 @@ public class DynamicBSPData extends DynamicData { private final BSPNode rootNode; private final int generation; - private DynamicBSPData(SectionPos sectionPos, VertexRange range, BSPResult result, Vector3dc initialCameraPos, TQuad[] quads, int generation) { - super(sectionPos, range, quads.length, result, initialCameraPos); + private DynamicBSPData(SectionPos sectionPos, int vertexCount, BSPResult result, Vector3dc initialCameraPos, TQuad[] quads, int generation) { + super(sectionPos, vertexCount, quads.length, result, initialCameraPos); this.rootNode = result.getRootNode(); this.generation = generation; } @@ -42,7 +41,7 @@ public Sorter getSorter() { return new DynamicBSPSorter(this.getQuadCount()); } - public static DynamicBSPData fromMesh(BuiltSectionMeshParts translucentMesh, + public static DynamicBSPData fromMesh(int vertexCount, CombinedCameraPos cameraPos, TQuad[] quads, SectionPos sectionPos, TranslucentData oldData) { BSPNode oldRoot = null; @@ -58,9 +57,7 @@ public static DynamicBSPData fromMesh(BuiltSectionMeshParts translucentMesh, } var result = BSPNode.buildBSP(quads, sectionPos, oldRoot, prepareNodeReuse); - VertexRange range = TranslucentData.getUnassignedVertexRange(translucentMesh); - - var dynamicData = new DynamicBSPData(sectionPos, range, result, cameraPos.getAbsoluteCameraPos(), quads, generation); + var dynamicData = new DynamicBSPData(sectionPos, vertexCount, result, cameraPos.getAbsoluteCameraPos(), quads, generation); // prepare geometry planes for integration into GFNI triggering result.prepareIntegration(); diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/DynamicData.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/DynamicData.java index 6a526b53a5..6c3c69080c 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/DynamicData.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/DynamicData.java @@ -1,6 +1,5 @@ package net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.data; -import net.caffeinemc.mods.sodium.client.gl.util.VertexRange; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.SortType; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.trigger.GeometryPlanes; import net.minecraft.core.SectionPos; @@ -10,8 +9,8 @@ public abstract class DynamicData extends MixedDirectionData { private GeometryPlanes geometryPlanes; private final Vector3dc initialCameraPos; - DynamicData(SectionPos sectionPos, VertexRange range, int quadCount, GeometryPlanes geometryPlanes, Vector3dc initialCameraPos) { - super(sectionPos, range, quadCount); + DynamicData(SectionPos sectionPos, int vertexCount, int quadCount, GeometryPlanes geometryPlanes, Vector3dc initialCameraPos) { + super(sectionPos, vertexCount, quadCount); this.geometryPlanes = geometryPlanes; this.initialCameraPos = initialCameraPos; } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/DynamicTopoData.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/DynamicTopoData.java index 574cf389bf..7b5fc1e491 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/DynamicTopoData.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/DynamicTopoData.java @@ -1,7 +1,6 @@ package net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.data; import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; -import net.caffeinemc.mods.sodium.client.gl.util.VertexRange; import net.caffeinemc.mods.sodium.client.render.chunk.data.BuiltSectionMeshParts; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.TQuad; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.trigger.GeometryPlanes; @@ -47,10 +46,10 @@ public class DynamicTopoData extends DynamicData { private final TQuad[] quads; private final Object2ReferenceOpenHashMap distancesByNormal; - private DynamicTopoData(SectionPos sectionPos, VertexRange range, TQuad[] quads, + private DynamicTopoData(SectionPos sectionPos, int vertexCount, TQuad[] quads, GeometryPlanes geometryPlanes, Vector3dc initialCameraPos, Object2ReferenceOpenHashMap distancesByNormal) { - super(sectionPos, range, quads.length, geometryPlanes, initialCameraPos); + super(sectionPos, vertexCount, quads.length, geometryPlanes, initialCameraPos); this.quads = quads; this.distancesByNormal = distancesByNormal; @@ -251,13 +250,12 @@ static void distanceSortDirect(IntBuffer indexBuffer, TQuad[] quads, Vector3fc c } } - public static DynamicTopoData fromMesh(BuiltSectionMeshParts translucentMesh, + public static DynamicTopoData fromMesh(int vertexCount, CombinedCameraPos cameraPos, TQuad[] quads, SectionPos sectionPos, GeometryPlanes geometryPlanes) { var distancesByNormal = geometryPlanes.prepareAndGetDistances(); - VertexRange range = TranslucentData.getUnassignedVertexRange(translucentMesh); - return new DynamicTopoData(sectionPos, range, quads, geometryPlanes, + return new DynamicTopoData(sectionPos, vertexCount, quads, geometryPlanes, cameraPos.getAbsoluteCameraPos(), distancesByNormal); } } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/MixedDirectionData.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/MixedDirectionData.java index 9f71919797..a7ab11d965 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/MixedDirectionData.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/MixedDirectionData.java @@ -1,20 +1,18 @@ package net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.data; -import net.caffeinemc.mods.sodium.client.gl.util.VertexRange; import net.caffeinemc.mods.sodium.client.model.quad.properties.ModelQuadFacing; -import net.caffeinemc.mods.sodium.client.util.NativeBuffer; import net.minecraft.core.SectionPos; public abstract class MixedDirectionData extends PresentTranslucentData { - private final VertexRange[] ranges = new VertexRange[ModelQuadFacing.COUNT]; + private final int[] vertexCounts = new int[ModelQuadFacing.COUNT]; - MixedDirectionData(SectionPos sectionPos, VertexRange range, int quadCount) { + MixedDirectionData(SectionPos sectionPos, int vertexCount, int quadCount) { super(sectionPos, quadCount); - this.ranges[ModelQuadFacing.UNASSIGNED.ordinal()] = range; + this.vertexCounts[ModelQuadFacing.UNASSIGNED.ordinal()] = vertexCount; } @Override - public VertexRange[] getVertexRanges() { - return this.ranges; + public int[] getVertexCounts() { + return this.vertexCounts; } } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/PresentTranslucentData.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/PresentTranslucentData.java index 2a73b70248..d4e219e3a7 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/PresentTranslucentData.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/PresentTranslucentData.java @@ -1,6 +1,5 @@ package net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.data; -import net.caffeinemc.mods.sodium.client.gl.util.VertexRange; import net.minecraft.core.SectionPos; /** @@ -15,7 +14,7 @@ public abstract class PresentTranslucentData extends TranslucentData { this.quadCount = quadCount; } - public abstract VertexRange[] getVertexRanges(); + public abstract int[] getVertexCounts(); public abstract Sorter getSorter(); diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/SplitDirectionData.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/SplitDirectionData.java index 708fb94a0b..cc07ffe669 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/SplitDirectionData.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/SplitDirectionData.java @@ -1,7 +1,5 @@ package net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.data; -import net.caffeinemc.mods.sodium.client.gl.util.VertexRange; -import net.caffeinemc.mods.sodium.client.util.NativeBuffer; import net.minecraft.core.SectionPos; /** @@ -10,15 +8,15 @@ * starting at zero for each facing. */ public abstract class SplitDirectionData extends PresentTranslucentData { - private final VertexRange[] ranges; + private final int[] vertexCounts; - public SplitDirectionData(SectionPos sectionPos, VertexRange[] ranges, int quadCount) { + public SplitDirectionData(SectionPos sectionPos, int[] vertexCounts, int quadCount) { super(sectionPos, quadCount); - this.ranges = ranges; + this.vertexCounts = vertexCounts; } @Override - public VertexRange[] getVertexRanges() { - return this.ranges; + public int[] getVertexCounts() { + return this.vertexCounts; } } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/StaticNormalRelativeData.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/StaticNormalRelativeData.java index c5593a5968..e0f253697f 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/StaticNormalRelativeData.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/StaticNormalRelativeData.java @@ -1,6 +1,5 @@ package net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.data; -import net.caffeinemc.mods.sodium.client.gl.util.VertexRange; import net.caffeinemc.mods.sodium.client.render.chunk.data.BuiltSectionMeshParts; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.SortType; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.TQuad; @@ -20,8 +19,8 @@ public class StaticNormalRelativeData extends SplitDirectionData { private Sorter sorterOnce; - public StaticNormalRelativeData(SectionPos sectionPos, VertexRange[] ranges, int quadCount) { - super(sectionPos, ranges, quadCount); + public StaticNormalRelativeData(SectionPos sectionPos, int[] vertexCounts, int quadCount) { + super(sectionPos, vertexCounts, quadCount); } @Override @@ -39,8 +38,8 @@ public Sorter getSorter() { return sorter; } - private static StaticNormalRelativeData fromDoubleUnaligned(BuiltSectionMeshParts translucentMesh, TQuad[] quads, SectionPos sectionPos) { - var snrData = new StaticNormalRelativeData(sectionPos, translucentMesh.getVertexRanges(), quads.length); + private static StaticNormalRelativeData fromDoubleUnaligned(int[] vertexCounts, TQuad[] quads, SectionPos sectionPos) { + var snrData = new StaticNormalRelativeData(sectionPos, vertexCounts, quads.length); var sorter = new StaticSorter(quads.length); snrData.sorterOnce = sorter; var indexBuffer = sorter.getIntBuffer(); @@ -80,19 +79,18 @@ private static StaticNormalRelativeData fromDoubleUnaligned(BuiltSectionMeshPart /** * Important: The vertex indexes must start at zero for each facing. */ - private static StaticNormalRelativeData fromMixed(BuiltSectionMeshParts translucentMesh, + private static StaticNormalRelativeData fromMixed(int[] vertexCounts, TQuad[] quads, SectionPos sectionPos) { - var snrData = new StaticNormalRelativeData(sectionPos, translucentMesh.getVertexRanges(), quads.length); + var snrData = new StaticNormalRelativeData(sectionPos, vertexCounts, quads.length); var sorter = new StaticSorter(quads.length); snrData.sorterOnce = sorter; var indexBuffer = sorter.getIntBuffer(); - var ranges = translucentMesh.getVertexRanges(); var maxQuadCount = 0; boolean anyNeedsSortData = false; - for (var range : ranges) { - if (range != null) { - var quadCount = TranslucentData.vertexCountToQuadCount(range.vertexCount()); + for (var vertexCount : vertexCounts) { + if (vertexCount != -1) { + var quadCount = TranslucentData.vertexCountToQuadCount(vertexCount); maxQuadCount = Math.max(maxQuadCount, quadCount); anyNeedsSortData |= !RadixSort.useRadixSort(quadCount) && quadCount > 1; } @@ -104,13 +102,8 @@ private static StaticNormalRelativeData fromMixed(BuiltSectionMeshParts transluc } int quadIndex = 0; - for (var range : ranges) { - if (range == null) { - continue; - } - - int vertexCount = range.vertexCount(); - if (vertexCount == 0) { + for (var vertexCount : vertexCounts) { + if (vertexCount == -1 || vertexCount == 0) { continue; } @@ -151,12 +144,12 @@ private static StaticNormalRelativeData fromMixed(BuiltSectionMeshParts transluc return snrData; } - public static StaticNormalRelativeData fromMesh(BuiltSectionMeshParts translucentMesh, + public static StaticNormalRelativeData fromMesh(int[] vertexCounts, TQuad[] quads, SectionPos sectionPos, boolean isDoubleUnaligned) { if (isDoubleUnaligned) { - return fromDoubleUnaligned(translucentMesh, quads, sectionPos); + return fromDoubleUnaligned(vertexCounts, quads, sectionPos); } else { - return fromMixed(translucentMesh, quads, sectionPos); + return fromMixed(vertexCounts, quads, sectionPos); } } } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/StaticTopoData.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/StaticTopoData.java index 079fbd1172..48d6bb298b 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/StaticTopoData.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/StaticTopoData.java @@ -1,6 +1,5 @@ package net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.data; -import net.caffeinemc.mods.sodium.client.gl.util.VertexRange; import net.caffeinemc.mods.sodium.client.render.chunk.data.BuiltSectionMeshParts; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.SortType; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.TQuad; @@ -17,8 +16,8 @@ public class StaticTopoData extends MixedDirectionData { private Sorter sorterOnce; - StaticTopoData(SectionPos sectionPos, VertexRange range, int quadCount) { - super(sectionPos, range, quadCount); + StaticTopoData(SectionPos sectionPos, int vertexCount, int quadCount) { + super(sectionPos, vertexCount, quadCount); } @Override @@ -43,8 +42,7 @@ public void accept(int value) { } } - public static StaticTopoData fromMesh(BuiltSectionMeshParts translucentMesh, TQuad[] quads, SectionPos sectionPos) { - VertexRange range = TranslucentData.getUnassignedVertexRange(translucentMesh); + public static StaticTopoData fromMesh(int vertexCount, TQuad[] quads, SectionPos sectionPos) { var sorter = new StaticSorter(quads.length); var indexWriter = new QuadIndexConsumerIntoBuffer(sorter.getIntBuffer()); @@ -53,7 +51,7 @@ public static StaticTopoData fromMesh(BuiltSectionMeshParts translucentMesh, TQu return null; } - var staticTopoData = new StaticTopoData(sectionPos, range, quads.length); + var staticTopoData = new StaticTopoData(sectionPos, vertexCount, quads.length); staticTopoData.sorterOnce = sorter; return staticTopoData; } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/TranslucentData.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/TranslucentData.java index af40b5bb83..4a683bc09c 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/TranslucentData.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/data/TranslucentData.java @@ -2,11 +2,7 @@ import java.nio.IntBuffer; -import org.joml.Vector3fc; - -import net.caffeinemc.mods.sodium.client.gl.util.VertexRange; import net.caffeinemc.mods.sodium.client.model.quad.properties.ModelQuadFacing; -import net.caffeinemc.mods.sodium.client.render.chunk.data.BuiltSectionMeshParts; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.SortType; import net.minecraft.core.SectionPos; @@ -67,14 +63,4 @@ public static void writeQuadVertexIndexes(IntBuffer intBuffer, int[] quadIndexes writeQuadVertexIndexes(intBuffer, quadIndexes[quadIndexPos]); } } - - static VertexRange getUnassignedVertexRange(BuiltSectionMeshParts translucentMesh) { - VertexRange range = translucentMesh.getVertexRanges()[ModelQuadFacing.UNASSIGNED.ordinal()]; - - if (range == null) { - throw new IllegalStateException("No unassigned data in mesh"); - } - - return range; - } } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/util/MathUtil.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/util/MathUtil.java index 8c41de06ec..5a11ae1355 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/util/MathUtil.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/util/MathUtil.java @@ -12,21 +12,21 @@ public static long toMib(long bytes) { return bytes / (1024L * 1024L); // 1 MiB = 1048576 (2^20) bytes } - private static final int BIT_COUNT = 32; - private static final int FLIP_SIGN_MASK = 1 << (BIT_COUNT - 1); - /** * Converts a float to a comparable integer value. This is used to compare * floating point values by their int bits (for example packed in a long). - * + *

* The resulting integer can be treated as if it's unsigned and numbers the * floats from the smallest negative to the largest positive value. + *

+ * Reference: StackOverflow Answer */ public static int floatToComparableInt(float f) { - // // uses Float.compare to avoid issues comparing -0.0f and 0.0f - // return Float.floatToRawIntBits(f) ^ (Float.compare(f, 0f) > 0 ? 0x80000000 : 0xffffffff); - var bits = Float.floatToRawIntBits(f); - return bits ^ ((bits >> (BIT_COUNT - 1)) | FLIP_SIGN_MASK); + return bits ^ ((bits >> 31) & 0x7FFFFFFF); + } + + public static float comparableIntToFloat(int i) { + return Float.intBitsToFloat(i ^ ((i >> 31) & 0x7FFFFFFF)); } }