From ae4f4dba0cab278e4f630243afde1264882d129a Mon Sep 17 00:00:00 2001 From: Rob Kelly Date: Fri, 3 Oct 2025 17:27:07 -0600 Subject: [PATCH] Utility component to automatically set visibility range based on defined LOD boundaries --- src/util/auto_range.gd | 25 +++++++++++++++++++ src/util/auto_range.gd.uid | 1 + .../generation/feature/arcology/arcology.tscn | 15 ++++++++--- .../generation/feature/arcology/empty.tscn | 8 +++++- .../metro_construct_simple.tscn | 13 +++++++++- .../generation/feature/metro/metro_empty.tscn | 8 +++++- .../worldgen_manager/worldgen_manager.gd | 4 +-- .../worldgen_manager/worldgen_manager.tscn | 1 - 8 files changed, 66 insertions(+), 9 deletions(-) create mode 100644 src/util/auto_range.gd create mode 100644 src/util/auto_range.gd.uid diff --git a/src/util/auto_range.gd b/src/util/auto_range.gd new file mode 100644 index 0000000..16d82bb --- /dev/null +++ b/src/util/auto_range.gd @@ -0,0 +1,25 @@ +class_name AutoRange extends Node +## Component that automatically adjusts the visibility range of its parent to match LOD bounds + +enum LODLevel { + LOW, + MEDIUM, + HIGH, +} + +@export var lod_level: LODLevel +@export_range(0.0, 1.0) var end_margin_pct := 0.05 + + +func _ready() -> void: + var target: GeometryInstance3D = get_parent() + match lod_level: + LODLevel.LOW: + target.visibility_range_end = WorldGenManager.low_detail_radius + LODLevel.MEDIUM: + target.visibility_range_end = WorldGenManager.med_detail_radius + LODLevel.HIGH: + target.visibility_range_end = WorldGenManager.high_detail_radius + + target.visibility_range_end_margin = end_margin_pct * target.visibility_range_end + queue_free() diff --git a/src/util/auto_range.gd.uid b/src/util/auto_range.gd.uid new file mode 100644 index 0000000..f7dcab9 --- /dev/null +++ b/src/util/auto_range.gd.uid @@ -0,0 +1 @@ +uid://cv0o1lirqeq44 diff --git a/src/world/generation/feature/arcology/arcology.tscn b/src/world/generation/feature/arcology/arcology.tscn index c4a7eae..b31b108 100644 --- a/src/world/generation/feature/arcology/arcology.tscn +++ b/src/world/generation/feature/arcology/arcology.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=7 format=3 uid="uid://nllc8ljmn37g"] +[gd_scene load_steps=8 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"] +[ext_resource type="Script" uid="uid://cv0o1lirqeq44" path="res://src/util/auto_range.gd" id="4_kox75"] [sub_resource type="PlaneMesh" id="PlaneMesh_pko82"] size = Vector2(100000, 100000) @@ -19,8 +20,6 @@ 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 use_collision = true radius = 60000.0 @@ -62,6 +61,11 @@ layers = 4 size = Vector3(100000, 30000, 10000) material = ExtResource("3_yw1ox") +[node name="AutoRange" type="Node" parent="InnerPyramid"] +script = ExtResource("4_kox75") +end_margin_pct = 0.01 +metadata/_custom_type_script = "uid://cv0o1lirqeq44" + [node name="WorldFloor" type="MeshInstance3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 50000, 0, 50000) layers = 4 @@ -72,6 +76,11 @@ mesh = SubResource("PlaneMesh_pko82") [node name="CollisionShape3D" type="CollisionShape3D" parent="WorldFloor/StaticBody3D"] shape = SubResource("ConcavePolygonShape3D_ek7o7") +[node name="AutoRange" type="Node" parent="WorldFloor"] +script = ExtResource("4_kox75") +end_margin_pct = 0.01 +metadata/_custom_type_script = "uid://cv0o1lirqeq44" + [node name="MetroGridLayer" parent="." instance=ExtResource("4_fy7wq")] simple_construct_threshold = 0.3 bounding_box = AABB(0, 0, 0, 99497, 100, 503) diff --git a/src/world/generation/feature/arcology/empty.tscn b/src/world/generation/feature/arcology/empty.tscn index 4da483f..b971d6e 100644 --- a/src/world/generation/feature/arcology/empty.tscn +++ b/src/world/generation/feature/arcology/empty.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=4 format=3 uid="uid://dawv6mbpr4d3c"] +[gd_scene load_steps=5 format=3 uid="uid://dawv6mbpr4d3c"] [ext_resource type="Script" uid="uid://drk82eeqk2mjs" path="res://src/world/generation/feature/generation_feature.gd" id="1_ydt4o"] +[ext_resource type="Script" uid="uid://cv0o1lirqeq44" path="res://src/util/auto_range.gd" id="2_q70le"] [sub_resource type="PlaneMesh" id="PlaneMesh_ydt4o"] size = Vector2(100000, 100000) @@ -21,3 +22,8 @@ mesh = SubResource("PlaneMesh_ydt4o") [node name="CollisionShape3D" type="CollisionShape3D" parent="WorldFloor/StaticBody3D"] shape = SubResource("ConcavePolygonShape3D_q70le") + +[node name="AutoRange" type="Node" parent="WorldFloor"] +script = ExtResource("2_q70le") +lod_level = 1 +metadata/_custom_type_script = "uid://cv0o1lirqeq44" diff --git a/src/world/generation/feature/metro/metro_construct_simple/metro_construct_simple.tscn b/src/world/generation/feature/metro/metro_construct_simple/metro_construct_simple.tscn index e08168a..62a0778 100644 --- a/src/world/generation/feature/metro/metro_construct_simple/metro_construct_simple.tscn +++ b/src/world/generation/feature/metro/metro_construct_simple/metro_construct_simple.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=4 format=3 uid="uid://beno0v5dxtwqs"] +[gd_scene load_steps=5 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"] +[ext_resource type="Script" uid="uid://cv0o1lirqeq44" path="res://src/util/auto_range.gd" id="2_74b57"] [sub_resource type="PlaneMesh" id="PlaneMesh_lhl33"] size = Vector2(64, 64) @@ -24,9 +25,19 @@ mesh = SubResource("PlaneMesh_lhl33") [node name="CollisionShape3D" type="CollisionShape3D" parent="WorldFloor/StaticBody3D"] shape = SubResource("ConvexPolygonShape3D_y2o1w") +[node name="AutoRange" type="Node" parent="WorldFloor"] +script = ExtResource("2_74b57") +lod_level = 1 +metadata/_custom_type_script = "uid://cv0o1lirqeq44" + [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) + +[node name="AutoRange" type="Node" parent="ConstructBox"] +script = ExtResource("2_74b57") +lod_level = 1 +metadata/_custom_type_script = "uid://cv0o1lirqeq44" diff --git a/src/world/generation/feature/metro/metro_empty.tscn b/src/world/generation/feature/metro/metro_empty.tscn index 18e333c..d8ff478 100644 --- a/src/world/generation/feature/metro/metro_empty.tscn +++ b/src/world/generation/feature/metro/metro_empty.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=4 format=3 uid="uid://cgvg7n525g18l"] +[gd_scene load_steps=5 format=3 uid="uid://cgvg7n525g18l"] [ext_resource type="Script" uid="uid://drk82eeqk2mjs" path="res://src/world/generation/feature/generation_feature.gd" id="1_e5j5s"] +[ext_resource type="Script" uid="uid://cv0o1lirqeq44" path="res://src/util/auto_range.gd" id="2_xbnbu"] [sub_resource type="PlaneMesh" id="PlaneMesh_e5j5s"] size = Vector2(64, 64) @@ -22,3 +23,8 @@ mesh = SubResource("PlaneMesh_e5j5s") [node name="CollisionShape3D" type="CollisionShape3D" parent="WorldFloor/StaticBody3D"] shape = SubResource("ConvexPolygonShape3D_e5j5s") + +[node name="AutoRange" type="Node" parent="WorldFloor"] +script = ExtResource("2_xbnbu") +lod_level = 1 +metadata/_custom_type_script = "uid://cv0o1lirqeq44" diff --git a/src/world/generation/worldgen_manager/worldgen_manager.gd b/src/world/generation/worldgen_manager/worldgen_manager.gd index 3bc7312..71555d9 100644 --- a/src/world/generation/worldgen_manager/worldgen_manager.gd +++ b/src/world/generation/worldgen_manager/worldgen_manager.gd @@ -6,9 +6,9 @@ class_name WorldGenManagerType extends Node ## Generate features with the lowest detail, like large distant structures, within this radius @export var low_detail_radius := 100000.0 ## Generate features with medium detail, like buildings, within this radius -@export var med_detail_radius := 1024.0 +@export var med_detail_radius := 8192.0 ## Generate features with high detail, like small complicated objects, within this radius -@export var high_detail_radius := 64.0 +@export var high_detail_radius := 128.0 ## Get the world-space coordinate to generate around. diff --git a/src/world/generation/worldgen_manager/worldgen_manager.tscn b/src/world/generation/worldgen_manager/worldgen_manager.tscn index abd56b9..00e3fa1 100644 --- a/src/world/generation/worldgen_manager/worldgen_manager.tscn +++ b/src/world/generation/worldgen_manager/worldgen_manager.tscn @@ -10,5 +10,4 @@ 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"