Use an array to store sections

Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
TheMode 2021-11-06 12:25:35 +01:00
parent cb1305281c
commit 74debbbbf7
2 changed files with 25 additions and 29 deletions

View File

@ -18,7 +18,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jglrxavpok.hephaistos.nbt.NBTCompound; import org.jglrxavpok.hephaistos.nbt.NBTCompound;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@ -86,8 +85,6 @@ public abstract class Chunk implements BlockGetter, BlockSetter, Viewable, Ticka
@Override @Override
public abstract void setBlock(int x, int y, int z, @NotNull Block block); public abstract void setBlock(int x, int y, int z, @NotNull Block block);
public abstract @NotNull Map<Integer, Section> getSections();
public abstract @NotNull Section getSection(int section); public abstract @NotNull Section getSection(int section);
/** /**

View File

@ -32,7 +32,8 @@ import java.util.*;
*/ */
public class DynamicChunk extends Chunk { public class DynamicChunk extends Chunk {
protected final Int2ObjectOpenHashMap<Section> sectionMap = new Int2ObjectOpenHashMap<>(); private final int minSection, maxSection;
private final Section[] sections;
// Key = ChunkUtils#getBlockIndex // Key = ChunkUtils#getBlockIndex
protected final Int2ObjectOpenHashMap<Block> entries = new Int2ObjectOpenHashMap<>(0); protected final Int2ObjectOpenHashMap<Block> entries = new Int2ObjectOpenHashMap<>(0);
@ -44,6 +45,9 @@ public class DynamicChunk extends Chunk {
public DynamicChunk(@NotNull Instance instance, int chunkX, int chunkZ) { public DynamicChunk(@NotNull Instance instance, int chunkX, int chunkZ) {
super(instance, chunkX, chunkZ, true); super(instance, chunkX, chunkZ, true);
this.minSection = instance.getDimensionType().getMinY() / CHUNK_SECTION_SIZE;
this.maxSection = instance.getDimensionType().getHeight() / CHUNK_SECTION_SIZE;
this.sections = new Section[maxSection - minSection];
} }
@Override @Override
@ -76,14 +80,12 @@ public class DynamicChunk extends Chunk {
} }
} }
@Override
public @NotNull Map<Integer, Section> getSections() {
return sectionMap;
}
@Override @Override
public @NotNull Section getSection(int section) { public @NotNull Section getSection(int section) {
return sectionMap.computeIfAbsent(section, key -> new Section()); final int index = section - minSection;
Section result = sections[index];
if (result == null) sections[index] = result = new Section();
return result;
} }
@Override @Override
@ -110,7 +112,7 @@ public class DynamicChunk extends Chunk {
} }
} }
// Retrieve the block from state id // Retrieve the block from state id
final Section section = getOptionalSection(y); final Section section = sections[ChunkUtils.getSectionAt(y) + minSection];
if (section == null) return Block.AIR; // Section is unloaded if (section == null) return Block.AIR; // Section is unloaded
final int blockStateId = section.blockPalette().get(toChunkRelativeCoordinate(x), y, toChunkRelativeCoordinate(z)); final int blockStateId = section.blockPalette().get(toChunkRelativeCoordinate(x), y, toChunkRelativeCoordinate(z));
if (blockStateId == -1) return Block.AIR; // Section is empty if (blockStateId == -1) return Block.AIR; // Section is empty
@ -139,16 +141,19 @@ public class DynamicChunk extends Chunk {
@Override @Override
public Chunk copy(@NotNull Instance instance, int chunkX, int chunkZ) { public Chunk copy(@NotNull Instance instance, int chunkX, int chunkZ) {
DynamicChunk dynamicChunk = new DynamicChunk(instance, chunkX, chunkZ); DynamicChunk dynamicChunk = new DynamicChunk(instance, chunkX, chunkZ);
for (var entry : sectionMap.int2ObjectEntrySet()) { Arrays.setAll(dynamicChunk.sections, value -> {
dynamicChunk.sectionMap.put(entry.getIntKey(), entry.getValue().clone()); final Section s = sections[value];
} return s != null ? s.clone() : null;
});
dynamicChunk.entries.putAll(entries); dynamicChunk.entries.putAll(entries);
return dynamicChunk; return dynamicChunk;
} }
@Override @Override
public void reset() { public void reset() {
this.sectionMap.values().forEach(Section::clear); for (Section section : sections) {
if (section != null) section.clear();
}
this.entries.clear(); this.entries.clear();
} }
@ -173,8 +178,7 @@ public class DynamicChunk extends Chunk {
} }
// Data // Data
final BinaryWriter writer = new BinaryWriter(); final BinaryWriter writer = new BinaryWriter();
for (int i = 0; i < 16; i++) { // TODO: variable section count for (Section section : sections) {
final Section section = sectionMap.get(i);
if (section != null) { if (section != null) {
final Palette blockPalette = section.blockPalette(); final Palette blockPalette = section.blockPalette();
writer.writeShort((short) blockPalette.size()); writer.writeShort((short) blockPalette.size());
@ -206,12 +210,12 @@ public class DynamicChunk extends Chunk {
List<byte[]> skyLights = new ArrayList<>(); List<byte[]> skyLights = new ArrayList<>();
List<byte[]> blockLights = new ArrayList<>(); List<byte[]> blockLights = new ArrayList<>();
for (int i = 0; i < 16; i++) { // TODO: variable section count int index = 0;
final Section section = sectionMap.get(i); for (Section section : sections) {
final int index = i+1; index++;
if(section != null){ if (section != null) {
final var skyLight = section.getSkyLight(); final byte[] skyLight = section.getSkyLight();
final var blockLight = section.getBlockLight(); final byte[] blockLight = section.getBlockLight();
if (!ArrayUtils.empty(skyLight)) { if (!ArrayUtils.empty(skyLight)) {
skyLights.add(skyLight); skyLights.add(skyLight);
skyMask.set(index); skyMask.set(index);
@ -220,7 +224,7 @@ public class DynamicChunk extends Chunk {
blockLights.add(blockLight); blockLights.add(blockLight);
blockMask.set(index); blockMask.set(index);
} }
}else{ } else {
emptyBlockMask.set(index); emptyBlockMask.set(index);
emptySkyMask.set(index); emptySkyMask.set(index);
} }
@ -238,9 +242,4 @@ public class DynamicChunk extends Chunk {
} }
return xz; return xz;
} }
private @Nullable Section getOptionalSection(int y) {
final int sectionIndex = ChunkUtils.getSectionAt(y);
return sectionMap.get(sectionIndex);
}
} }