Simple metro biome

This commit is contained in:
Rob Kelly 2025-10-03 17:12:19 -06:00
parent 5272ebdc0a
commit 3a12e8218d
15 changed files with 170 additions and 31 deletions

View File

@ -36,7 +36,6 @@ settings/updates/check_for_updates=false
window/size/viewport_width=1920
window/size/viewport_height=1080
window/vsync/vsync_mode=0
[dotnet]

View File

@ -67,6 +67,7 @@ script = ExtResource("1_5f2sf")
shape = SubResource("CapsuleShape3D_qnmj6")
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
layers = 7
gi_mode = 0
mesh = SubResource("CapsuleMesh_4anbu")
@ -94,11 +95,12 @@ rebound_time_curve = SubResource("Curve_ylhto")
script = ExtResource("1_rxibo")
priority = 1
tween_resource = SubResource("Resource_244u8")
noise_emitter_layer = 1
noise_emitter_layer = 512
metadata/_custom_type_script = "uid://csjccrhj5wnx7"
[node name="MeshInstance3D" type="MeshInstance3D" parent="CameraOffset/CameraController/StrafeBankEffect/FallKickEffect/PhantomCamera3D"]
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, -1, 0, 1, -4.371139e-08, 0, 0, -0.45)
layers = 7
gi_mode = 0
mesh = SubResource("CapsuleMesh_o822w")

View File

@ -1,6 +1,9 @@
[gd_scene load_steps=5 format=3 uid="uid://nllc8ljmn37g"]
[gd_scene load_steps=7 format=3 uid="uid://nllc8ljmn37g"]
[ext_resource type="Script" uid="uid://drk82eeqk2mjs" path="res://src/world/generation/feature/generation_feature.gd" id="1_ek7o7"]
[ext_resource type="Material" uid="uid://0ja682cfcvu3" path="res://assets/materials/shaders/megalith_base.material" id="2_pko82"]
[ext_resource type="Material" uid="uid://bjbctidts4k5b" path="res://assets/materials/shaders/megalith_interior.material" id="3_yw1ox"]
[ext_resource type="PackedScene" uid="uid://cwygxhknl2h8r" path="res://src/world/generation/layer/metro_grid_layer/metro_grid_layer.tscn" id="4_fy7wq"]
[sub_resource type="PlaneMesh" id="PlaneMesh_pko82"]
size = Vector2(100000, 100000)
@ -8,15 +11,14 @@ size = Vector2(100000, 100000)
[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_ek7o7"]
data = PackedVector3Array(50000, 0, 50000, -50000, 0, 50000, 50000, 0, -50000, -50000, 0, 50000, -50000, 0, -50000, 50000, 0, -50000)
[sub_resource type="BoxShape3D" id="BoxShape3D_pko82"]
size = Vector3(200000, 200000, 200000)
[node name="Arcology" type="Node3D"]
[node name="Arcology" type="Node3D" node_paths=PackedStringArray("sub_layers")]
script = ExtResource("1_ek7o7")
sub_layers = [NodePath("MetroGridLayer"), NodePath("MetroGridLayer2"), NodePath("MetroGridLayer3"), NodePath("MetroGridLayer4")]
metadata/_custom_type_script = "uid://drk82eeqk2mjs"
[node name="InnerPyramid" type="CSGCylinder3D" parent="."]
transform = Transform3D(0.70710677, 0, 0.70710677, 0, 1, 0, -0.70710677, 0, 0.70710677, 50000, 30000, 50000)
layers = 4
visibility_range_end = 100000.0
visibility_range_end_margin = 64.0
visibility_range_fade_mode = 1
@ -29,43 +31,40 @@ smooth_faces = false
[node name="OuterPyramid" type="CSGCylinder3D" parent="InnerPyramid"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 5000, 0)
layers = 4
radius = 70000.0
height = 70000.0
sides = 4
cone = true
smooth_faces = false
material = ExtResource("2_pko82")
[node name="TopCutoff" type="CSGBox3D" parent="InnerPyramid/OuterPyramid"]
transform = Transform3D(0.70710677, 0, -0.70710677, 0, 1, 0, 0.70710677, 0, 0.70710677, 0, 30000, 0)
layers = 4
operation = 2
size = Vector3(100000, 80000, 100000)
[node name="Slots" type="CSGCombiner3D" parent="InnerPyramid/OuterPyramid"]
transform = Transform3D(0.70710677, 0, -0.70710677, 0, 1, 0, 0.70710677, 0, 0.70710677, 0, 0, 0)
operation = 2
[node name="CSGBox3D2" type="CSGBox3D" parent="InnerPyramid/OuterPyramid/Slots"]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, 0, 0, 0)
size = Vector3(100000, 71000, 10000)
[node name="CSGBox3D3" type="CSGBox3D" parent="InnerPyramid/OuterPyramid/Slots"]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, 0, 0, 0)
size = Vector3(10000, 71000, 100000)
[node name="Slots" type="CSGCombiner3D" parent="InnerPyramid"]
transform = Transform3D(0.70710677, 0, -0.70710677, 0, 1, 0, 0.70710677, 0, 0.70710677, 0, -18000, 0)
layers = 4
operation = 2
[node name="CSGBox3D2" type="CSGBox3D" parent="InnerPyramid/Slots"]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, 0, 0, 0)
layers = 4
size = Vector3(100000, 30000, 10000)
material = ExtResource("3_yw1ox")
[node name="CSGBox3D3" type="CSGBox3D" parent="InnerPyramid/Slots"]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, 0, 0, 0)
size = Vector3(10000, 30000, 100000)
transform = Transform3D(-4.3711385e-08, 0, 0.99999994, 0, 1, 0, -0.99999994, 0, -4.3711385e-08, 0, 0, 0)
layers = 4
size = Vector3(100000, 30000, 10000)
material = ExtResource("3_yw1ox")
[node name="WorldFloor" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 50000, 0, 50000)
layers = 4
mesh = SubResource("PlaneMesh_pko82")
[node name="StaticBody3D" type="StaticBody3D" parent="WorldFloor"]
@ -73,10 +72,21 @@ mesh = SubResource("PlaneMesh_pko82")
[node name="CollisionShape3D" type="CollisionShape3D" parent="WorldFloor/StaticBody3D"]
shape = SubResource("ConcavePolygonShape3D_ek7o7")
[node name="HighDetailArea" type="Area3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 50000, 0, 50000)
collision_layer = 0
collision_mask = 2
[node name="MetroGridLayer" parent="." instance=ExtResource("4_fy7wq")]
simple_construct_threshold = 0.3
bounding_box = AABB(0, 0, 0, 99497, 100, 503)
[node name="CollisionShape3D" type="CollisionShape3D" parent="HighDetailArea"]
shape = SubResource("BoxShape3D_pko82")
[node name="MetroGridLayer2" parent="." instance=ExtResource("4_fy7wq")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 99497, 0, 0)
simple_construct_threshold = 0.3
bounding_box = AABB(0, 0, 0, 503, 100, 99497)
[node name="MetroGridLayer3" parent="." instance=ExtResource("4_fy7wq")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 503, 0, 99497)
simple_construct_threshold = 0.3
bounding_box = AABB(0, 0, 0, 99497, 100, 503)
[node name="MetroGridLayer4" parent="." instance=ExtResource("4_fy7wq")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 503)
simple_construct_threshold = 0.3
bounding_box = AABB(0, 0, 0, 503, 100, 99497)

View File

@ -14,6 +14,7 @@ metadata/_custom_type_script = "uid://drk82eeqk2mjs"
[node name="WorldFloor" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 50000, 0, 50000)
layers = 4
mesh = SubResource("PlaneMesh_ydt4o")
[node name="StaticBody3D" type="StaticBody3D" parent="WorldFloor"]

View File

@ -0,0 +1,14 @@
class_name MetroConstructSimple extends GenerationFeature
@export var min_height := 48.0
@export var height_factor := 200.0
@onready var construct_box: CSGBox3D = %ConstructBox
func generate() -> void:
var value := absf(sample_noise())
var height := value * height_factor + min_height
construct_box.position.y = height / 2
construct_box.size.y = height
_generated = true

View File

@ -0,0 +1 @@
uid://dq5xadqwyspyh

View File

@ -0,0 +1,32 @@
[gd_scene load_steps=4 format=3 uid="uid://beno0v5dxtwqs"]
[ext_resource type="Script" uid="uid://dq5xadqwyspyh" path="res://src/world/generation/feature/metro/metro_construct_simple/metro_construct_simple.gd" id="1_jv74y"]
[sub_resource type="PlaneMesh" id="PlaneMesh_lhl33"]
size = Vector2(64, 64)
subdivide_width = 4
subdivide_depth = 4
[sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_y2o1w"]
points = PackedVector3Array(-31.999998, 0, -31.999998, -31.999998, 0, 31.999998, 32, 0, -31.999998, 32, 0, 31.999998)
[node name="MetroConstructSimple" type="Node3D"]
script = ExtResource("1_jv74y")
metadata/_custom_type_script = "uid://drk82eeqk2mjs"
[node name="WorldFloor" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 32, 0, 32)
layers = 2
mesh = SubResource("PlaneMesh_lhl33")
[node name="StaticBody3D" type="StaticBody3D" parent="WorldFloor"]
[node name="CollisionShape3D" type="CollisionShape3D" parent="WorldFloor/StaticBody3D"]
shape = SubResource("ConvexPolygonShape3D_y2o1w")
[node name="ConstructBox" type="CSGBox3D" parent="."]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 32, 24, 32)
layers = 2
use_collision = true
size = Vector3(48, 48, 48)

View File

@ -0,0 +1,24 @@
[gd_scene load_steps=4 format=3 uid="uid://cgvg7n525g18l"]
[ext_resource type="Script" uid="uid://drk82eeqk2mjs" path="res://src/world/generation/feature/generation_feature.gd" id="1_e5j5s"]
[sub_resource type="PlaneMesh" id="PlaneMesh_e5j5s"]
size = Vector2(64, 64)
subdivide_width = 4
subdivide_depth = 4
[sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_e5j5s"]
points = PackedVector3Array(-31.999998, 0, -31.999998, -31.999998, 0, 31.999998, 32, 0, -31.999998, 32, 0, 31.999998)
[node name="MetroEmpty" type="Node3D"]
script = ExtResource("1_e5j5s")
metadata/_custom_type_script = "uid://drk82eeqk2mjs"
[node name="WorldFloor" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 32, 0, 32)
mesh = SubResource("PlaneMesh_e5j5s")
[node name="StaticBody3D" type="StaticBody3D" parent="WorldFloor"]
[node name="CollisionShape3D" type="CollisionShape3D" parent="WorldFloor/StaticBody3D"]
shape = SubResource("ConvexPolygonShape3D_e5j5s")

View File

@ -46,9 +46,9 @@ func probe_grid(grid_pos: Vector2) -> void:
func local_to_world(local_pos: Vector2) -> Vector3:
return global_position + Vector3(local_pos.x * GRID_SIZE.x, 0, local_pos.y * GRID_SIZE.y)
return global_transform * Vector3(local_pos.x * GRID_SIZE.x, 0, local_pos.y * GRID_SIZE.y)
func world_to_local(world_pos: Vector3) -> Vector2:
var rel_pos := world_pos - global_position
var rel_pos := world_pos * global_transform
return Vector2(rel_pos.x / GRID_SIZE.x, rel_pos.z / GRID_SIZE.y)

View File

@ -0,0 +1 @@
uid://bo2pmuy3dn5y4

View File

@ -0,0 +1,41 @@
@tool
extends GridLayer
## Procedural cityscape generation
@export var empty_scene: PackedScene
@export var simple_construct_scene: PackedScene
@export var noise_scale := Vector3.ONE
@export var noise_offset := Vector3.ZERO
@export_group("Construct Parameters")
@export var simple_construct_threshold := 0.4
@export var construct_height_factor_x: Curve
@export var construct_height_factor_z: Curve
var features: Dictionary[Vector2, GenerationFeature] = {}
func generate_simple_construct(grid_pos: Vector2) -> MetroConstructSimple:
var instance: MetroConstructSimple = simple_construct_scene.instantiate()
var sample_pos := grid_pos / _plane_size()
if construct_height_factor_x:
instance.height_factor *= construct_height_factor_x.sample(sample_pos.x)
if construct_height_factor_z:
instance.height_factor *= construct_height_factor_z.sample(sample_pos.y)
return instance
func probe_grid(grid_pos: Vector2) -> void:
if grid_pos not in features:
var feature: GenerationFeature
var sample_point := local_to_world(grid_pos) * noise_scale + noise_offset
var sample := absf(WorldGenManager.noise.get_noise_3dv(sample_point))
if sample > simple_construct_threshold:
feature = generate_simple_construct(grid_pos)
else:
feature = empty_scene.instantiate()
add_child(feature)
feature.global_position = local_to_world(grid_pos)
features[grid_pos] = feature
features[grid_pos].probe()

View File

@ -0,0 +1 @@
uid://d25t2340sdrox

View File

@ -0,0 +1,11 @@
[gd_scene load_steps=4 format=3 uid="uid://cwygxhknl2h8r"]
[ext_resource type="Script" uid="uid://d25t2340sdrox" path="res://src/world/generation/layer/metro_grid_layer/metro_grid_layer.gd" id="1_ng6r6"]
[ext_resource type="PackedScene" uid="uid://cgvg7n525g18l" path="res://src/world/generation/feature/metro/metro_empty.tscn" id="2_47xjc"]
[ext_resource type="PackedScene" uid="uid://beno0v5dxtwqs" path="res://src/world/generation/feature/metro/metro_construct_simple/metro_construct_simple.tscn" id="3_woad2"]
[node name="MetroGridLayer" type="Node3D"]
script = ExtResource("1_ng6r6")
empty_scene = ExtResource("2_47xjc")
simple_construct_scene = ExtResource("3_woad2")
grid_size = Vector2(64, 64)

View File

@ -10,4 +10,5 @@ offset = Vector3(1024, 1024, 1024)
[node name="WorldGenManager" type="Node"]
script = ExtResource("1_7xvag")
noise = SubResource("FastNoiseLite_7xvag")
med_detail_radius = 8192.0
metadata/_custom_type_script = "uid://7frynyj4vspc"

File diff suppressed because one or more lines are too long