diff options
author | dusoleil <howcansocksbereal@gmail.com> | 2022-09-18 19:38:35 -0400 |
---|---|---|
committer | dusoleil <howcansocksbereal@gmail.com> | 2022-09-18 19:42:01 -0400 |
commit | 32bf9d2024362d45dc351c8f1d0b3b301caf1131 (patch) | |
tree | fb6540bce94cb55c6123ecfe1327abeabea2925f /world | |
parent | ffc92ed12c6e680776d355ff9fcef70e5e28d7c8 (diff) | |
download | godot_wildjam_49-32bf9d2024362d45dc351c8f1d0b3b301caf1131.tar.gz godot_wildjam_49-32bf9d2024362d45dc351c8f1d0b3b301caf1131.zip |
Organize World Gen Stuff
Diffstat (limited to 'world')
-rw-r--r-- | world/World.gd | 77 | ||||
-rw-r--r-- | world/World.tscn | 64 | ||||
-rw-r--r-- | world/chunk/Chunk.gd | 16 | ||||
-rw-r--r-- | world/chunk/Chunk.tscn | 36 | ||||
-rw-r--r-- | world/chunk/ChunkGen.gd | 49 | ||||
-rw-r--r-- | world/chunk/ChunkLoader.gd | 66 | ||||
-rw-r--r-- | world/chunk/helper/ChunkedCSGMesh.gd | 6 | ||||
-rw-r--r-- | world/chunk/helper/ChunkedMeshInstance.gd | 6 | ||||
-rw-r--r-- | world/chunk/helper/ChunkedSprite3D.gd | 6 | ||||
-rw-r--r-- | world/obstacles/Rock.gd | 18 | ||||
-rw-r--r-- | world/obstacles/Rock.tscn | 53 |
11 files changed, 397 insertions, 0 deletions
diff --git a/world/World.gd b/world/World.gd new file mode 100644 index 0000000..af2ba6a --- /dev/null +++ b/world/World.gd @@ -0,0 +1,77 @@ +extends Spatial + +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 = lod_distance.get_node("Radius").shape.radius + +onready var chunk_half_size = $"Chunks/Chunk/Size".shape.radius +onready var chunk_size = chunk_half_size * 2.0 + +func _ready(): + ChunkLoader.world = self + ChunkGen.chunk_half_size = self.chunk_half_size + +func _on_ChunkRenderDistance_area_entered(area:Area): + if area.lod < area.LOD.DISTANCE: + area.lod = area.LOD.DISTANCE + area.lod_update() + +func _on_ChunkRenderMid_area_entered(area:Area): + if area.lod < area.LOD.MID: + area.lod = area.LOD.MID + area.lod_update() + +func _on_ChunkRenderClose_area_entered(area:Area): + if area.lod < area.LOD.CLOSE: + area.lod = area.LOD.CLOSE + area.lod_update() + +func _on_ChunkRenderDistance_area_exited(area:Area): + area.queue_free() + +func _on_ChunkRenderMid_area_exited(area:Area): + area.lod = area.LOD.DISTANCE + area.lod_update() + +func _on_ChunkRenderClose_area_exited(area:Area): + area.lod = area.LOD.MID + area.lod_update() + +func travel(direction:Vector3): + var heading = _traveler.global_transform.basis + heading = Basis(Vector3.UP*heading.get_euler().y) + direction = -direction + direction = heading * direction + direction = direction.normalized() + $"Chunks".add_central_force(direction*acceleration) + +func _physics_process(_state): + chunk_process() + 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() diff --git a/world/World.tscn b/world/World.tscn new file mode 100644 index 0000000..81b2201 --- /dev/null +++ b/world/World.tscn @@ -0,0 +1,64 @@ +[gd_scene load_steps=7 format=2] + +[ext_resource path="res://world/World.gd" type="Script" id=1] +[ext_resource path="res://world/chunk/Chunk.tscn" type="PackedScene" id=3] + +[sub_resource type="SphereShape" id=24] +radius = 500.0 + +[sub_resource type="SphereShape" id=25] +radius = 300.0 + +[sub_resource type="SphereShape" id=26] +radius = 150.0 + +[sub_resource type="BoxShape" id=23] + +[node name="World" type="Spatial"] +script = ExtResource( 1 ) +acceleration = 50.0 + +[node name="ChunkRenderDistance" type="Area" parent="."] +collision_layer = 0 +collision_mask = 32 + +[node name="Radius" type="CollisionShape" parent="ChunkRenderDistance"] +shape = SubResource( 24 ) + +[node name="ChunkRenderMid" type="Area" parent="."] +collision_layer = 0 +collision_mask = 32 + +[node name="Radius" type="CollisionShape" parent="ChunkRenderMid"] +shape = SubResource( 25 ) + +[node name="ChunkRenderClose" type="Area" parent="."] +collision_layer = 0 +collision_mask = 32 + +[node name="Radius" type="CollisionShape" parent="ChunkRenderClose"] +shape = SubResource( 26 ) + +[node name="Chunks" type="RigidBody" parent="."] +collision_layer = 0 +collision_mask = 0 +can_sleep = false +axis_lock_linear_y = true +axis_lock_angular_x = true +axis_lock_angular_y = true +axis_lock_angular_z = true +linear_damp = 0.5 + +[node name="CollisionShape" type="CollisionShape" parent="Chunks"] +shape = SubResource( 23 ) + +[node name="Chunk" parent="Chunks" instance=ExtResource( 3 )] +visible = false +collision_layer = 0 + +[connection signal="area_entered" from="ChunkRenderDistance" to="." method="_on_ChunkRenderDistance_area_entered"] +[connection signal="area_exited" from="ChunkRenderDistance" to="." method="_on_ChunkRenderDistance_area_exited"] +[connection signal="area_entered" from="ChunkRenderMid" to="." method="_on_ChunkRenderMid_area_entered"] +[connection signal="area_exited" from="ChunkRenderMid" to="." method="_on_ChunkRenderMid_area_exited"] +[connection signal="area_entered" from="ChunkRenderClose" to="." method="_on_ChunkRenderClose_area_entered"] +[connection signal="area_exited" from="ChunkRenderClose" to="." method="_on_ChunkRenderClose_area_exited"] diff --git a/world/chunk/Chunk.gd b/world/chunk/Chunk.gd new file mode 100644 index 0000000..7c5c1c3 --- /dev/null +++ b/world/chunk/Chunk.gd @@ -0,0 +1,16 @@ +extends Area + +enum LOD {DISTANCE,MID,CLOSE} +var lod = -1 + +func lod_update(): + 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() diff --git a/world/chunk/Chunk.tscn b/world/chunk/Chunk.tscn new file mode 100644 index 0000000..4ce985b --- /dev/null +++ b/world/chunk/Chunk.tscn @@ -0,0 +1,36 @@ +[gd_scene load_steps=7 format=2] + +[ext_resource path="res://world/chunk/Chunk.gd" type="Script" id=1] +[ext_resource path="res://world/chunk/helper/ChunkedCSGMesh.gd" type="Script" id=2] + +[sub_resource type="SphereShape" id=1] +radius = 50.0 + +[sub_resource type="SpatialMaterial" id=3] +flags_unshaded = true +params_cull_mode = 2 +albedo_color = Color( 0.937255, 0, 1, 1 ) + +[sub_resource type="PlaneMesh" id=2] +size = Vector2( 100, 100 ) + +[sub_resource type="PlaneMesh" id=4] +size = Vector2( 98, 98 ) + +[node name="Chunk" type="Area"] +collision_layer = 32 +collision_mask = 0 +script = ExtResource( 1 ) + +[node name="Size" type="CollisionShape" parent="."] +shape = SubResource( 1 ) + +[node name="Border" type="CSGMesh" parent="."] +material_override = SubResource( 3 ) +script = ExtResource( 2 ) +_mesh = SubResource( 2 ) + +[node name="CSGMesh" type="CSGMesh" parent="Border"] +operation = 2 +script = ExtResource( 2 ) +_mesh = SubResource( 4 ) diff --git a/world/chunk/ChunkGen.gd b/world/chunk/ChunkGen.gd new file mode 100644 index 0000000..5e99be8 --- /dev/null +++ b/world/chunk/ChunkGen.gd @@ -0,0 +1,49 @@ +extends Node + +var chunk_half_size setget _set_chunk_size +var chunk_size + +func _set_chunk_size(val): + chunk_half_size = val + chunk_size = val * 2.0 + +onready var noise = OpenSimplexNoise.new() + +func _ready(): + randomize() + noise.seed = randi() + noise.octaves = 4 + noise.period = 64 + noise.persistence = 0.001 + noise.lacunarity = 2.0 + +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")) + +func v2_coords(coords:Vector3): + return Vector2(coords.x,coords.z) + +func v3_coords(coords:Vector2): + return Vector3(coords.x,0.0,coords.y) + +func iterate_chunk(chunk,step:Vector2,cb:FuncRef): + 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)) + +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 world_coords = chunk_coords + v2_coords(chunk.transform.origin) + var noise_val = self.noise.get_noise_2dv(world_coords) + if noise_val > 0.4: + make_rock(chunk,Transform(Basis().scaled(Vector3(2.0,2.0,2.0)),v3_coords(chunk_coords))) diff --git a/world/chunk/ChunkLoader.gd b/world/chunk/ChunkLoader.gd new file mode 100644 index 0000000..9f1d9b3 --- /dev/null +++ b/world/chunk/ChunkLoader.gd @@ -0,0 +1,66 @@ +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 + +func _ready(): + chunk_thread.start(self, "chunk_loader") + +func _exit_tree(): + mtx.lock() + exit = true + sgnl.post() + mtx.unlock() + chunk_thread.wait_to_finish() + +func add_chunk(coords:Vector2): + chunks[coords] = coords.length() + +func chunk_update(): + 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]: + closest_unloaded_chunk = chunk + closest_len = chunks[chunk] + if closest_unloaded_chunk != null: + mtx.lock() + if chunk_to_load == null: + chunk_to_load = closest_unloaded_chunk + sgnl.post() + 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) + chunks = {} + +func chunk_loader(): + while true: + sgnl.wait() + mtx.lock() + var x = exit + var coords = chunk_to_load + chunk_to_load = null + mtx.unlock() + if x: + break + var chunk = Chunk.instance() + chunk.transform.origin = Vector3(coords.x,0.0,coords.y) + 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) diff --git a/world/chunk/helper/ChunkedCSGMesh.gd b/world/chunk/helper/ChunkedCSGMesh.gd new file mode 100644 index 0000000..2b8c6db --- /dev/null +++ b/world/chunk/helper/ChunkedCSGMesh.gd @@ -0,0 +1,6 @@ +extends CSGMesh + +export(Mesh) var _mesh + +func _ready(): + self.mesh = _mesh diff --git a/world/chunk/helper/ChunkedMeshInstance.gd b/world/chunk/helper/ChunkedMeshInstance.gd new file mode 100644 index 0000000..dde7eda --- /dev/null +++ b/world/chunk/helper/ChunkedMeshInstance.gd @@ -0,0 +1,6 @@ +extends MeshInstance + +export(Mesh) var _mesh + +func _ready(): + self.mesh = _mesh diff --git a/world/chunk/helper/ChunkedSprite3D.gd b/world/chunk/helper/ChunkedSprite3D.gd new file mode 100644 index 0000000..c9e0be9 --- /dev/null +++ b/world/chunk/helper/ChunkedSprite3D.gd @@ -0,0 +1,6 @@ +extends Sprite3D + +export(Texture) var _tex + +func _ready(): + self.texture = _tex diff --git a/world/obstacles/Rock.gd b/world/obstacles/Rock.gd new file mode 100644 index 0000000..577e626 --- /dev/null +++ b/world/obstacles/Rock.gd @@ -0,0 +1,18 @@ +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 new file mode 100644 index 0000000..3b50ff3 --- /dev/null +++ b/world/obstacles/Rock.tscn @@ -0,0 +1,53 @@ +[gd_scene load_steps=10 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] + +[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="OpenSimplexNoise" id=3] +octaves = 4 +period = 32.0 + +[sub_resource type="NoiseTexture" id=4] +noise = SubResource( 3 ) + +[sub_resource type="NoiseTexture" id=5] +seamless = true +as_normalmap = true +bump_strength = 32.0 +noise = SubResource( 3 ) + +[sub_resource type="SpatialMaterial" id=6] +albedo_color = Color( 0.231373, 0.231373, 0.231373, 1 ) +albedo_texture = SubResource( 4 ) +normal_enabled = true +normal_scale = 1.0 +normal_texture = SubResource( 5 ) + +[sub_resource type="PrismMesh" id=1] +size = Vector3( 5, 10, 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 = SubResource( 6 ) +script = ExtResource( 2 ) +_mesh = SubResource( 1 ) + +[node name="MeshInstance2" type="MeshInstance" parent="."] +visible = false +material_override = SubResource( 6 ) +script = ExtResource( 2 ) +_mesh = SubResource( 9 ) |