diff --git a/modules/world-core/src/block_registry_tests.zig b/modules/world-core/src/block_registry_tests.zig index 1ed7818c..31eec7f7 100644 --- a/modules/world-core/src/block_registry_tests.zig +++ b/modules/world-core/src/block_registry_tests.zig @@ -181,6 +181,28 @@ test "core natural block pack registry properties" { try testing.expectEqual(block_registry.RenderPass.solid, block_registry.getBlockDefinition(.white_terracotta).render_pass); } +test "BlockDefinition.isFullCubeOccluder true for solid cube blocks" { + try testing.expect(block_registry.getBlockDefinition(.stone).isFullCubeOccluder()); + try testing.expect(block_registry.getBlockDefinition(.bedrock).isFullCubeOccluder()); + try testing.expect(block_registry.getBlockDefinition(.cobblestone).isFullCubeOccluder()); +} + +test "BlockDefinition.isFullCubeOccluder false for transparent blocks" { + try testing.expect(!block_registry.getBlockDefinition(.glass).isFullCubeOccluder()); + try testing.expect(!block_registry.getBlockDefinition(.ice).isFullCubeOccluder()); +} + +test "BlockDefinition.isFullCubeOccluder false for non-cube shapes" { + try testing.expect(!block_registry.getBlockDefinition(.torch).isFullCubeOccluder()); + try testing.expect(!block_registry.getBlockDefinition(.tall_grass).isFullCubeOccluder()); + try testing.expect(!block_registry.getBlockDefinition(.vine).isFullCubeOccluder()); +} + +test "BlockDefinition.isFullCubeOccluder false for solid but non-cube render shape" { + try testing.expect(!block_registry.getBlockDefinition(.stone_slab).isFullCubeOccluder()); + try testing.expect(!block_registry.getBlockDefinition(.stone_stairs).isFullCubeOccluder()); +} + test "aquatic vegetation blocks use cutout shapes" { const seagrass = block_registry.getBlockDefinition(.seagrass); try testing.expect(!seagrass.is_solid); diff --git a/modules/world-meshing/src/meshing/boundary_cross_tests.zig b/modules/world-meshing/src/meshing/boundary_cross_tests.zig new file mode 100644 index 00000000..7aa11888 --- /dev/null +++ b/modules/world-meshing/src/meshing/boundary_cross_tests.zig @@ -0,0 +1,56 @@ +const std = @import("std"); +const testing = std.testing; +const boundary = @import("boundary.zig"); +const NeighborChunks = boundary.NeighborChunks; +const Chunk = @import("world-core").Chunk; + +test "getBlockCross cross-chunk east neighbor returns neighbor block" { + var chunk = Chunk.init(0, 0); + var east = Chunk.init(1, 0); + east.setBlock(0, 64, 8, .glowstone); + const neighbors = NeighborChunks{ .east = &east }; + try testing.expectEqual(.glowstone, boundary.getBlockCross(&chunk, neighbors, 16, 64, 8)); +} + +test "getBlockCross cross-chunk north neighbor returns neighbor block" { + var chunk = Chunk.init(0, 1); + var north = Chunk.init(0, 0); + north.setBlock(8, 64, 15, .water); + const neighbors = NeighborChunks{ .north = &north }; + try testing.expectEqual(.water, boundary.getBlockCross(&chunk, neighbors, 8, 64, -1)); +} + +test "getBlockCross null neighbor returns air" { + var chunk = Chunk.init(0, 0); + try testing.expectEqual(.air, boundary.getBlockCross(&chunk, .empty, 16, 64, 8)); + try testing.expectEqual(.air, boundary.getBlockCross(&chunk, .empty, -1, 64, 8)); + try testing.expectEqual(.air, boundary.getBlockCross(&chunk, .empty, 8, 64, 16)); +} + +test "getEntranceBounceCross cross-chunk west neighbor returns neighbor value" { + var chunk = Chunk.init(1, 0); + var west = Chunk.init(0, 0); + west.setEntranceBounce(15, 64, 8, 5); + const neighbors = NeighborChunks{ .west = &west }; + try testing.expectEqual(@as(u4, 5), boundary.getEntranceBounceCross(&chunk, neighbors, -1, 64, 8)); +} + +test "getEntranceBounceCross out of Y range returns zero" { + var chunk = Chunk.init(0, 0); + try testing.expectEqual(@as(u4, 0), boundary.getEntranceBounceCross(&chunk, .empty, 5, -1, 10)); + try testing.expectEqual(@as(u4, 0), boundary.getEntranceBounceCross(&chunk, .empty, 5, 256, 10)); +} + +test "getEntranceDirCross cross-chunk south neighbor returns neighbor value" { + var chunk = Chunk.init(0, 0); + var south = Chunk.init(0, 1); + south.setEntranceDir(8, 64, 0, 99); + const neighbors = NeighborChunks{ .south = &south }; + try testing.expectEqual(@as(u8, 99), boundary.getEntranceDirCross(&chunk, neighbors, 8, 64, 16)); +} + +test "getEntranceDirCross null neighbor on boundary returns zero" { + var chunk = Chunk.init(0, 0); + try testing.expectEqual(@as(u8, 0), boundary.getEntranceDirCross(&chunk, .empty, 16, 64, 8)); + try testing.expectEqual(@as(u8, 0), boundary.getEntranceDirCross(&chunk, .empty, -1, 64, 8)); +} diff --git a/modules/world-meshing/src/root.zig b/modules/world-meshing/src/root.zig index 00af1266..1ae4802f 100644 --- a/modules/world-meshing/src/root.zig +++ b/modules/world-meshing/src/root.zig @@ -13,6 +13,7 @@ pub const meshing = struct { pub const biome_color_sampler = @import("meshing/biome_color_sampler.zig"); pub const boundary = @import("meshing/boundary.zig"); pub const boundary_tests = @import("meshing/boundary_tests.zig"); + pub const boundary_cross_tests = @import("meshing/boundary_cross_tests.zig"); pub const cross_mesher = @import("meshing/cross_mesher.zig"); pub const custom_mesh_mesher = @import("meshing/custom_mesh_mesher.zig"); pub const greedy_mesher = @import("meshing/greedy_mesher.zig"); diff --git a/src/tests.zig b/src/tests.zig index c4bb6aaa..374fd1ce 100644 --- a/src/tests.zig +++ b/src/tests.zig @@ -95,6 +95,7 @@ test { _ = @import("world-meshing").chunk_storage_interface_tests; _ = @import("world-core").biome_and_block_tests; _ = @import("world-core").packed_light_tests; + _ = @import("world-meshing").meshing.boundary_cross_tests; _ = @import("world-meshing").meshing.boundary_tests; _ = @import("world-core").world_coord_tests; _ = @import("world-core").world_block_fill_tests;