From 9bc2a0767e15d4dde7fd6231b07882d6456af71e Mon Sep 17 00:00:00 2001
From: dusoleil <howcansocksbereal@gmail.com>
Date: Mon, 19 Sep 2022 06:28:21 -0400
Subject: Use MultiMesh to dramatically increase performance of generated world

---
 world/chunk/Chunk.gd       |  1 +
 world/chunk/ChunkGen.gd    | 36 ++++++++++++++++++++++++------------
 world/chunk/ChunkLoader.gd | 13 +++++++++----
 3 files changed, 34 insertions(+), 16 deletions(-)

(limited to 'world/chunk')

diff --git a/world/chunk/Chunk.gd b/world/chunk/Chunk.gd
index 7c5c1c3..1860c84 100644
--- a/world/chunk/Chunk.gd
+++ b/world/chunk/Chunk.gd
@@ -4,6 +4,7 @@ enum LOD {DISTANCE,MID,CLOSE}
 var lod = -1
 
 func lod_update():
+    return
     for obj in $"gen_tree".get_children():
         match lod:
             LOD.CLOSE:
diff --git a/world/chunk/ChunkGen.gd b/world/chunk/ChunkGen.gd
index d60b2e5..75d3736 100644
--- a/world/chunk/ChunkGen.gd
+++ b/world/chunk/ChunkGen.gd
@@ -12,8 +12,9 @@ onready var rng = RandomNumberGenerator.new()
 var _seed
 
 func _ready():
-    randomize()
-    self._seed = randi()
+    #randomize()
+    #self._seed = randi()
+    self._seed = 0
     self.noise.seed = self._seed
     self.noise.seed = 0
     self.noise.period = 16
@@ -27,7 +28,7 @@ func gen_chunk(chunk):
     var gen_tree = Spatial.new()
     gen_tree.name = "gen_tree"
     chunk.add_child(gen_tree)
-    iterate_chunk(chunk, Vector2(10.0,10.0), funcref(self,"gen_rocks"))
+    gen_rocks(chunk)
 
 func v2_coords(coords:Vector3):
     return Vector2(coords.x,coords.z)
@@ -41,14 +42,9 @@ func iterate_chunk(chunk,step:Vector2,cb:FuncRef):
         for y in range(-chunk_size_rounded.y,chunk_size_rounded.y,step.y):
             cb.call_func(chunk,Vector2(x,y))
 
-onready var Rock = preload("res://world/obstacles/Rock.tscn")
-const rock_size = 5.0
-func make_rock(chunk,xform:Transform):
-    var rock = Rock.instance()
-    rock.transform = xform
-    chunk.get_node("gen_tree").add_child(rock)
-
-func gen_rocks(chunk,chunk_coords:Vector2):
+var rock_mesh = preload("res://world/obstacles/Rock_mesh.tres")
+var rock_mat = preload("res://world/obstacles/Rock_mat.tres")
+func make_rock(chunk,chunk_coords:Vector2):
     var coords = v3_coords(chunk_coords)
     var basis = Basis()
     var world_coords = chunk_coords + v2_coords(chunk.transform.origin)
@@ -64,4 +60,20 @@ func gen_rocks(chunk,chunk_coords:Vector2):
     noise_val = lerp(1.0,4.0,noise_val)
     basis = basis.scaled(Vector3.ONE*noise_val)
     coords.y += (noise_val*5.0)-5.0
-    make_rock(chunk,Transform(basis,coords))
+    var gen_tree = chunk.get_node("gen_tree")
+    var rocks = gen_tree.get_node("rocks").multimesh
+    rocks.visible_instance_count += 1
+    rocks.set_instance_transform(rocks.visible_instance_count-1, Transform(basis,coords))
+
+func gen_rocks(chunk):
+    var multi_inst = MultiMeshInstance.new()
+    multi_inst.name = "rocks"
+    var multi = MultiMesh.new()
+    multi_inst.multimesh = multi
+    chunk.get_node("gen_tree").add_child(multi_inst)
+    multi.transform_format = MultiMesh.TRANSFORM_3D
+    multi.instance_count = 1000
+    multi.visible_instance_count = 0
+    multi.mesh = rock_mesh
+    rock_mesh.material = rock_mat
+    iterate_chunk(chunk, Vector2(10.0,10.0), funcref(self,"make_rock"))
diff --git a/world/chunk/ChunkLoader.gd b/world/chunk/ChunkLoader.gd
index 9f1d9b3..2e01bca 100644
--- a/world/chunk/ChunkLoader.gd
+++ b/world/chunk/ChunkLoader.gd
@@ -24,6 +24,14 @@ func _exit_tree():
 func add_chunk(coords:Vector2):
     chunks[coords] = coords.length()
 
+func free_chunk(coords:Vector2):
+    if !loaded_chunks.has(coords):
+        return
+    var c = loaded_chunks[coords].get_ref()
+    if c != null:
+        c.queue_free()
+    loaded_chunks.erase(coords)
+
 func chunk_update():
     var closest_unloaded_chunk = null
     var closest_len = 0.0
@@ -40,10 +48,7 @@ func chunk_update():
         mtx.unlock()
     for chunk in loaded_chunks.keys():
         if !chunks.has(chunk):
-            var c = loaded_chunks[chunk].get_ref()
-            if c != null:
-                c.queue_free()
-            loaded_chunks.erase(chunk)
+            free_chunk(chunk)
     chunks = {}
 
 func chunk_loader():
-- 
cgit v1.2.3