refactor(M03): extract M2 mesh resource traversal

Work-Package: M03-RND-M2-MESH-RESOURCE-EXTRACTOR-001
Agent: sindo-main-codex
Tests: 36 headless renderer/coordinate contracts pass; checkpoint dry-run 7/7; documentation and coordination gates pass
Fidelity: preserves first-Mesh preorder and temporary PackedScene cleanup; no visual parity claim
This commit is contained in:
2026-07-17 13:02:40 +04:00
parent 6607100686
commit 7b0e1eac5f
12 changed files with 471 additions and 35 deletions
@@ -0,0 +1,34 @@
class_name M2MeshResourceExtractor
extends RefCounted
## Selects the first Mesh from loaded M2 Resources or existing Node subtrees.
## The caller owns ResourceLoader I/O, cache adoption and material preparation.
## Returns the direct Mesh Resource or the first Mesh in a temporary PackedScene
## instance. The temporary instance is freed before this method returns.
func extract_first_mesh(resource: Resource) -> Mesh:
if resource is Mesh:
return resource as Mesh
if not (resource is PackedScene):
return null
var temporary_root := (resource as PackedScene).instantiate()
if temporary_root == null:
return null
var mesh := find_first_mesh_in_subtree(temporary_root)
temporary_root.free()
return mesh
## Returns the first MeshInstance3D Mesh in depth-first preorder. The subtree
## and Mesh ownership remain unchanged.
func find_first_mesh_in_subtree(root: Node) -> Mesh:
if root == null:
return null
if root is MeshInstance3D:
return (root as MeshInstance3D).mesh
for child in root.get_children():
var mesh := find_first_mesh_in_subtree(child)
if mesh != null:
return mesh
return null
@@ -0,0 +1 @@
uid://dea4gekrxshjf