Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix fluids shape on octree edge #1579

Merged
merged 1 commit into from
Oct 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 35 additions & 23 deletions chunky/src/java/se/llbit/chunky/renderer/scene/OctreeFinalizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import se.llbit.math.Octree;
import se.llbit.math.Vector3i;

import java.util.Set;

/**
* Processes the Octree after it has been loaded and updates block states for blocks that depend on
* neighbor blocks. Octree finalization is be done after all chunks have been loaded because before
Expand All @@ -41,7 +43,7 @@ public class OctreeFinalizer {
* @param cp Position of the chunk to finalize
*/
public static void finalizeChunk(Octree worldTree, Octree waterTree, BlockPalette palette,
Vector3i origin, ChunkPosition cp, int yMin, int yMax) {
Set<ChunkPosition> loadedChunks, Vector3i origin, ChunkPosition cp, int yMin, int yMax) {
for (int cy = yMin; cy < yMax; ++cy) {
for (int cz = 0; cz < 16; ++cz) {
int z = cz + cp.z * 16 - origin.z;
Expand All @@ -50,7 +52,7 @@ public static void finalizeChunk(Octree worldTree, Octree waterTree, BlockPalett
// process blocks that are at the edge of the chunk, the other should have be taken care of during the loading
if (cy == yMin || cy == yMax - 1 || cz == 0 || cz == 15 || cx == 0 || cx == 15) {
hideBlocks(worldTree, palette, x, cy, z, yMin, yMax, origin);
processBlock(worldTree, waterTree, palette, x, cy, z, origin);
processBlock(worldTree, waterTree, palette, loadedChunks, x, cy, z, origin);
}
}
}
Expand All @@ -75,8 +77,8 @@ private static void hideBlocks(Octree worldTree, BlockPalette palette, int x,
}
}

private static void processBlock(Octree worldTree, Octree waterTree, BlockPalette palette, int x,
int cy, int z, Vector3i origin) {
private static void processBlock(Octree worldTree, Octree waterTree, BlockPalette palette,
Set<ChunkPosition> loadedChunks, int x, int cy, int z, Vector3i origin) {
int y = cy - origin.y;
Material mat = worldTree.getMaterial(x, y, z, palette);
Material wmat = waterTree.getMaterial(x, y, z, palette);
Expand All @@ -91,32 +93,32 @@ private static void processBlock(Octree worldTree, Octree waterTree, BlockPalett
int corner2 = level0;
int corner3 = level0;

int level = waterLevelAt(worldTree, waterTree, palette, x - 1, y, z, level0);
int level = waterLevelAt(worldTree, waterTree, palette, loadedChunks, x - 1, y, z, level0);
corner3 += level;
corner0 += level;

level = waterLevelAt(worldTree, waterTree, palette, x - 1, y, z + 1, level0);
level = waterLevelAt(worldTree, waterTree, palette, loadedChunks, x - 1, y, z + 1, level0);
corner0 += level;

level = waterLevelAt(worldTree, waterTree, palette, x, y, z + 1, level0);
level = waterLevelAt(worldTree, waterTree, palette, loadedChunks, x, y, z + 1, level0);
corner0 += level;
corner1 += level;

level = waterLevelAt(worldTree, waterTree, palette, x + 1, y, z + 1, level0);
level = waterLevelAt(worldTree, waterTree, palette, loadedChunks, x + 1, y, z + 1, level0);
corner1 += level;

level = waterLevelAt(worldTree, waterTree, palette, x + 1, y, z, level0);
level = waterLevelAt(worldTree, waterTree, palette, loadedChunks, x + 1, y, z, level0);
corner1 += level;
corner2 += level;

level = waterLevelAt(worldTree, waterTree, palette, x + 1, y, z - 1, level0);
level = waterLevelAt(worldTree, waterTree, palette, loadedChunks, x + 1, y, z - 1, level0);
corner2 += level;

level = waterLevelAt(worldTree, waterTree, palette, x, y, z - 1, level0);
level = waterLevelAt(worldTree, waterTree, palette, loadedChunks, x, y, z - 1, level0);
corner2 += level;
corner3 += level;

level = waterLevelAt(worldTree, waterTree, palette, x - 1, y, z - 1, level0);
level = waterLevelAt(worldTree, waterTree, palette, loadedChunks, x - 1, y, z - 1, level0);
corner3 += level;

corner0 = Math.min(7, 8 - (corner0 / 4));
Expand All @@ -142,32 +144,32 @@ private static void processBlock(Octree worldTree, Octree waterTree, BlockPalett
int corner2 = level0;
int corner3 = level0;

int level = lavaLevelAt(worldTree, palette, x - 1, y, z, level0);
int level = lavaLevelAt(worldTree, palette, loadedChunks, x - 1, y, z, level0);
corner3 += level;
corner0 += level;

level = lavaLevelAt(worldTree, palette, x - 1, y, z + 1, level0);
level = lavaLevelAt(worldTree, palette, loadedChunks, x - 1, y, z + 1, level0);
corner0 += level;

level = lavaLevelAt(worldTree, palette, x, y, z + 1, level0);
level = lavaLevelAt(worldTree, palette, loadedChunks, x, y, z + 1, level0);
corner0 += level;
corner1 += level;

level = lavaLevelAt(worldTree, palette, x + 1, y, z + 1, level0);
level = lavaLevelAt(worldTree, palette, loadedChunks, x + 1, y, z + 1, level0);
corner1 += level;

level = lavaLevelAt(worldTree, palette, x + 1, y, z, level0);
level = lavaLevelAt(worldTree, palette, loadedChunks, x + 1, y, z, level0);
corner1 += level;
corner2 += level;

level = lavaLevelAt(worldTree, palette, x + 1, y, z - 1, level0);
level = lavaLevelAt(worldTree, palette, loadedChunks, x + 1, y, z - 1, level0);
corner2 += level;

level = lavaLevelAt(worldTree, palette, x, y, z - 1, level0);
level = lavaLevelAt(worldTree, palette, loadedChunks, x, y, z - 1, level0);
corner2 += level;
corner3 += level;

level = lavaLevelAt(worldTree, palette, x - 1, y, z - 1, level0);
level = lavaLevelAt(worldTree, palette, loadedChunks, x - 1, y, z - 1, level0);
corner3 += level;

corner0 = Math.min(7, 8 - (corner0 / 4));
Expand All @@ -185,8 +187,13 @@ private static void processBlock(Octree worldTree, Octree waterTree, BlockPalett
}
}

private static int waterLevelAt(Octree worldTree, Octree waterTree,
BlockPalette palette, int x, int cy, int z, int baseLevel) {
private static int waterLevelAt(Octree worldTree, Octree waterTree, BlockPalette palette,
Set<ChunkPosition> loadedChunks, int x, int cy, int z, int baseLevel) {
// If the position isn't in a loaded chunk, return the baseLevel to make the edge-of-world water flat
if (!loadedChunks.contains(new ChunkPosition(x >> 4, z >> 4))) {
return baseLevel;
}

Material corner = waterTree.getMaterial(x, cy, z, palette);
if (corner instanceof Water) {
Material above = waterTree.getMaterial(x, cy + 1, z, palette);
Expand All @@ -201,7 +208,12 @@ private static int waterLevelAt(Octree worldTree, Octree waterTree,
}

private static int lavaLevelAt(Octree octree, BlockPalette palette,
int x, int cy, int z, int baseLevel) {
Set<ChunkPosition> loadedChunks, int x, int cy, int z, int baseLevel) {
// If the position isn't in a loaded chunk, return the baseLevel to make the edge-of-world water flat
if (!loadedChunks.contains(new ChunkPosition(x >> 4, z >> 4))) {
return baseLevel;
}

Material corner = octree.getMaterial(x, cy, z, palette);
if (corner instanceof Lava) {
Material above = octree.getMaterial(x, cy + 1, z, palette);
Expand Down
2 changes: 1 addition & 1 deletion chunky/src/java/se/llbit/chunky/renderer/scene/Scene.java
Original file line number Diff line number Diff line change
Expand Up @@ -1354,7 +1354,7 @@ public synchronized void loadChunks(TaskTracker taskTracker, World world, Collec
}
}
}
OctreeFinalizer.finalizeChunk(worldOctree, waterOctree, palette, origin, cp, yMin, yMax);
OctreeFinalizer.finalizeChunk(worldOctree, waterOctree, palette, loadedChunks, origin, cp, yMin, yMax);
if (legacyChunks.contains(cp)) {
LegacyBlocksFinalizer
.finalizeChunk(worldOctree, waterOctree, palette, origin, cp, yMin, yMax);
Expand Down