Skip to content

Commit

Permalink
make chunk rendering faster (using threads, yey!) and disable collisi…
Browse files Browse the repository at this point in the history
…on for now as it takes 400+ ms
  • Loading branch information
MiniDigger committed Apr 14, 2020
1 parent 5f6db09 commit c7ca3b1
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 22 deletions.
23 changes: 23 additions & 0 deletions export_presets.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,26 @@ application/product_name=""
application/file_description=""
application/copyright=""
application/trademarks=""

[preset.1]

name="HTML5"
platform="HTML5"
runnable=true
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="export/godotcraft.html"
patch_list=PoolStringArray( )
script_export_mode=1
script_encryption_key=""

[preset.1.options]

vram_texture_compression/for_desktop=true
vram_texture_compression/for_mobile=false
html/custom_html_shell=""
html/head_include=""
custom_template/release=""
custom_template/debug=""
1 change: 1 addition & 0 deletions project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ movement_jump={
[mono]

debugger_agent/port=50000
debugger_agent/wait_for_debugger=true
debugger_agent/wait_timeout=10000

[rendering]
Expand Down
2 changes: 1 addition & 1 deletion scripts/network/protocol/play/server/ChunkDataPacket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public override void read(DataTypes dataTypes, List<byte> data) {
chunkPos = new Vector2(dataTypes.ReadNextInt(data), dataTypes.ReadNextInt(data));
fullChunk = dataTypes.ReadNextBool(data);
chunkData = new ChunkData();
chunkData.read(dataTypes, data);
chunkData.read(dataTypes, data, fullChunk);
int num = dataTypes.ReadNextVarInt(data);
blockEntities = new List<Dictionary<string, object>>();
for (var i = 0; i < num; i++) {
Expand Down
7 changes: 2 additions & 5 deletions scripts/renderer/ChunkRenderer.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Godot;
using Godot;
using Godotcraft.scripts.world;
using Console = Godotcraft.scripts.objects.Console;

namespace Godotcraft.scripts.renderer {
public class ChunkRenderer : Godot.MeshInstance {
public class ChunkRenderer : MeshInstance {
const float CUBE_SIZE = 0.5f;

private readonly SurfaceTool tool = new SurfaceTool();
Expand Down
15 changes: 9 additions & 6 deletions scripts/world/ChunkData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public int getSectionCount() {
return sections.Length;
}

public void read(DataTypes dataTypes, List<byte> data) {
public void read(DataTypes dataTypes, List<byte> data, bool fullChunk) {
int primBitMask = dataTypes.ReadNextVarInt(data);
var heightMapNbt = dataTypes.ReadNextNbt(data);
if (heightMapNbt.ContainsKey("MOTION_BLOCKING")) {
Expand All @@ -73,14 +73,17 @@ public void read(DataTypes dataTypes, List<byte> data) {
// heightMap[i] = (long) map[i];
}
}

int biomesSize = dataTypes.ReadNextVarInt(data);
biomes = new int[biomesSize];
for (var i = 0; i < biomesSize; i++) {
biomes[i] = dataTypes.ReadNextInt(data);

if (fullChunk) {
int biomesSize = dataTypes.ReadNextVarInt(data);
biomes = new int[biomesSize];
for (var i = 0; i < biomesSize; i++) {
biomes[i] = dataTypes.ReadNextInt(data);
}
}

int dataSize = dataTypes.ReadNextVarInt(data);
// byte[] chunkData = dataTypes.ReadData(dataSize, data);
int sectionCount = numberOfSetBits(primBitMask);
sections = new ChunkSection[sectionCount];
for (var i = 0; i < sectionCount; i++) {
Expand Down
41 changes: 32 additions & 9 deletions scripts/world/ChunkHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,37 @@ public class ChunkHandler : Spatial {
private readonly BlockingCollection<Node> spawningQueue = new BlockingCollection<Node>();

private bool shouldQuit = false;
private Thread creationThread;

private int threadTarget = 10;
private List<Thread> creationThreads = new List<Thread>();

public override void _Ready() {
SingletonHandler.instance.chunkHandler = this;

creationThread = new Thread(doCreation);
creationThread.Start();
// initial thread
startNewThread();
}

public void handle(ChunkDataPacket packet) {
if (packet.chunkData.getSectionCount() == 0) return;
creationQueue.Add(packet);
GD.Print("handle, size is now " + creationQueue.Count);
GD.Print("add new packet, size is now " + creationQueue.Count);
}

private bool shouldStartNewThread() {
return creationThreads.Count >= threadTarget;
}

private void startNewThread() {
Thread creationThread = new Thread(doCreation);
creationThread.Start();
creationThreads.Add(creationThread);
}

public void doCreation() {
while (IsProcessing() && !shouldQuit) {
ChunkDataPacket packet;
if (creationQueue.TryTake(out packet, 10)) {
var watch = System.Diagnostics.Stopwatch.StartNew();
if (packet.chunkData.getSectionCount() == 0) continue;
if (GetNodeOrNull<Node>("Chunk" + packet.chunkPos) != null) {
GD.Print("Chunk already existed!");
Expand All @@ -42,13 +54,14 @@ public void doCreation() {
Node chunk = new Node {Name = "Chunk" + packet.chunkPos};
for (var i = 0; i < packet.chunkData.getSectionCount(); i++) {
ChunkSection section = packet.chunkData.getSection(i);
if(section.isEmpty()) continue;
ChunkRenderer renderer = new ChunkRenderer {
Translation = calcPos(packet.chunkPos, i),
Name = "Section@" + i
};
Timeout.TimeoutAfter(() => {
bool created = renderer.createMesh(section);
if (created) renderer.createCollision();
// if (created) renderer.createCollision();
return created;
}, TimeSpan.FromSeconds(1));
chunk.AddChild(renderer);
Expand All @@ -57,6 +70,14 @@ public void doCreation() {
if (!spawningQueue.TryAdd(chunk, 100)) {
GD.Print("failed");
}

// create new threads delayed
if (shouldStartNewThread()) {
startNewThread();
}

watch.Stop();
GD.Print("handled packet, size is now " + creationQueue.Count + ", took " + watch.ElapsedMilliseconds);
}
}

Expand All @@ -67,9 +88,11 @@ public override void _Notification(int what) {
if (what == MainLoop.NotificationWmQuitRequest) {
GD.Print("request quit");
shouldQuit = true;
creationThread.Interrupt();
creationThread.Abort();
GD.Print("Alive? " + creationThread.IsAlive);
foreach (var creationThread in creationThreads) {
creationThread.Interrupt();
creationThread.Abort();
GD.Print("Alive? " + creationThread.IsAlive);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion scripts/world/ChunkSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public int get(int index) {
}

public bool isEmpty() {
return false;
return blockCount == 0;
}

public void read(DataTypes dataTypes, List<byte> dataBytes) {
Expand Down

0 comments on commit c7ca3b1

Please sign in to comment.