From 32bf9d2024362d45dc351c8f1d0b3b301caf1131 Mon Sep 17 00:00:00 2001 From: dusoleil Date: Sun, 18 Sep 2022 19:38:35 -0400 Subject: Organize World Gen Stuff --- Chunk.gd | 16 ------- Chunk.tscn | 36 --------------- ChunkGen.gd | 49 -------------------- ChunkLoader.gd | 66 -------------------------- ChunkedCSGMesh.gd | 6 --- ChunkedMeshInstance.gd | 6 --- ChunkedSprite3D.gd | 6 --- Main.tscn | 2 +- Rock.gd | 18 -------- Rock.tscn | 53 --------------------- World.gd | 77 ------------------------------- World.tscn | 64 ------------------------- project.godot | 4 +- world/World.gd | 77 +++++++++++++++++++++++++++++++ world/World.tscn | 64 +++++++++++++++++++++++++ world/chunk/Chunk.gd | 16 +++++++ world/chunk/Chunk.tscn | 36 +++++++++++++++ world/chunk/ChunkGen.gd | 49 ++++++++++++++++++++ world/chunk/ChunkLoader.gd | 66 ++++++++++++++++++++++++++ world/chunk/helper/ChunkedCSGMesh.gd | 6 +++ world/chunk/helper/ChunkedMeshInstance.gd | 6 +++ world/chunk/helper/ChunkedSprite3D.gd | 6 +++ world/obstacles/Rock.gd | 18 ++++++++ world/obstacles/Rock.tscn | 53 +++++++++++++++++++++ 24 files changed, 400 insertions(+), 400 deletions(-) delete mode 100644 Chunk.gd delete mode 100644 Chunk.tscn delete mode 100644 ChunkGen.gd delete mode 100644 ChunkLoader.gd delete mode 100644 ChunkedCSGMesh.gd delete mode 100644 ChunkedMeshInstance.gd delete mode 100644 ChunkedSprite3D.gd delete mode 100644 Rock.gd delete mode 100644 Rock.tscn delete mode 100644 World.gd delete mode 100644 World.tscn create mode 100644 world/World.gd create mode 100644 world/World.tscn create mode 100644 world/chunk/Chunk.gd create mode 100644 world/chunk/Chunk.tscn create mode 100644 world/chunk/ChunkGen.gd create mode 100644 world/chunk/ChunkLoader.gd create mode 100644 world/chunk/helper/ChunkedCSGMesh.gd create mode 100644 world/chunk/helper/ChunkedMeshInstance.gd create mode 100644 world/chunk/helper/ChunkedSprite3D.gd create mode 100644 world/obstacles/Rock.gd create mode 100644 world/obstacles/Rock.tscn diff --git a/Chunk.gd b/Chunk.gd deleted file mode 100644 index 7c5c1c3..0000000 --- a/Chunk.gd +++ /dev/null @@ -1,16 +0,0 @@ -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/Chunk.tscn b/Chunk.tscn deleted file mode 100644 index 8f5ea84..0000000 --- a/Chunk.tscn +++ /dev/null @@ -1,36 +0,0 @@ -[gd_scene load_steps=7 format=2] - -[ext_resource path="res://Chunk.gd" type="Script" id=1] -[ext_resource path="res://ChunkedCSGMesh.gd" type="Script" id=3] - -[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( 3 ) -_mesh = SubResource( 2 ) - -[node name="CSGMesh" type="CSGMesh" parent="Border"] -operation = 2 -script = ExtResource( 3 ) -_mesh = SubResource( 4 ) diff --git a/ChunkGen.gd b/ChunkGen.gd deleted file mode 100644 index ef29365..0000000 --- a/ChunkGen.gd +++ /dev/null @@ -1,49 +0,0 @@ -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://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/ChunkLoader.gd b/ChunkLoader.gd deleted file mode 100644 index 90cac4f..0000000 --- a/ChunkLoader.gd +++ /dev/null @@ -1,66 +0,0 @@ -extends Node - -var world = null - -var Chunk = preload("res://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/ChunkedCSGMesh.gd b/ChunkedCSGMesh.gd deleted file mode 100644 index 2b8c6db..0000000 --- a/ChunkedCSGMesh.gd +++ /dev/null @@ -1,6 +0,0 @@ -extends CSGMesh - -export(Mesh) var _mesh - -func _ready(): - self.mesh = _mesh diff --git a/ChunkedMeshInstance.gd b/ChunkedMeshInstance.gd deleted file mode 100644 index dde7eda..0000000 --- a/ChunkedMeshInstance.gd +++ /dev/null @@ -1,6 +0,0 @@ -extends MeshInstance - -export(Mesh) var _mesh - -func _ready(): - self.mesh = _mesh diff --git a/ChunkedSprite3D.gd b/ChunkedSprite3D.gd deleted file mode 100644 index c9e0be9..0000000 --- a/ChunkedSprite3D.gd +++ /dev/null @@ -1,6 +0,0 @@ -extends Sprite3D - -export(Texture) var _tex - -func _ready(): - self.texture = _tex diff --git a/Main.tscn b/Main.tscn index ea78903..54062f1 100644 --- a/Main.tscn +++ b/Main.tscn @@ -5,7 +5,7 @@ [ext_resource path="res://water/Water.tscn" type="PackedScene" id=3] [ext_resource path="res://Float.tscn" type="PackedScene" id=4] [ext_resource path="res://ship/ship/crate.tscn" type="PackedScene" id=5] -[ext_resource path="res://World.tscn" type="PackedScene" id=6] +[ext_resource path="res://world/World.tscn" type="PackedScene" id=6] [ext_resource path="res://Ship.gd" type="Script" id=7] [ext_resource path="res://FPS.gd" type="Script" id=8] [ext_resource path="res://Main.gd" type="Script" id=9] diff --git a/Rock.gd b/Rock.gd deleted file mode 100644 index 577e626..0000000 --- a/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/Rock.tscn b/Rock.tscn deleted file mode 100644 index f3c7316..0000000 --- a/Rock.tscn +++ /dev/null @@ -1,53 +0,0 @@ -[gd_scene load_steps=10 format=2] - -[ext_resource path="res://Rock.gd" type="Script" id=1] -[ext_resource path="res://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 ) diff --git a/World.gd b/World.gd deleted file mode 100644 index af2ba6a..0000000 --- a/World.gd +++ /dev/null @@ -1,77 +0,0 @@ -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.tscn b/World.tscn deleted file mode 100644 index 37056c5..0000000 --- a/World.tscn +++ /dev/null @@ -1,64 +0,0 @@ -[gd_scene load_steps=7 format=2] - -[ext_resource path="res://World.gd" type="Script" id=1] -[ext_resource path="res://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/project.godot b/project.godot index a22cfe0..26f3e5b 100644 --- a/project.godot +++ b/project.godot @@ -27,8 +27,8 @@ config/icon="res://icon.png" [autoload] Settings="*res://singletons/settings.gd" -ChunkLoader="*res://ChunkLoader.gd" -ChunkGen="*res://ChunkGen.gd" +ChunkLoader="*res://world/chunk/ChunkLoader.gd" +ChunkGen="*res://world/chunk/ChunkGen.gd" [display] 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 ) -- cgit v1.2.3