refactor(M03): extract WMO placement resolver
This commit is contained in:
@@ -9,6 +9,9 @@ const SPLAT_TILE_SCRIPT := preload("res://src/resources/splat_adt_tile.gd")
|
||||
const CONTROL_SPLAT_TILE_SCRIPT := preload("res://src/resources/control_splat_adt_tile.gd")
|
||||
const WMO_STREAMING_SCRIPT := preload("res://src/resources/wmo_streaming_resource.gd")
|
||||
const WMO_BUILDER_SCRIPT := preload("res://addons/mpq_extractor/loaders/wmo_builder.gd")
|
||||
const WMO_PLACEMENT_RESOLVER_SCRIPT := preload(
|
||||
"res://src/render/wmo/wmo_placement_resolver.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")
|
||||
@@ -277,6 +280,7 @@ var _wmo_scene_resource_cache: Dictionary = {}
|
||||
var _wmo_scene_cache_missing: Dictionary = {}
|
||||
var _wmo_scene_load_requests: Dictionary = {}
|
||||
var _wmo_missing_cache: Dictionary = {}
|
||||
var _wmo_placement_resolver := WMO_PLACEMENT_RESOLVER_SCRIPT.new()
|
||||
var _m2_scene_cache: Dictionary = {}
|
||||
var _m2_animated_scene_cache: Dictionary = {}
|
||||
var _m2_static_animation_cache: Dictionary = {}
|
||||
@@ -3557,7 +3561,11 @@ func _process_wmo_build_jobs() -> void:
|
||||
var placement: Dictionary = placement_variant
|
||||
var name_id: int = int(placement.get("name_id", -1))
|
||||
if name_id >= 0 and name_id < wmo_names.size():
|
||||
var unique_key := _wmo_unique_key(placement, tile_key, index)
|
||||
var unique_key := _wmo_placement_resolver.resolve_unique_key(
|
||||
placement,
|
||||
tile_key,
|
||||
index
|
||||
)
|
||||
if _wmo_registry.has(unique_key):
|
||||
var entry: Dictionary = _wmo_registry[unique_key]
|
||||
var entry_refs: Dictionary = entry["refs"]
|
||||
@@ -3578,7 +3586,9 @@ func _process_wmo_build_jobs() -> void:
|
||||
refs.append(unique_key)
|
||||
_start_wmo_render_build(unique_key, instance, render_resource)
|
||||
else:
|
||||
var normalized_rel := _normalize_wmo_rel_path(rel_path)
|
||||
var normalized_rel := _wmo_placement_resolver.normalize_relative_path(
|
||||
rel_path
|
||||
)
|
||||
if _wmo_render_load_requests.has(normalized_rel):
|
||||
advance_job = false
|
||||
else:
|
||||
@@ -3676,12 +3686,8 @@ func _drain_wmo_render_loads() -> void:
|
||||
_wmo_render_missing_cache[normalized_rel] = true
|
||||
|
||||
|
||||
func _normalize_wmo_rel_path(rel_path: String) -> String:
|
||||
return rel_path.replace("\\", "/").to_lower()
|
||||
|
||||
|
||||
func _get_wmo_render_or_request(rel_path: String) -> Resource:
|
||||
var normalized_rel := _normalize_wmo_rel_path(rel_path)
|
||||
var normalized_rel := _wmo_placement_resolver.normalize_relative_path(rel_path)
|
||||
if normalized_rel.is_empty():
|
||||
return null
|
||||
if _wmo_render_cache.has(normalized_rel):
|
||||
@@ -3706,7 +3712,7 @@ func _get_wmo_render_or_request(rel_path: String) -> Resource:
|
||||
|
||||
|
||||
func _get_wmo_scene_or_request(rel_path: String) -> PackedScene:
|
||||
var normalized_rel := _normalize_wmo_rel_path(rel_path)
|
||||
var normalized_rel := _wmo_placement_resolver.normalize_relative_path(rel_path)
|
||||
if normalized_rel.is_empty():
|
||||
return null
|
||||
if _wmo_scene_resource_cache.has(normalized_rel):
|
||||
@@ -3748,10 +3754,7 @@ func _get_wmo_scene_or_request(rel_path: String) -> PackedScene:
|
||||
func _instantiate_wmo_render_root(rel_path: String, placement: Dictionary) -> Node3D:
|
||||
var root := Node3D.new()
|
||||
root.name = rel_path.get_file().get_basename()
|
||||
root.position = placement.get("pos", Vector3.ZERO)
|
||||
root.rotation = placement.get("rot", Vector3.ZERO)
|
||||
var scale_value: float = float(placement.get("scale", 1.0))
|
||||
root.scale = Vector3.ONE * scale_value
|
||||
root.transform = _wmo_placement_resolver.resolve_world_transform(placement)
|
||||
return root
|
||||
|
||||
|
||||
@@ -3893,10 +3896,7 @@ func _instantiate_wmo_scene(rel_path: String, scene: PackedScene, placement: Dic
|
||||
instance.free()
|
||||
return null
|
||||
instance.name = rel_path.get_file().get_basename()
|
||||
instance.position = placement.get("pos", Vector3.ZERO)
|
||||
instance.rotation = placement.get("rot", Vector3.ZERO)
|
||||
var scale_value: float = float(placement.get("scale", 1.0))
|
||||
instance.scale = Vector3.ONE * scale_value
|
||||
instance.transform = _wmo_placement_resolver.resolve_world_transform(placement)
|
||||
return instance
|
||||
|
||||
|
||||
@@ -4020,16 +4020,6 @@ func _unregister_tile_wmos(state: Dictionary) -> void:
|
||||
state["wmo_building"] = false
|
||||
|
||||
|
||||
func _wmo_unique_key(placement: Dictionary, tile_key: String, idx: int) -> String:
|
||||
var uid: int = int(placement.get("unique_id", -1))
|
||||
# uniqueId is always set in vanilla/3.3.5a MODF data, but older baked caches
|
||||
# predating the ADTLoader unique_id field will miss it. Fall back to a
|
||||
# per-tile synthetic key — no cross-tile dedup, but also no collisions.
|
||||
if uid > 0:
|
||||
return "uid:%d" % uid
|
||||
return "tile:%s:%d" % [tile_key, idx]
|
||||
|
||||
|
||||
func _clear_wmo_registry() -> void:
|
||||
_wmo_render_build_jobs.clear()
|
||||
_wmo_render_build_queue.clear()
|
||||
@@ -4898,10 +4888,7 @@ func _instantiate_wmo_world(rel_path: String, placement: Dictionary) -> Node3D:
|
||||
instance.name = rel_path.get_file().get_basename()
|
||||
# WMOs are parented to _terrain_root, whose position absorbs the editor
|
||||
# offset — use world-space placement.pos directly (no tile_origin subtraction).
|
||||
instance.position = placement.get("pos", Vector3.ZERO)
|
||||
instance.rotation = placement.get("rot", Vector3.ZERO)
|
||||
var scale_value: float = float(placement.get("scale", 1.0))
|
||||
instance.scale = Vector3.ONE * scale_value
|
||||
instance.transform = _wmo_placement_resolver.resolve_world_transform(placement)
|
||||
if not enable_occlusion_culling:
|
||||
var occluders := instance.get_node_or_null("Occluders")
|
||||
if occluders != null:
|
||||
|
||||
Reference in New Issue
Block a user