Skip to content

Commit

Permalink
fix a bug with the plane-based triggering system where sections added…
Browse files Browse the repository at this point in the history
… later would not be added to the triggering system even though they should have been,

this was caused by a buggy equals implementation
  • Loading branch information
douira committed Jan 24, 2025
1 parent f2a0b41 commit 84c8d6a
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting;

import it.unimi.dsi.fastutil.Hash;
import org.joml.Vector3f;
import org.joml.Vector3fc;

Expand Down Expand Up @@ -44,30 +45,6 @@ public boolean isAligned() {
return this.alignedDirection != UNASSIGNED;
}

@Override
public int hashCode() {
if (this.isAligned()) {
return this.alignedDirection;
} else {
return super.hashCode() + ModelQuadFacing.DIRECTIONS;
}
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
AlignableNormal other = (AlignableNormal) obj;
return this.alignedDirection == other.alignedDirection;
}

public static boolean queryRange(float[] sortedDistances, float start, float end) {
// test that there is actually an entry in the query range
int result = FloatArrays.binarySearch(sortedDistances, start);
Expand All @@ -91,4 +68,35 @@ public static boolean queryRange(float[] sortedDistances, float start, float end
}
return false;
}

public static final Hash.Strategy<? super Vector3fc> HASH_STRATEGY = new Hash.Strategy<>() {
@Override
public int hashCode(Vector3fc vector) {
if (vector instanceof AlignableNormal aligned && aligned.isAligned()) {
return aligned.alignedDirection;
}

return vector.hashCode();
}

@Override
public boolean equals(Vector3fc a, Vector3fc b) {
if (a == b) {
return true;
}
if (a == null || b == null) {
return false;
}

if (a instanceof AlignableNormal alignedA && b instanceof AlignableNormal alignedB &&
alignedA.isAligned() && alignedB.isAligned()) {
return alignedA.alignedDirection == alignedB.alignedDirection;
}

var aVec = (Vector3f) a;
var bVec = (Vector3f) b;

return aVec.x == bVec.x && aVec.y == bVec.y && aVec.z == bVec.z;
}
};
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.data;

import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ReferenceMap;
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.quad.TQuad;
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.trigger.GeometryPlanes;
import net.caffeinemc.mods.sodium.client.util.sorting.RadixSort;
Expand Down Expand Up @@ -43,11 +43,11 @@ public class DynamicTopoData extends DynamicData {
private boolean pendingTriggerIsDirect;

private final TQuad[] quads;
private final Object2ReferenceOpenHashMap<Vector3fc, float[]> distancesByNormal;
private final Object2ReferenceMap<Vector3fc, float[]> distancesByNormal;

private DynamicTopoData(SectionPos sectionPos, TQuad[] quads,
GeometryPlanes geometryPlanes, Vector3dc initialCameraPos,
Object2ReferenceOpenHashMap<Vector3fc, float[]> distancesByNormal) {
Object2ReferenceMap<Vector3fc, float[]> distancesByNormal) {
super(sectionPos, quads.length, geometryPlanes, initialCameraPos);
this.quads = quads;
this.distancesByNormal = distancesByNormal;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.data;

import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ReferenceMap;
import net.caffeinemc.mods.sodium.client.model.quad.properties.ModelQuadFacing;
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.AlignableNormal;
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.quad.TQuad;
Expand Down Expand Up @@ -92,7 +92,7 @@ public static boolean orthogonalQuadVisibleThrough(TQuad quadA, TQuad quadB) {
return vis;
}

private static boolean testSeparatorRange(Object2ReferenceOpenHashMap<Vector3fc, float[]> distancesByNormal,
private static boolean testSeparatorRange(Object2ReferenceMap<Vector3fc, float[]> distancesByNormal,
Vector3fc normal, float start, float end) {
var distances = distancesByNormal.get(normal);
if (distances == null) {
Expand All @@ -102,7 +102,7 @@ private static boolean testSeparatorRange(Object2ReferenceOpenHashMap<Vector3fc,
}

private static boolean visibilityWithSeparator(TQuad quadA, TQuad quadB,
Object2ReferenceOpenHashMap<Vector3fc, float[]> distancesByNormal, Vector3fc cameraPos) {
Object2ReferenceMap<Vector3fc, float[]> distancesByNormal, Vector3fc cameraPos) {
// check if there is an aligned separator
for (int direction = 0; direction < ModelQuadFacing.DIRECTIONS; direction++) {
var facing = ModelQuadFacing.VALUES[direction];
Expand Down Expand Up @@ -163,7 +163,7 @@ private static boolean visibilityWithSeparator(TQuad quadA, TQuad quadB,
* @return true if the other quad is visible through the first quad
*/
private static boolean quadVisibleThrough(TQuad quad, TQuad other,
Object2ReferenceOpenHashMap<Vector3fc, float[]> distancesByNormal, Vector3fc cameraPos) {
Object2ReferenceMap<Vector3fc, float[]> distancesByNormal, Vector3fc cameraPos) {
if (quad == other) {
return false;
}
Expand Down Expand Up @@ -250,7 +250,7 @@ private static boolean quadVisibleThrough(TQuad quad, TQuad other,
*/
public static boolean topoGraphSort(
IntConsumer indexConsumer, TQuad[] allQuads,
Object2ReferenceOpenHashMap<Vector3fc, float[]> distancesByNormal,
Object2ReferenceMap<Vector3fc, float[]> distancesByNormal,
Vector3fc cameraPos) {
// if enabled, check for visibility and produce a mapping of indices
TQuad[] quads;
Expand Down Expand Up @@ -284,7 +284,7 @@ public static boolean topoGraphSort(
return topoGraphSort(indexConsumer, quads, quadCount, activeToRealIndex, distancesByNormal, cameraPos);
}

public static boolean topoGraphSort(IntConsumer indexConsumer, TQuad[] quads, int quadCount, int[] activeToRealIndex, Object2ReferenceOpenHashMap<Vector3fc, float[]> distancesByNormal, Vector3fc cameraPos) {
public static boolean topoGraphSort(IntConsumer indexConsumer, TQuad[] quads, int quadCount, int[] activeToRealIndex, Object2ReferenceMap<Vector3fc, float[]> distancesByNormal, Vector3fc cameraPos) {
// special case for 0 to 2 quads
if (quadCount == 0) {
return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.trigger;

import org.joml.Vector3fc;

import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ReferenceMap;
import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenCustomHashMap;
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.AlignableNormal;
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.data.DynamicData;
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.data.TranslucentData;
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.trigger.SortTriggering.SectionTriggers;
import net.minecraft.core.SectionPos;
import org.joml.Vector3fc;

/**
* Performs triggering based on globally-indexed face planes, bucketed by their normals.
Expand All @@ -20,7 +21,7 @@ class GFNITriggers implements SectionTriggers<DynamicData> {
/**
* A map of all the normal lists, indexed by their normal.
*/
private Object2ReferenceOpenHashMap<Vector3fc, NormalList> normalLists = new Object2ReferenceOpenHashMap<>();
private final Object2ReferenceMap<Vector3fc, NormalList> normalLists = new Object2ReferenceOpenCustomHashMap<>(AlignableNormal.HASH_STRATEGY);

int getUniqueNormalCount() {
return this.normalLists.size();
Expand All @@ -33,7 +34,7 @@ public void processTriggers(SortTriggering ts, CameraMovement movement) {
}
}

private void addSectionInNewNormalLists(DynamicData dynamicData, NormalPlanes normalPlanes) {
private void addSectionInNewNormalLists(NormalPlanes normalPlanes) {
var normal = normalPlanes.normal;
var normalList = this.normalLists.get(normal);
if (normalList == null) {
Expand Down Expand Up @@ -94,14 +95,14 @@ public void integrateSection(SortTriggering ts, SectionPos pos, DynamicData data
if (aligned != null) {
for (var normalPlane : aligned) {
if (normalPlane != null) {
this.addSectionInNewNormalLists(data, normalPlane);
this.addSectionInNewNormalLists(normalPlane);
}
}
}
var unaligned = geometryPlanes.getUnaligned();
if (unaligned != null) {
for (var normalPlane : unaligned) {
this.addSectionInNewNormalLists(data, normalPlane);
this.addSectionInNewNormalLists(normalPlane);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import java.util.Collection;

import it.unimi.dsi.fastutil.objects.Object2ReferenceMap;
import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenCustomHashMap;
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.AlignableNormal;
import org.joml.Vector3f;
import org.joml.Vector3fc;

Expand All @@ -16,7 +19,7 @@
*/
public class GeometryPlanes {
private NormalPlanes[] alignedPlanes;
private Object2ReferenceOpenHashMap<Vector3fc, NormalPlanes> unalignedPlanes;
private Object2ReferenceMap<Vector3fc, NormalPlanes> unalignedPlanes;

public NormalPlanes[] getAligned() {
return this.alignedPlanes;
Expand All @@ -36,9 +39,9 @@ public Collection<NormalPlanes> getUnaligned() {
return this.unalignedPlanes.values();
}

public Object2ReferenceOpenHashMap<Vector3fc, NormalPlanes> getUnalignedOrCreate() {
public Object2ReferenceMap<Vector3fc, NormalPlanes> getUnalignedOrCreate() {
if (this.unalignedPlanes == null) {
this.unalignedPlanes = new Object2ReferenceOpenHashMap<>();
this.unalignedPlanes = new Object2ReferenceOpenCustomHashMap<>(AlignableNormal.HASH_STRATEGY);
}
return this.unalignedPlanes;
}
Expand Down Expand Up @@ -104,7 +107,7 @@ public void addQuadPlane(SectionPos sectionPos, TQuad quad) {
}
}

private void prepareAndInsert(Object2ReferenceOpenHashMap<Vector3fc, float[]> distancesByNormal) {
private void prepareAndInsert(Object2ReferenceMap<Vector3fc, float[]> distancesByNormal) {
if (this.alignedPlanes != null) {
for (var normalPlanes : this.alignedPlanes) {
if (normalPlanes != null) {
Expand All @@ -123,7 +126,7 @@ public void prepareIntegration() {
this.prepareAndInsert(null);
}

public Object2ReferenceOpenHashMap<Vector3fc, float[]> prepareAndGetDistances() {
public Object2ReferenceMap<Vector3fc, float[]> prepareAndGetDistances() {
var distancesByNormal = new Object2ReferenceOpenHashMap<Vector3fc, float[]>(10);
this.prepareAndInsert(distancesByNormal);
return distancesByNormal;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.trigger;

import it.unimi.dsi.fastutil.objects.Object2ReferenceMap;
import org.joml.Vector3fc;
import java.util.Arrays;

Expand Down Expand Up @@ -38,12 +39,8 @@ public NormalPlanes(SectionPos sectionPos, int alignedDirection) {
this(sectionPos, AlignableNormal.fromAligned(alignedDirection));
}

boolean addPlaneMember(float vertexX, float vertexY, float vertexZ) {
return this.addPlaneMember(this.normal.dot(vertexX, vertexY, vertexZ));
}

public boolean addPlaneMember(float distance) {
return this.relativeDistancesSet.add(distance);
public void addPlaneMember(float distance) {
this.relativeDistancesSet.add(distance);
}

public void prepareIntegration() {
Expand All @@ -64,17 +61,17 @@ public void prepareIntegration() {
}

// sort the array ascending
Arrays.sort(relativeDistances);
Arrays.sort(this.relativeDistances);

this.baseDistance = this.normal.dot(
sectionPos.minBlockX(), sectionPos.minBlockY(), sectionPos.minBlockZ());
this.sectionPos.minBlockX(), this.sectionPos.minBlockY(), this.sectionPos.minBlockZ());
this.distanceRange = new DoubleInterval(
this.relativeDistances[0] + this.baseDistance,
this.relativeDistances[size - 1] + this.baseDistance,
Bounded.CLOSED);
}

public void prepareAndInsert(Object2ReferenceOpenHashMap<Vector3fc, float[]> distancesByNormal) {
public void prepareAndInsert(Object2ReferenceMap<Vector3fc, float[]> distancesByNormal) {
this.prepareIntegration();
if (distancesByNormal != null) {
distancesByNormal.put(this.normal, this.relativeDistances);
Expand Down

0 comments on commit 84c8d6a

Please sign in to comment.