Skip to content
This repository has been archived by the owner on Feb 24, 2024. It is now read-only.

Send Lighting Immediately #131

Merged
merged 11 commits into from
Feb 4, 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
1 change: 1 addition & 0 deletions demo/src/main/java/net/minestom/demo/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public static void main(String[] args) {
commandManager.register(new ConfigCommand());
commandManager.register(new SidebarCommand());
commandManager.register(new SetEntityType());
commandManager.register(new RelightCommand());

commandManager.setUnknownCommandCallback((sender, command) -> sender.sendMessage(Component.text("Unknown command", NamedTextColor.RED)));

Expand Down
12 changes: 11 additions & 1 deletion demo/src/main/java/net/minestom/demo/PlayerInit.java
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,16 @@ public class PlayerInit {
InstanceManager instanceManager = MinecraftServer.getInstanceManager();

InstanceContainer instanceContainer = instanceManager.createInstanceContainer(DimensionType.OVERWORLD);
instanceContainer.setGenerator(unit -> unit.modifier().fillHeight(0, 40, Block.STONE));
instanceContainer.setGenerator(unit -> {
unit.modifier().fillHeight(0, 40, Block.STONE);

if (unit.absoluteStart().blockY() < 40 && unit.absoluteEnd().blockY() > 40) {
unit.modifier().setBlock(unit.absoluteStart().blockX(), 40, unit.absoluteStart().blockZ(), Block.TORCH);
}
});
instanceContainer.setChunkSupplier(LightingChunk::new);
instanceContainer.setTimeRate(0);
instanceContainer.setTime(18000);

// var i2 = new InstanceContainer(UUID.randomUUID(), DimensionType.OVERWORLD, null, NamespaceID.from("minestom:demo"));
// instanceManager.registerInstance(i2);
Expand All @@ -185,6 +193,8 @@ public class PlayerInit {
// CompletableFuture.runAsync(() -> {
// CompletableFuture.allOf(chunks.toArray(CompletableFuture[]::new)).join();
// System.out.println("load end");
// LightingChunk.relight(instanceContainer, instanceContainer.getChunks());
// System.out.println("light end");
// });

inventory = new Inventory(InventoryType.CHEST_1_ROW, Component.text("Test inventory"));
Expand Down
21 changes: 21 additions & 0 deletions demo/src/main/java/net/minestom/demo/commands/RelightCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package net.minestom.demo.commands;

import net.minestom.server.command.builder.Command;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.LightingChunk;

public class RelightCommand extends Command {
public RelightCommand() {
super("relight");
setDefaultExecutor((source, args) -> {
if (source instanceof Player player) {
long start = System.currentTimeMillis();
source.sendMessage("Relighting...");
LightingChunk.relight(player.getInstance(), player.getInstance().getChunks());
source.sendMessage("Relighted " + player.getInstance().getChunks().size() + " chunks in " + (System.currentTimeMillis() - start) + "ms");
player.getInstance().getChunks().forEach(chunk -> chunk.sendChunk(player));
source.sendMessage("Chunks Received");
}
});
}
}
70 changes: 22 additions & 48 deletions src/main/java/net/minestom/server/instance/DynamicChunk.java
Original file line number Diff line number Diff line change
Expand Up @@ -210,24 +210,7 @@ public void reset() {
}

private @NotNull ChunkDataPacket createChunkPacket() {
final NBTCompound heightmapsNBT;
// TODO: don't hardcode heightmaps
// Heightmap
{
int dimensionHeight = getInstance().getDimensionType().getHeight();
int[] motionBlocking = new int[16 * 16];
int[] worldSurface = new int[16 * 16];
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
motionBlocking[x + z * 16] = 0;
worldSurface[x + z * 16] = dimensionHeight - 1;
}
}
final int bitsForHeight = MathUtils.bitsToRepresent(dimensionHeight);
heightmapsNBT = NBT.Compound(Map.of(
"MOTION_BLOCKING", NBT.LongArray(encodeBlocks(motionBlocking, bitsForHeight)),
"WORLD_SURFACE", NBT.LongArray(encodeBlocks(worldSurface, bitsForHeight))));
}
final NBTCompound heightmapsNBT = computeHeightmap();
// Data

final byte[] data;
Expand All @@ -238,44 +221,35 @@ public void reset() {
}));
}

if (this instanceof LightingChunk light) {
if (light.lightCache.isValid()) {
return new ChunkDataPacket(chunkX, chunkZ,
new ChunkData(heightmapsNBT, data, entries),
createLightData(true));
} else {
// System.out.println("Regenerating light for chunk " + chunkX + " " + chunkZ);
LightingChunk.updateAfterGeneration(light);
return new ChunkDataPacket(chunkX, chunkZ,
new ChunkData(heightmapsNBT, data, entries),
createEmptyLight());
}
}

return new ChunkDataPacket(chunkX, chunkZ,
new ChunkData(heightmapsNBT, data, entries),
createLightData(true)
createLightData()
);
}

@NotNull UpdateLightPacket createLightPacket() {
return new UpdateLightPacket(chunkX, chunkZ, createLightData(false));
protected NBTCompound computeHeightmap() {
// TODO: don't hardcode heightmaps
// Heightmap
int dimensionHeight = getInstance().getDimensionType().getHeight();
int[] motionBlocking = new int[16 * 16];
int[] worldSurface = new int[16 * 16];
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
motionBlocking[x + z * 16] = 0;
worldSurface[x + z * 16] = dimensionHeight - 1;
}
}
final int bitsForHeight = MathUtils.bitsToRepresent(dimensionHeight);
return NBT.Compound(Map.of(
"MOTION_BLOCKING", NBT.LongArray(encodeBlocks(motionBlocking, bitsForHeight)),
"WORLD_SURFACE", NBT.LongArray(encodeBlocks(worldSurface, bitsForHeight))));
}

private LightData createEmptyLight() {
BitSet skyMask = new BitSet();
BitSet blockMask = new BitSet();
BitSet emptySkyMask = new BitSet();
BitSet emptyBlockMask = new BitSet();
List<byte[]> skyLights = new ArrayList<>();
List<byte[]> blockLights = new ArrayList<>();

return new LightData(skyMask, blockMask,
emptySkyMask, emptyBlockMask,
skyLights, blockLights);
@NotNull UpdateLightPacket createLightPacket() {
return new UpdateLightPacket(chunkX, chunkZ, createLightData());
}

protected LightData createLightData(boolean sendLater) {
protected LightData createLightData() {
BitSet skyMask = new BitSet();
BitSet blockMask = new BitSet();
BitSet emptySkyMask = new BitSet();
Expand Down Expand Up @@ -346,7 +320,7 @@ private void assertLock() {
70409299, 70409299, 0, 69273666, 69273666, 0, 68174084, 68174084, 0, Integer.MIN_VALUE,
0, 5};

private static long[] encodeBlocks(int[] blocks, int bitsPerEntry) {
static long[] encodeBlocks(int[] blocks, int bitsPerEntry) {
final long maxEntryValue = (1L << bitsPerEntry) - 1;
final char valuesPerLong = (char) (64 / bitsPerEntry);
final int magicIndex = 3 * (valuesPerLong - 1);
Expand Down
Loading
Loading