fix: use collision shape for Shape#isFaceFull instead of occlusion shape

This commit is contained in:
mworzala 2024-03-24 21:50:54 -04:00
parent 6e179dbd8a
commit ee17c032e7
No known key found for this signature in database
GPG Key ID: B148F922E64797C7
2 changed files with 19 additions and 7 deletions

View File

@ -18,6 +18,7 @@ public final class ShapeImpl implements Shape {
private static final Pattern PATTERN = Pattern.compile("\\d.\\d+", Pattern.MULTILINE);
private final BoundingBox[] collisionBoundingBoxes;
private final Point relativeStart, relativeEnd;
private final byte fullFaces;
private final BoundingBox[] occlusionBoundingBoxes;
private final byte blockOcclusion;
@ -49,10 +50,17 @@ public final class ShapeImpl implements Shape {
this.relativeEnd = new Vec(maxX, maxY, maxZ);
}
byte fullCollisionFaces = 0;
for (BlockFace f : BlockFace.values()) {
final byte res = isFaceCovered(computeOcclusionSet(f, collisionBoundingBoxes));
fullCollisionFaces |= ((res == 2) ? 0b1 : 0b0) << (byte) f.ordinal();
}
this.fullFaces = fullCollisionFaces;
byte airFaces = 0;
byte fullFaces = 0;
for (BlockFace f : BlockFace.values()) {
final byte res = isFaceCovered(computeOcclusionSet(f));
final byte res = isFaceCovered(computeOcclusionSet(f, occlusionBoundingBoxes));
airFaces |= ((res == 0) ? 0b1 : 0b0) << (byte) f.ordinal();
fullFaces |= ((res == 2) ? 0b1 : 0b0) << (byte) f.ordinal();
}
@ -145,14 +153,14 @@ public final class ShapeImpl implements Shape {
if (hasAirOcclusion || hasAirOcclusionOther) return false;
// Comparing two partial faces. Computation needed
List<Rectangle> allRectangles = shapeImpl.computeOcclusionSet(face.getOppositeFace());
allRectangles.addAll(computeOcclusionSet(face));
List<Rectangle> allRectangles = computeOcclusionSet(face.getOppositeFace(), shapeImpl.occlusionBoundingBoxes);
allRectangles.addAll(computeOcclusionSet(face, occlusionBoundingBoxes));
return isFaceCovered(allRectangles) == 2;
}
@Override
public boolean isFaceFull(@NotNull BlockFace face) {
return (((blockOcclusion >> face.ordinal()) & 1) == 1);
return (((fullFaces >> face.ordinal()) & 1) == 1);
}
@Override
@ -184,9 +192,9 @@ public final class ShapeImpl implements Shape {
return block;
}
private List<Rectangle> computeOcclusionSet(BlockFace face) {
private static @NotNull List<Rectangle> computeOcclusionSet(BlockFace face, BoundingBox[] boundingBoxes) {
List<Rectangle> rSet = new ArrayList<>();
for (BoundingBox boundingBox : this.occlusionBoundingBoxes) {
for (BoundingBox boundingBox : boundingBoxes) {
switch (face) {
case NORTH -> // negative Z
{

View File

@ -20,7 +20,11 @@ public class TestShape {
Arguments.of(Block.ENCHANTING_TABLE, BlockFace.TOP, false),
Arguments.of(Block.ENCHANTING_TABLE, BlockFace.NORTH, false),
Arguments.of(Block.ACACIA_FENCE, BlockFace.TOP, false),
Arguments.of(Block.IRON_BARS, BlockFace.TOP, false)
Arguments.of(Block.IRON_BARS, BlockFace.TOP, false),
// We are testing collision faces here, so this should be true even though it doesnt occlude light
Arguments.of(Block.GLASS, BlockFace.TOP, true),
Arguments.of(Block.DARK_OAK_DOOR, BlockFace.NORTH, false),
Arguments.of(Block.DARK_OAK_DOOR, BlockFace.SOUTH, true)
);
}