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
@@ -0,0 +1,102 @@
class_name TerrainChunkGeometryQueuePlanner
extends RefCounted
## Pure desired-operation planner for terrain chunk geometry queues.
const GODOT_WORLD_POSITION_SCRIPT := preload(
"res://src/domain/coordinates/godot_world_position.gd"
)
## Returns fresh nearest-first create and stable-order remove request arrays.
## The caller retains queue storage, execution order and every render side effect.
func plan(tile_states: Dictionary, focus_position: RefCounted) -> Dictionary:
var chunk_create_requests: Array = []
var chunk_remove_requests: Array = []
if (
focus_position == null
or focus_position.get_script() != GODOT_WORLD_POSITION_SCRIPT
):
return _create_plan(chunk_create_requests, chunk_remove_requests)
var focus_x_units := float(focus_position.get("x_units"))
var focus_z_units := float(focus_position.get("z_units"))
for tile_key_variant in tile_states.keys():
var tile_key := String(tile_key_variant)
var tile_state: Dictionary = tile_states[tile_key_variant]
var current_chunks: Dictionary = tile_state["chunks"]
var desired_lods: Dictionary = tile_state["desired_lods"]
var desired_tile_lod := int(tile_state.get("desired_tile_lod", -1))
if desired_tile_lod >= 0:
for chunk_id in current_chunks.keys():
chunk_remove_requests.append({"tile": tile_key, "chunk": chunk_id})
continue
for chunk_id in current_chunks.keys():
if not desired_lods.has(chunk_id):
chunk_remove_requests.append({"tile": tile_key, "chunk": chunk_id})
continue
if int(current_chunks[chunk_id]["lod"]) != int(desired_lods[chunk_id]):
chunk_create_requests.append(_create_chunk_request(
tile_key,
chunk_id,
int(desired_lods[chunk_id]),
_resolve_chunk_origin(tile_state, int(chunk_id)),
focus_x_units,
focus_z_units
))
for chunk_id in desired_lods.keys():
if current_chunks.has(chunk_id):
continue
chunk_create_requests.append(_create_chunk_request(
tile_key,
chunk_id,
int(desired_lods[chunk_id]),
_resolve_chunk_origin(tile_state, int(chunk_id)),
focus_x_units,
focus_z_units
))
chunk_create_requests.sort_custom(func(
left_request: Dictionary,
right_request: Dictionary
) -> bool:
return float(left_request["dist_sq"]) < float(right_request["dist_sq"])
)
return _create_plan(chunk_create_requests, chunk_remove_requests)
func _resolve_chunk_origin(tile_state: Dictionary, chunk_id: int) -> Vector3:
var chunks: Array = tile_state["data"].get("chunks", [])
if chunk_id >= 0 and chunk_id < chunks.size():
var chunk: Dictionary = chunks[chunk_id]
if not chunk.is_empty():
return chunk.get("origin", Vector3.ZERO)
return tile_state.get("origin", Vector3.ZERO)
func _create_chunk_request(
tile_key: String,
chunk_id: Variant,
desired_lod: int,
chunk_origin: Vector3,
focus_x_units: float,
focus_z_units: float
) -> Dictionary:
var delta_x_units := chunk_origin.x - focus_x_units
var delta_z_units := chunk_origin.z - focus_z_units
return {
"tile": tile_key,
"chunk": chunk_id,
"lod": desired_lod,
"dist_sq": delta_x_units * delta_x_units + delta_z_units * delta_z_units,
}
func _create_plan(chunk_create_requests: Array, chunk_remove_requests: Array) -> Dictionary:
return {
"create_requests": chunk_create_requests,
"remove_requests": chunk_remove_requests,
}