summaryrefslogtreecommitdiffstats
path: root/world
diff options
context:
space:
mode:
authordusoleil <howcansocksbereal@gmail.com>2022-09-19 10:32:24 -0400
committerdusoleil <howcansocksbereal@gmail.com>2022-09-19 10:32:24 -0400
commit51a0664a1c2265adddbf4c42d4eda747c8ea8aaf (patch)
tree1bcdb3bcee5a0c1e303d55a001158ec906810329 /world
parent9bc2a0767e15d4dde7fd6231b07882d6456af71e (diff)
downloadgame_jam49-51a0664a1c2265adddbf4c42d4eda747c8ea8aaf.tar.gz
game_jam49-51a0664a1c2265adddbf4c42d4eda747c8ea8aaf.zip
Add Levels of Detail per Chunk
Diffstat (limited to 'world')
-rw-r--r--world/World.gd37
-rw-r--r--world/World.tscn4
-rw-r--r--world/chunk/Chunk.gd37
-rw-r--r--world/chunk/Chunk.tscn10
-rw-r--r--world/chunk/ChunkGen.gd87
-rw-r--r--world/chunk/ChunkLoader.gd32
-rw-r--r--world/obstacles/Rock.gd18
-rw-r--r--world/obstacles/Rock.tscn32
-rw-r--r--world/obstacles/Rock_coll.tres4
-rw-r--r--world/obstacles/Rock_lowres_mesh.tres4
10 files changed, 143 insertions, 122 deletions
diff --git a/world/World.gd b/world/World.gd
index 2c8d822..04c3ef1 100644
--- a/world/World.gd
+++ b/world/World.gd
@@ -4,11 +4,13 @@ export(NodePath) var traveler = null
onready var _traveler = get_node(traveler)
export var acceleration = 10.0
-onready var lod_distance = $"ChunkRenderDistance"
-onready var lod_mid = $"ChunkRenderMid"
-onready var lod_close = $"ChunkRenderClose"
+onready var chunk_render_distance = $"ChunkRenderDistance"
+onready var chunk_render_mid = $"ChunkRenderMid"
+onready var chunk_render_close = $"ChunkRenderClose"
-onready var chunk_render_distance = lod_distance.get_node("Radius").shape.radius
+onready var lod_distance = chunk_render_distance.get_node("Radius").shape.radius
+onready var lod_mid = chunk_render_mid.get_node("Radius").shape.radius
+onready var lod_close = chunk_render_close.get_node("Radius").shape.radius
onready var chunk_half_size = $"Chunks/Chunk/Size".shape.radius
onready var chunk_size = chunk_half_size * 2.0
@@ -33,7 +35,7 @@ func _on_ChunkRenderClose_area_entered(area:Area):
area.lod_update()
func _on_ChunkRenderDistance_area_exited(area:Area):
- ChunkLoader.free_chunk(chunk_coords(v2_coords(area.transform.origin)))
+ free_chunk(area)
func _on_ChunkRenderMid_area_exited(area:Area):
area.lod = area.LOD.DISTANCE
@@ -52,26 +54,13 @@ func travel(direction:Vector3):
$"Chunks".add_central_force(direction*acceleration)
func _physics_process(_state):
- chunk_process()
+ ChunkLoader.chunk_update()
var stick = Input.get_axis("ship_down","ship_up")
if stick != 0.0:
self.travel(Vector3.FORWARD*stick)
-func v2_coords(coords:Vector3):
- return Vector2(coords.x,coords.z)
-
-func chunk_coords(coords:Vector2):
- return coords.snapped(Vector2(chunk_size,chunk_size))
-
-func chunk_process():
- var gen_center = -v2_coords($"Chunks".transform.origin)
- var gen_radius = chunk_render_distance
- var gen_radius_rounded = stepify(gen_radius, chunk_size)
- for x in range(-gen_radius_rounded, gen_radius_rounded+chunk_size, chunk_size):
- for y in range(-gen_radius_rounded, gen_radius_rounded+chunk_size, chunk_size):
- var gen_coords = Vector2(x,y)
- if gen_coords.length() > gen_radius:
- continue
- var coords = chunk_coords(gen_coords + gen_center)
- ChunkLoader.add_chunk(coords)
- ChunkLoader.chunk_update()
+func free_chunk(chunk):
+ var coords = chunk.transform.origin
+ coords = Vector2(coords.x,coords.z)
+ coords = coords.snapped(Vector2(chunk_size,chunk_size))
+ ChunkLoader.free_chunk(coords)
diff --git a/world/World.tscn b/world/World.tscn
index 81b2201..647f47b 100644
--- a/world/World.tscn
+++ b/world/World.tscn
@@ -4,10 +4,10 @@
[ext_resource path="res://world/chunk/Chunk.tscn" type="PackedScene" id=3]
[sub_resource type="SphereShape" id=24]
-radius = 500.0
+radius = 1000.0
[sub_resource type="SphereShape" id=25]
-radius = 300.0
+radius = 500.0
[sub_resource type="SphereShape" id=26]
radius = 150.0
diff --git a/world/chunk/Chunk.gd b/world/chunk/Chunk.gd
index 1860c84..4356caf 100644
--- a/world/chunk/Chunk.gd
+++ b/world/chunk/Chunk.gd
@@ -3,15 +3,30 @@ extends Area
enum LOD {DISTANCE,MID,CLOSE}
var lod = -1
+onready var lod_distance = $"gen_tree/lod_distance"
+onready var lod_mid = $"gen_tree/lod_mid"
+onready var lod_close = $"gen_tree/lod_close"
+
+onready var _collision_enabled = lod_close.collision_layer
+
+func _ready():
+ lod_update()
+
func lod_update():
- return
- for obj in $"gen_tree".get_children():
- match lod:
- LOD.CLOSE:
- obj.lod_close()
- LOD.MID:
- obj.lod_mid()
- LOD.DISTANCE:
- obj.lod_distance()
- _:
- obj.lod_distance()
+ match lod:
+ LOD.CLOSE:
+ lod_distance.visible = false
+ lod_mid.visible = true
+ lod_close.collision_layer = _collision_enabled
+ LOD.MID:
+ lod_distance.visible = false
+ lod_mid.visible = true
+ lod_close.collision_layer = 0
+ LOD.DISTANCE:
+ lod_distance.visible = true
+ lod_mid.visible = false
+ lod_close.collision_layer = 0
+ _:
+ lod_distance.visible = true
+ lod_mid.visible = false
+ lod_close.collision_layer = 0
diff --git a/world/chunk/Chunk.tscn b/world/chunk/Chunk.tscn
index 4ce985b..5377ae9 100644
--- a/world/chunk/Chunk.tscn
+++ b/world/chunk/Chunk.tscn
@@ -34,3 +34,13 @@ _mesh = SubResource( 2 )
operation = 2
script = ExtResource( 2 )
_mesh = SubResource( 4 )
+
+[node name="gen_tree" type="Spatial" parent="."]
+
+[node name="lod_distance" type="Spatial" parent="gen_tree"]
+
+[node name="lod_mid" type="Spatial" parent="gen_tree"]
+
+[node name="lod_close" type="StaticBody" parent="gen_tree"]
+collision_layer = 8
+collision_mask = 0
diff --git a/world/chunk/ChunkGen.gd b/world/chunk/ChunkGen.gd
index 75d3736..e71cc57 100644
--- a/world/chunk/ChunkGen.gd
+++ b/world/chunk/ChunkGen.gd
@@ -25,10 +25,18 @@ func rng_2dv(coords:Vector2):
self.rng.seed = hash(coords)
func gen_chunk(chunk):
- var gen_tree = Spatial.new()
- gen_tree.name = "gen_tree"
- chunk.add_child(gen_tree)
- gen_rocks(chunk)
+ gen_distance(chunk,chunk.get_node("gen_tree/lod_distance"))
+ gen_mid(chunk,chunk.get_node("gen_tree/lod_mid"))
+ gen_close(chunk,chunk.get_node("gen_tree/lod_close"))
+
+func gen_distance(chunk,tree):
+ gen_lowres_rocks(chunk,tree)
+
+func gen_mid(chunk,tree):
+ gen_rocks(chunk,tree)
+
+func gen_close(chunk,tree):
+ gen_rock_hitboxes(chunk,tree)
func v2_coords(coords:Vector3):
return Vector2(coords.x,coords.z)
@@ -36,15 +44,43 @@ func v2_coords(coords:Vector3):
func v3_coords(coords:Vector2):
return Vector3(coords.x,0.0,coords.y)
-func iterate_chunk(chunk,step:Vector2,cb:FuncRef):
+func iterate_chunk(chunk,tree,step:Vector2,cb:FuncRef,data):
var chunk_size_rounded = Vector2(chunk_half_size,chunk_half_size).snapped(step)
for x in range(-chunk_size_rounded.x,chunk_size_rounded.x,step.x):
for y in range(-chunk_size_rounded.y,chunk_size_rounded.y,step.y):
- cb.call_func(chunk,Vector2(x,y))
+ cb.call_func(chunk,tree,Vector2(x,y),data)
+
+func make_multimesh(name,cnt,mesh):
+ var multi_inst = MultiMeshInstance.new()
+ multi_inst.name = name
+ var multi = MultiMesh.new()
+ multi_inst.multimesh = multi
+ multi.transform_format = MultiMesh.TRANSFORM_3D
+ multi.instance_count = cnt
+ multi.visible_instance_count = 0
+ multi.mesh = mesh
+ return multi_inst
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):
+func gen_rocks(chunk,tree):
+ rock_mesh.material = rock_mat
+ var multi = make_multimesh("rocks",200,rock_mesh)
+ tree.add_child(multi)
+ iterate_chunk(chunk, multi.multimesh, Vector2(10.0,10.0), funcref(self,"rock_rng"), [0.4,0.6,1.0,4.0,1.0,funcref(self,"make_rock")])
+
+var rock_lowres_mesh = preload("res://world/obstacles/Rock_lowres_mesh.tres")
+func gen_lowres_rocks(chunk,tree):
+ rock_lowres_mesh.material = rock_mat
+ var multi = make_multimesh("rocks",50,rock_lowres_mesh)
+ tree.add_child(multi)
+ iterate_chunk(chunk, multi.multimesh, Vector2(20.0,20.0), funcref(self,"rock_rng"), [0.4,0.6,2.0,8.0,0.5,funcref(self,"make_rock")])
+
+var rock_coll = preload("res://world/obstacles/Rock_coll.tres")
+func gen_rock_hitboxes(chunk,tree):
+ iterate_chunk(chunk, tree, Vector2(20.0,20.0), funcref(self,"rock_rng"), [0.4,0.6,1.0,4.0,1.0,funcref(self,"make_rock_hitbox")])
+
+func rock_rng(chunk,rocks,chunk_coords:Vector2,data):
var coords = v3_coords(chunk_coords)
var basis = Basis()
var world_coords = chunk_coords + v2_coords(chunk.transform.origin)
@@ -52,28 +88,23 @@ func make_rock(chunk,chunk_coords:Vector2):
var rng_val = self.rng.randf_range(0.0,TAU)
basis = Basis(Vector3.UP,rng_val) * basis
var noise_val = self.noise.get_noise_2dv(world_coords * 0.125)
- if noise_val < 0.4:
+ if noise_val < data[0]:
return
- noise_val = min(noise_val,0.6)
- noise_val -= 0.4
- noise_val /= 0.2
- noise_val = lerp(1.0,4.0,noise_val)
+ noise_val = min(noise_val,data[1])
+ noise_val -= data[0]
+ noise_val /= data[1] - data[0]
+ noise_val = lerp(data[2],data[3],noise_val)
basis = basis.scaled(Vector3.ONE*noise_val)
- coords.y += (noise_val*5.0)-5.0
- var gen_tree = chunk.get_node("gen_tree")
- var rocks = gen_tree.get_node("rocks").multimesh
+ basis = basis.scaled(Vector3(1.0,data[4],1.0))
+ coords.y += (noise_val*data[4]*5.0)-5.0
+ data[5].call_func(rocks,Transform(basis,coords))
+
+func make_rock(rocks,xform:Transform):
rocks.visible_instance_count += 1
- rocks.set_instance_transform(rocks.visible_instance_count-1, Transform(basis,coords))
+ rocks.set_instance_transform(rocks.visible_instance_count-1, xform)
-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"))
+func make_rock_hitbox(rocks,xform:Transform):
+ var shape = CollisionShape.new()
+ shape.shape = rock_coll
+ shape.transform = xform
+ rocks.add_child(shape)
diff --git a/world/chunk/ChunkLoader.gd b/world/chunk/ChunkLoader.gd
index 2e01bca..42e40bb 100644
--- a/world/chunk/ChunkLoader.gd
+++ b/world/chunk/ChunkLoader.gd
@@ -3,13 +3,13 @@ extends Node
var world = null
var Chunk = preload("res://world/chunk/Chunk.tscn")
-var chunks = {}
var loaded_chunks = {}
var chunk_thread = Thread.new()
var mtx = Mutex.new()
var sgnl = Semaphore.new()
var exit = false
var chunk_to_load = null
+var chunk_to_len
func _ready():
chunk_thread.start(self, "chunk_loader")
@@ -21,8 +21,11 @@ func _exit_tree():
mtx.unlock()
chunk_thread.wait_to_finish()
-func add_chunk(coords:Vector2):
- chunks[coords] = coords.length()
+func v2_coords(coords:Vector3):
+ return Vector2(coords.x,coords.z)
+
+func chunk_coords(coords:Vector2):
+ return coords.snapped(Vector2(world.chunk_size,world.chunk_size))
func free_chunk(coords:Vector2):
if !loaded_chunks.has(coords):
@@ -33,23 +36,35 @@ func free_chunk(coords:Vector2):
loaded_chunks.erase(coords)
func chunk_update():
+ var chunks = {}
+ var gen_center = -v2_coords(world.get_node("Chunks").transform.origin)
+ var gen_radius = world.lod_distance
+ var gen_radius_rounded = stepify(gen_radius, world.chunk_size)
+ for x in range(-gen_radius_rounded, gen_radius_rounded+world.chunk_size, world.chunk_size):
+ for y in range(-gen_radius_rounded, gen_radius_rounded+world.chunk_size, world.chunk_size):
+ var gen_coords = Vector2(x,y)
+ if gen_coords.length() > gen_radius:
+ continue
+ var coords = chunk_coords(gen_coords + gen_center)
+ chunks[coords] = coords.length()
var closest_unloaded_chunk = null
var closest_len = 0.0
for chunk in chunks.keys():
if !loaded_chunks.has(chunk):
- if closest_unloaded_chunk == null || closest_len > chunks[chunk]:
+ var chunk_len = chunks[chunk]
+ if closest_unloaded_chunk == null || closest_len > chunk_len:
closest_unloaded_chunk = chunk
- closest_len = chunks[chunk]
+ closest_len = chunk_len
if closest_unloaded_chunk != null:
mtx.lock()
if chunk_to_load == null:
chunk_to_load = closest_unloaded_chunk
+ chunk_to_len = closest_len
sgnl.post()
mtx.unlock()
for chunk in loaded_chunks.keys():
if !chunks.has(chunk):
free_chunk(chunk)
- chunks = {}
func chunk_loader():
while true:
@@ -57,15 +72,18 @@ func chunk_loader():
mtx.lock()
var x = exit
var coords = chunk_to_load
+ var owo = chunk_to_len
chunk_to_load = null
mtx.unlock()
if x:
break
var chunk = Chunk.instance()
chunk.transform.origin = Vector3(coords.x,0.0,coords.y)
+ owo -= world.chunk_size
+ chunk.lod = 2 if owo <= world.lod_close else 1 if owo <= world.lod_mid else 0
ChunkGen.gen_chunk(chunk)
self.call_deferred("finish_chunk", chunk)
func finish_chunk(chunk):
world.get_node("Chunks").add_child(chunk)
- loaded_chunks[Vector2(chunk.transform.origin.x,chunk.transform.origin.z)] = weakref(chunk)
+ loaded_chunks[v2_coords(chunk.transform.origin)] = weakref(chunk)
diff --git a/world/obstacles/Rock.gd b/world/obstacles/Rock.gd
deleted file mode 100644
index 577e626..0000000
--- a/world/obstacles/Rock.gd
+++ /dev/null
@@ -1,18 +0,0 @@
-extends StaticBody
-
-onready var collision_enabled = self.collision_layer
-
-func lod_distance():
- $"MeshInstance".visible = false
- $"MeshInstance2".visible = true
- self.collision_layer = 0
-
-func lod_mid():
- $"MeshInstance".visible = true
- $"MeshInstance2".visible = false
- self.collision_layer = 0
-
-func lod_close():
- $"MeshInstance".visible = true
- $"MeshInstance2".visible = false
- self.collision_layer = collision_enabled
diff --git a/world/obstacles/Rock.tscn b/world/obstacles/Rock.tscn
deleted file mode 100644
index 819e9a8..0000000
--- a/world/obstacles/Rock.tscn
+++ /dev/null
@@ -1,32 +0,0 @@
-[gd_scene load_steps=7 format=2]
-
-[ext_resource path="res://world/obstacles/Rock.gd" type="Script" id=1]
-[ext_resource path="res://world/chunk/helper/ChunkedMeshInstance.gd" type="Script" id=2]
-[ext_resource path="res://world/obstacles/Rock_mesh.tres" type="PrismMesh" id=3]
-[ext_resource path="res://world/obstacles/Rock_mat.tres" type="Material" id=4]
-
-[sub_resource type="ConvexPolygonShape" id=2]
-points = PoolVector3Array( 2.5, -5, 2.5, 2.5, -5, -2.5, -2.5, -5, -2.5, -2.5, -5, 2.5, 0, 5, 2.5, 0, 5, -2.5 )
-
-[sub_resource type="CubeMesh" id=9]
-size = Vector3( 5, 10, 5 )
-
-[node name="Rock" type="StaticBody"]
-collision_layer = 8
-collision_mask = 0
-script = ExtResource( 1 )
-
-[node name="CollisionShape" type="CollisionShape" parent="."]
-shape = SubResource( 2 )
-
-[node name="MeshInstance" type="MeshInstance" parent="."]
-visible = false
-material_override = ExtResource( 4 )
-script = ExtResource( 2 )
-_mesh = ExtResource( 3 )
-
-[node name="MeshInstance2" type="MeshInstance" parent="."]
-visible = false
-material_override = ExtResource( 4 )
-script = ExtResource( 2 )
-_mesh = SubResource( 9 )
diff --git a/world/obstacles/Rock_coll.tres b/world/obstacles/Rock_coll.tres
new file mode 100644
index 0000000..b06d080
--- /dev/null
+++ b/world/obstacles/Rock_coll.tres
@@ -0,0 +1,4 @@
+[gd_resource type="ConvexPolygonShape" format=2]
+
+[resource]
+points = PoolVector3Array( 2.5, -5, 2.5, 2.5, -5, -2.5, -2.5, -5, -2.5, -2.5, -5, 2.5, 0, 5, 2.5, 0, 5, -2.5 )
diff --git a/world/obstacles/Rock_lowres_mesh.tres b/world/obstacles/Rock_lowres_mesh.tres
new file mode 100644
index 0000000..910d7f6
--- /dev/null
+++ b/world/obstacles/Rock_lowres_mesh.tres
@@ -0,0 +1,4 @@
+[gd_resource type="CubeMesh" format=2]
+
+[resource]
+size = Vector3( 5, 10, 5 )