Skip to content

Commit 6dd5293

Browse files
NotStirredleMaik
andauthored
Optimize map view of legacy and cubic chunks worlds (#1032)
* Statically initialise legacy tags, leading to enormous improvement in legacy world parsing performance * Actually use heightmap data when initialising SurfaceLayer * unsynchronise palette in map view surface loading * Use existing Chunk.X_MAX instead of hardcoded 16 Co-authored-by: Maik Marschner <m.marschner@wertarbyte.com> * Update map view optimisations to support cubicchunks PR Co-authored-by: Maik Marschner <m.marschner@wertarbyte.com>
1 parent 49d07c0 commit 6dd5293

6 files changed

Lines changed: 29 additions & 12 deletions

File tree

chunky/src/java/se/llbit/chunky/block/legacy/LegacyBlocks.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,27 @@
99

1010
public class LegacyBlocks {
1111

12+
/** statically initialised array of every possible tag */
13+
private static final Tag[] legacyTags = new Tag[(1 << 8) * (1 << 4)];
14+
15+
static {
16+
for (int id = 0; id < 1 << 8; id++) { //id is 8 bits
17+
for (int data = 0; data < 1 << 4; data++) { //data is 4 bits
18+
legacyTags[id * (1 << 4) + data] = getTag(id, data);
19+
}
20+
}
21+
}
22+
1223
public static Tag getTag(int offset, byte[] blocks, byte[] blockData) {
1324
int id = blocks[offset] & 0xFF;
1425
int data = 0xFF & blockData[offset / 2];
1526
data >>= (offset % 2) * 4;
1627
data &= 0xF;
1728

29+
return legacyTags[id * (1 << 4) + data];
30+
}
31+
32+
private static Tag getTag(int id, int data) {
1833
CompoundTag tag = new CompoundTag();
1934
switch (id) {
2035
case 0: return nameTag(tag, "air");

chunky/src/java/se/llbit/chunky/map/SurfaceLayer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ public class SurfaceLayer extends BitmapLayer {
5050
* @param dim current dimension
5151
* @param chunkData data for the chunk
5252
*/
53-
public SurfaceLayer(int dim, ChunkData chunkData, BlockPalette palette, int yMin, int yMax) {
53+
public SurfaceLayer(int dim, ChunkData chunkData, BlockPalette palette, int yMin, int yMax, int[] heightmapData) {
5454
bitmap = new int[Chunk.X_MAX * Chunk.Z_MAX];
5555
topo = new int[Chunk.X_MAX * Chunk.Z_MAX];
5656
for (int x = 0; x < Chunk.X_MAX; ++x) {
5757
for (int z = 0; z < Chunk.Z_MAX; ++z) {
5858

5959
// Find the topmost non-empty block.
60-
int y = Math.min(chunkData.maxY() - 1, yMax);
60+
int y = Math.min(Math.min(chunkData.maxY() - 1, yMax), heightmapData[z*Chunk.X_MAX + x]);
6161
int minY = Math.max(chunkData.minY(), yMin);
6262
for (; y > minY; --y) {
6363
if (palette.get(chunkData.getBlockAt(x, y, z)) != Air.INSTANCE) {

chunky/src/java/se/llbit/chunky/world/Chunk.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,11 @@ private void loadSurface(Map<String, Tag> data, ChunkData chunkData, int yMin, i
174174
extractBiomeData(data.get(LEVEL_BIOMES), chunkData);
175175
if (version.equals("1.13") || version.equals("1.12")) {
176176
BlockPalette palette = new BlockPalette();
177+
palette.unsynchronize(); //only this RegionParser will use this palette
177178
loadBlockData(data, chunkData, palette, yMin, yMax);
178179
int[] heightmapData = extractHeightmapData(data, chunkData);
179180
updateHeightmap(heightmap, position, chunkData, heightmapData, palette, yMax);
180-
surface = new SurfaceLayer(world.currentDimension(), chunkData, palette, yMin, yMax);
181+
surface = new SurfaceLayer(world.currentDimension(), chunkData, palette, yMin, yMax, heightmapData);
181182
queueTopography();
182183
}
183184
} else {

chunky/src/java/se/llbit/chunky/world/CubicWorld.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ public synchronized Region getRegion(ChunkPosition pos) {
7676
if (regionExists(pos)) {
7777
region = createRegion(pos);
7878
}
79-
setRegion(pos, region);
8079
return region;
8180
});
8281
}
@@ -88,7 +87,6 @@ public synchronized Region getRegionWithinRange(ChunkPosition pos, int minY, int
8887
if (regionExistsWithinRange(pos, minY, maxY)) {
8988
region = createRegion(pos);
9089
}
91-
setRegion(pos, region);
9290
return region;
9391
});
9492
}

chunky/src/java/se/llbit/chunky/world/ImposterCubicChunk.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,26 @@
44
import se.llbit.chunky.chunk.BlockPalette;
55
import se.llbit.chunky.chunk.ChunkData;
66
import se.llbit.chunky.chunk.EmptyChunkData;
7-
import se.llbit.chunky.chunk.GenericChunkData;
87
import se.llbit.chunky.map.IconLayer;
98
import se.llbit.chunky.map.SurfaceLayer;
109
import se.llbit.chunky.world.region.ImposterCubicRegion;
11-
import se.llbit.math.QuickMath;
12-
import se.llbit.nbt.*;
13-
import se.llbit.util.BitBuffer;
10+
import se.llbit.nbt.CompoundTag;
11+
import se.llbit.nbt.ListTag;
12+
import se.llbit.nbt.SpecificTag;
13+
import se.llbit.nbt.Tag;
1414
import se.llbit.util.Mutable;
15-
import se.llbit.util.NotNull;
1615

1716
import java.util.HashSet;
1817
import java.util.Map;
1918
import java.util.Set;
2019

2120
import static se.llbit.chunky.world.World.VERSION_1_12_2;
2221

22+
/**
23+
* An implementation of a cube wrapper for pre flattening cubic chunks (1.10, 1.11, 1.12)
24+
*
25+
* Represents an infinitely tall column of 16x16x16 Cubes
26+
*/
2327
public class ImposterCubicChunk extends Chunk {
2428
private final CubicWorld world;
2529

@@ -100,7 +104,7 @@ private void loadSurfaceCubic(Map<Integer, Map<String, Tag>> data, ChunkData chu
100104

101105
int[] heightmapData = extractHeightmapDataCubic(null, chunkData);
102106
updateHeightmap(heightmap, position, chunkData, heightmapData, palette, yMax);
103-
surface = new SurfaceLayer(world.currentDimension(), chunkData, palette, yMin, yMax);
107+
surface = new SurfaceLayer(world.currentDimension(), chunkData, palette, yMin, yMax, heightmapData);
104108
}
105109

106110
private int[] extractHeightmapDataCubic(Map<String, Tag> cubeData, ChunkData chunkData) {

chunky/src/java/se/llbit/chunky/world/World.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,6 @@ public synchronized Region getRegion(ChunkPosition pos) {
313313
if (regionExists(pos)) {
314314
region = createRegion(pos);
315315
}
316-
setRegion(pos, region);
317316
return region;
318317
});
319318
}

0 commit comments

Comments
 (0)