1616import net .caffeinemc .mods .sodium .client .util .MathUtil ;
1717import net .caffeinemc .mods .sodium .client .util .sorting .RadixSort ;
1818import net .minecraft .util .Mth ;
19+ import org .joml .Vector3f ;
1920import org .joml .Vector3fc ;
2021
2122import java .util .Arrays ;
@@ -471,6 +472,10 @@ static void flushBestSplittingGroup(IntArrayList splittingGroup, IntArrayList be
471472 splittingGroup .clear ();
472473 }
473474
475+ private static boolean floatEquals (float a , float b ) {
476+ return Float .floatToIntBits (a ) == Float .floatToIntBits (b ) || Math .abs (a - b ) <= TQuad .VERTEX_EPSILON ;
477+ }
478+
474479 static private BSPNode handleUnsortableBySplitting (BSPWorkspace workspace , IntArrayList indexes , int depth , BSPNode oldNode , IntArrayList splittingGroup ) {
475480 // pick the first quad if there's no prepared splitting group
476481 int representativeIndex ;
@@ -487,6 +492,9 @@ static private BSPNode handleUnsortableBySplitting(BSPWorkspace workspace, IntAr
487492 // split all quads by the splitting group's plane
488493 var splitPlane = representative .getVeryAccurateNormal ();
489494 var splitDistance = representative .getAccurateDotProduct ();
495+ var splitPlaneNeg = splitPlane .negate (new Vector3f ());
496+ var splitDistanceNeg = -splitDistance ;
497+ var splitPlaneIsAligned = representativeFacing .isAligned ();
490498
491499 IntArrayList inside = new IntArrayList ();
492500 IntArrayList outside = new IntArrayList ();
@@ -507,11 +515,17 @@ static private BSPNode handleUnsortableBySplitting(BSPWorkspace workspace, IntAr
507515 var quadFacing = insideQuad .getFacing ();
508516
509517 // eliminate quads that lie in the split plane
510- if (quadFacing == representativeFacing && insideQuad .getAccurateDotProduct () == splitDistance &&
511- (representativeFacing != ModelQuadFacing .UNASSIGNED ||
512- insideQuad .getVeryAccurateNormal ().equals (splitPlane ))) {
513- splittingGroup .add (candidateIndex );
514- continue ;
518+ if (quadFacing == representativeFacing ) {
519+ var accurateNormal = insideQuad .getVeryAccurateNormal ();
520+ var accurateDotProduct = insideQuad .getAccurateDotProduct ();
521+ var coplanar = floatEquals (accurateDotProduct , splitDistance ) && (splitPlaneIsAligned ||
522+ accurateNormal .equals (splitPlane , TQuad .VERTEX_EPSILON ));
523+ var antiCoplanar = coplanar || floatEquals (accurateDotProduct , splitDistanceNeg ) && (splitPlaneIsAligned ||
524+ accurateNormal .equals (splitPlaneNeg , TQuad .VERTEX_EPSILON ));
525+ if (coplanar || antiCoplanar ) {
526+ splittingGroup .add (candidateIndex );
527+ continue ;
528+ }
515529 }
516530
517531 // split the geometry with the plane
@@ -646,18 +660,19 @@ else if (insideCount == 1) {
646660 splitTriangleCorner (cornerIndex , outsideQuad , insideQuad , splitPlane , splitDistance );
647661 }
648662 } else { // uniqueVertices == 4, masked == unmasked
649- // after dealing with the other cases, now two vertices being on the plane implies the quad is split exactly along its diagonal
650- // insideCount is 2, onPlaneMap is 0b0101 or 0b1010
651- if (onPlaneCount == 2 ) {
652- // this case can be treated like even splitting if the two on-plane vertices are declared as each part of one of the sides
653- if (onPlaneMap == 0b0101) {
654- insideMap |= 0b0001;
655- } else {
656- insideMap |= 0b0010;
657- }
663+ // it's split along the diagonal.
664+ // this case can be treated like even splitting if the two on-plane vertices are declared as each part of one of the sides
665+ if (onPlaneCount == 2 && onPlaneMap == 0b0101) {
666+ insideMap |= 0b0001;
667+ insideCount = 2 ;
668+ } else if (onPlaneCount == 2 && onPlaneMap == 0b1010) {
669+ insideMap |= 0b0010;
658670 insideCount = 2 ;
659671 }
660672
673+ // or it's a bent quad where one edge lies on the split and the opposite edge crosses the split.
674+ // in this case it simply falls through to one of the odd splitting modes
675+
661676 // one vertex being on the plane now implies the quad is split on a vertex and through an edge.
662677 // if there is one vertex inside (and two outside), move the on-plane vertex inside to produce an even split case.
663678 // in the other case nothing needs to be done since for splitting the 0-bits in the insideMap are treated as outside.
0 commit comments