refactor(M03): extract terrain chunk queue planner

This commit is contained in:
2026-07-16 09:52:01 +04:00
parent 0d2c820ea7
commit f800e11cd2
9 changed files with 515 additions and 49 deletions
+18 -47
View File
@@ -21,6 +21,9 @@ const RENDERED_GROUND_SAMPLE_SCRIPT := preload("res://src/render/terrain/rendere
const TERRAIN_QUALITY_MESH_CACHE_SCRIPT := preload("res://src/render/terrain/terrain_quality_mesh_cache.gd")
const TERRAIN_CHUNK_LOD_POLICY_SCRIPT := preload("res://src/render/terrain/terrain_chunk_lod_policy.gd")
const TERRAIN_CHUNK_LOD_PLANNER_SCRIPT := preload("res://src/render/terrain/terrain_chunk_lod_planner.gd")
const TERRAIN_CHUNK_GEOMETRY_QUEUE_PLANNER_SCRIPT := preload(
"res://src/render/terrain/terrain_chunk_geometry_queue_planner.gd"
)
const STREAMING_TARGET_PLANNER_SCRIPT := preload("res://src/render/streaming/streaming_target_planner.gd")
const STREAMING_TARGET_POLICY_SCRIPT := preload("res://src/render/streaming/streaming_target_policy.gd")
const RENDER_BUDGET_SCHEDULER_SCRIPT := preload("res://src/render/streaming/render_budget_scheduler.gd")
@@ -184,6 +187,9 @@ const QUALITY_HIGH := "High"
var _builder
var _streaming_target_planner := STREAMING_TARGET_PLANNER_SCRIPT.new()
var _terrain_chunk_lod_planner := TERRAIN_CHUNK_LOD_PLANNER_SCRIPT.new()
var _terrain_chunk_geometry_operation_planner := (
TERRAIN_CHUNK_GEOMETRY_QUEUE_PLANNER_SCRIPT.new()
)
var _map_dir := ""
var _abs_map_dir := ""
var _wdt_info: Dictionary = {}
@@ -857,34 +863,29 @@ func _apply_streaming_target(wanted_tiles: Dictionary, retained_tiles: Dictionar
_rebuild_chunk_queues()
func _chunk_origin_for(state: Dictionary, chunk_id: int) -> Vector3:
var chunks: Array = state["data"].get("chunks", [])
if chunk_id >= 0 and chunk_id < chunks.size():
var c: Dictionary = chunks[chunk_id]
if not c.is_empty():
return c.get("origin", Vector3.ZERO)
return state.get("origin", Vector3.ZERO)
func _rebuild_chunk_queues() -> void:
_chunk_remove_queue.clear()
_chunk_create_queue.clear()
var typed_focus_position = GODOT_WORLD_POSITION_SCRIPT.new(
_last_focus_pos.x,
_last_focus_pos.y,
_last_focus_pos.z
)
var chunk_queue_plan: Dictionary = _terrain_chunk_geometry_operation_planner.plan(
_tile_states,
typed_focus_position
)
_chunk_remove_queue = chunk_queue_plan.get("remove_requests", [])
_chunk_create_queue = chunk_queue_plan.get("create_requests", [])
_tile_lod_remove_queue.clear()
_tile_lod_create_queue.clear()
for key in _tile_states.keys():
var state: Dictionary = _tile_states[key]
var current_chunks: Dictionary = state["chunks"]
var desired_lods: Dictionary = state["desired_lods"]
var current_tile_lod: int = int(state.get("tile_lod", -1))
var desired_tile_lod: int = int(state.get("desired_tile_lod", -1))
var current_tile_lod_visible: bool = bool(state.get("tile_lod_visible", false))
var desired_tile_lod_visible: bool = bool(state.get("desired_tile_lod_visible", false))
if desired_tile_lod >= 0:
for chunk_id in current_chunks.keys():
_chunk_remove_queue.append({"tile": key, "chunk": chunk_id})
if current_tile_lod != desired_tile_lod or current_tile_lod_visible != desired_tile_lod_visible:
_tile_lod_create_queue.append({
"tile": key,
@@ -905,37 +906,7 @@ func _rebuild_chunk_queues() -> void:
if current_tile_lod >= 0 and _is_tile_chunk_set_ready(state):
_tile_lod_remove_queue.append({"tile": key})
for chunk_id in current_chunks.keys():
if not desired_lods.has(chunk_id):
_chunk_remove_queue.append({"tile": key, "chunk": chunk_id})
continue
if current_chunks[chunk_id]["lod"] != desired_lods[chunk_id]:
var lod_change_origin: Vector3 = _chunk_origin_for(state, chunk_id)
var dx2: float = lod_change_origin.x - _last_focus_pos.x
var dz2: float = lod_change_origin.z - _last_focus_pos.z
_chunk_create_queue.append({
"tile": key,
"chunk": chunk_id,
"lod": desired_lods[chunk_id],
"dist_sq": dx2 * dx2 + dz2 * dz2,
})
for chunk_id in desired_lods.keys():
if current_chunks.has(chunk_id):
continue
var chunk_origin: Vector3 = _chunk_origin_for(state, chunk_id)
var dx: float = chunk_origin.x - _last_focus_pos.x
var dz: float = chunk_origin.z - _last_focus_pos.z
_chunk_create_queue.append({
"tile": key,
"chunk": chunk_id,
"lod": desired_lods[chunk_id],
"dist_sq": dx * dx + dz * dz,
})
# Sort after fully rebuilding so nearest chunks are processed first
_chunk_create_queue.sort_custom(func(a: Dictionary, b: Dictionary) -> bool:
return a["dist_sq"] < b["dist_sq"])
# Sort tile LOD creates after fully rebuilding; chunk creates arrive nearest-first.
_tile_lod_create_queue.sort_custom(func(a: Dictionary, b: Dictionary) -> bool:
return a["dist_sq"] < b["dist_sq"])