refactor(M03): extract WMO placement registry
This commit is contained in:
@@ -12,6 +12,9 @@ const WMO_BUILDER_SCRIPT := preload("res://addons/mpq_extractor/loaders/wmo_buil
|
||||
const WMO_PLACEMENT_RESOLVER_SCRIPT := preload(
|
||||
"res://src/render/wmo/wmo_placement_resolver.gd"
|
||||
)
|
||||
const WMO_PLACEMENT_REGISTRY_SCRIPT := preload(
|
||||
"res://src/render/wmo/wmo_placement_registry.gd"
|
||||
)
|
||||
const M2_BUILDER_SCRIPT := preload("res://addons/mpq_extractor/loaders/m2_builder.gd")
|
||||
const M2_NATIVE_ANIMATED_BUILDER_SCRIPT := preload("res://addons/mpq_extractor/loaders/m2_native_animated_builder.gd")
|
||||
const M2_NATIVE_ANIMATOR_SCRIPT := preload("res://src/scenes/streaming/m2_native_animator.gd")
|
||||
@@ -286,7 +289,8 @@ var _m2_animated_scene_cache: Dictionary = {}
|
||||
var _m2_static_animation_cache: Dictionary = {}
|
||||
var _m2_missing_cache: Dictionary = {}
|
||||
var _world_wmo_root: Node3D
|
||||
var _wmo_registry: Dictionary = {}
|
||||
var _wmo_placement_registry := WMO_PLACEMENT_REGISTRY_SCRIPT.new()
|
||||
var _wmo_instance_nodes_by_unique_key: Dictionary = {}
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@@ -1031,7 +1035,7 @@ func render_baseline_snapshot() -> Dictionary:
|
||||
},
|
||||
"cache_entries": _tile_mesh_cache.size(),
|
||||
"m2_active_unique_ids": _m2_unique_placement_registry.active_count(),
|
||||
"wmo_instances": _wmo_registry.size(),
|
||||
"wmo_instances": _wmo_placement_registry.active_count(),
|
||||
}
|
||||
|
||||
|
||||
@@ -1313,7 +1317,7 @@ func _tick_runtime_stats(delta: float) -> void:
|
||||
m2_tiles,
|
||||
m2_multimeshes,
|
||||
m2_instances,
|
||||
_wmo_registry.size(),
|
||||
_wmo_placement_registry.active_count(),
|
||||
])
|
||||
|
||||
|
||||
@@ -3363,7 +3367,7 @@ func _wdt_has_global_wmo() -> bool:
|
||||
func _place_global_wmo() -> void:
|
||||
if not _wdt_has_global_wmo():
|
||||
return
|
||||
if _wmo_registry.has("global"):
|
||||
if _wmo_placement_registry.contains("global"):
|
||||
return
|
||||
|
||||
_ensure_world_wmo_root()
|
||||
@@ -3387,10 +3391,7 @@ func _place_global_wmo() -> void:
|
||||
|
||||
_world_wmo_root.add_child(instance)
|
||||
_set_editor_owner_recursive(instance)
|
||||
_wmo_registry["global"] = {
|
||||
"node": instance,
|
||||
"refs": {"__global__": true},
|
||||
}
|
||||
_register_wmo_instance_reference("global", "__global__", instance)
|
||||
|
||||
|
||||
func _sync_detail_assets(state: Dictionary, focus_pos: Vector3) -> Dictionary:
|
||||
@@ -3566,10 +3567,8 @@ func _process_wmo_build_jobs() -> void:
|
||||
tile_key,
|
||||
index
|
||||
)
|
||||
if _wmo_registry.has(unique_key):
|
||||
var entry: Dictionary = _wmo_registry[unique_key]
|
||||
var entry_refs: Dictionary = entry["refs"]
|
||||
entry_refs[tile_key] = true
|
||||
if _wmo_placement_registry.contains(unique_key):
|
||||
_wmo_placement_registry.add_reference(unique_key, tile_key)
|
||||
refs.append(unique_key)
|
||||
else:
|
||||
var rel_path: String = str(wmo_names[name_id]).replace("\\", "/")
|
||||
@@ -3579,10 +3578,7 @@ func _process_wmo_build_jobs() -> void:
|
||||
if instance != null:
|
||||
_world_wmo_root.add_child(instance)
|
||||
_set_editor_owner_recursive(instance)
|
||||
_wmo_registry[unique_key] = {
|
||||
"node": instance,
|
||||
"refs": {tile_key: true},
|
||||
}
|
||||
_register_wmo_instance_reference(unique_key, tile_key, instance)
|
||||
refs.append(unique_key)
|
||||
_start_wmo_render_build(unique_key, instance, render_resource)
|
||||
else:
|
||||
@@ -3602,10 +3598,11 @@ func _process_wmo_build_jobs() -> void:
|
||||
_prepare_runtime_wmo_instance(live_instance)
|
||||
_world_wmo_root.add_child(live_instance)
|
||||
_set_editor_owner_recursive(live_instance)
|
||||
_wmo_registry[unique_key] = {
|
||||
"node": live_instance,
|
||||
"refs": {tile_key: true},
|
||||
}
|
||||
_register_wmo_instance_reference(
|
||||
unique_key,
|
||||
tile_key,
|
||||
live_instance
|
||||
)
|
||||
refs.append(unique_key)
|
||||
else:
|
||||
var scene_instance := _instantiate_wmo_scene(rel_path, scene, placement)
|
||||
@@ -3613,10 +3610,11 @@ func _process_wmo_build_jobs() -> void:
|
||||
_prepare_runtime_wmo_instance(scene_instance)
|
||||
_world_wmo_root.add_child(scene_instance)
|
||||
_set_editor_owner_recursive(scene_instance)
|
||||
_wmo_registry[unique_key] = {
|
||||
"node": scene_instance,
|
||||
"refs": {tile_key: true},
|
||||
}
|
||||
_register_wmo_instance_reference(
|
||||
unique_key,
|
||||
tile_key,
|
||||
scene_instance
|
||||
)
|
||||
refs.append(unique_key)
|
||||
if advance_job:
|
||||
job["refs"] = refs
|
||||
@@ -3994,6 +3992,17 @@ func _cancel_wmo_build_job(tile_key: String) -> void:
|
||||
_wmo_build_queue.erase(tile_key)
|
||||
|
||||
|
||||
func _register_wmo_instance_reference(
|
||||
placement_key: String,
|
||||
reference_key: String,
|
||||
instance: Node3D
|
||||
) -> void:
|
||||
if placement_key.is_empty() or reference_key.is_empty() or instance == null:
|
||||
return
|
||||
_wmo_instance_nodes_by_unique_key[placement_key] = instance
|
||||
_wmo_placement_registry.add_reference(placement_key, reference_key)
|
||||
|
||||
|
||||
func _unregister_tile_wmos(state: Dictionary) -> void:
|
||||
var refs: Array = state.get("wmo_refs", [])
|
||||
var tile_key: String = String(state.get("key", ""))
|
||||
@@ -4003,18 +4012,16 @@ func _unregister_tile_wmos(state: Dictionary) -> void:
|
||||
state["wmo_building"] = false
|
||||
return
|
||||
|
||||
for unique_key in refs:
|
||||
if not _wmo_registry.has(unique_key):
|
||||
for unique_key_variant in refs:
|
||||
var unique_key := String(unique_key_variant)
|
||||
if not _wmo_placement_registry.contains(unique_key):
|
||||
continue
|
||||
var entry: Dictionary = _wmo_registry[unique_key]
|
||||
var entry_refs: Dictionary = entry["refs"]
|
||||
entry_refs.erase(tile_key)
|
||||
if entry_refs.is_empty():
|
||||
if _wmo_placement_registry.release_reference(unique_key, tile_key):
|
||||
_cancel_wmo_render_build_job(String(unique_key))
|
||||
var node: Node = entry.get("node", null)
|
||||
if node:
|
||||
var node: Node = _wmo_instance_nodes_by_unique_key.get(unique_key, null)
|
||||
if node != null and is_instance_valid(node):
|
||||
node.queue_free()
|
||||
_wmo_registry.erase(unique_key)
|
||||
_wmo_instance_nodes_by_unique_key.erase(unique_key)
|
||||
|
||||
state["wmo_refs"] = []
|
||||
state["wmo_building"] = false
|
||||
@@ -4023,14 +4030,14 @@ func _unregister_tile_wmos(state: Dictionary) -> void:
|
||||
func _clear_wmo_registry() -> void:
|
||||
_wmo_render_build_jobs.clear()
|
||||
_wmo_render_build_queue.clear()
|
||||
for entry_variant in _wmo_registry.values():
|
||||
if not (entry_variant is Dictionary):
|
||||
for node_variant in _wmo_instance_nodes_by_unique_key.values():
|
||||
if not (node_variant is Node):
|
||||
continue
|
||||
var entry: Dictionary = entry_variant
|
||||
var node: Node = entry.get("node", null)
|
||||
if node and is_instance_valid(node):
|
||||
var node := node_variant as Node
|
||||
if is_instance_valid(node):
|
||||
_queue_free_streamed_node(node)
|
||||
_wmo_registry.clear()
|
||||
_wmo_instance_nodes_by_unique_key.clear()
|
||||
_wmo_placement_registry.clear()
|
||||
if _world_wmo_root and is_instance_valid(_world_wmo_root):
|
||||
_queue_free_streamed_node(_world_wmo_root)
|
||||
_world_wmo_root = null
|
||||
|
||||
Reference in New Issue
Block a user