refactor(M03): extract M2 placement grouper
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
class_name M2PlacementGrouper
|
||||
extends RefCounted
|
||||
|
||||
## Stateless ADT M2 placement validation, normalization and transform grouping.
|
||||
|
||||
const M2_PLACEMENT_TRANSFORM_RESOLVER_SCRIPT := preload(
|
||||
"res://src/render/m2/m2_placement_transform_resolver.gd"
|
||||
)
|
||||
|
||||
|
||||
## Groups valid placements by normalized relative M2 path while preserving
|
||||
## placement order inside each group. Returned containers are caller-owned.
|
||||
func group_placements(
|
||||
tile_origin: Vector3,
|
||||
m2_names: PackedStringArray,
|
||||
m2_placements: Array
|
||||
) -> Dictionary:
|
||||
var groups: Dictionary = {}
|
||||
var placement_transform_resolver := (
|
||||
M2_PLACEMENT_TRANSFORM_RESOLVER_SCRIPT.new()
|
||||
)
|
||||
for placement_variant in m2_placements:
|
||||
if not (placement_variant is Dictionary):
|
||||
continue
|
||||
var placement: Dictionary = placement_variant
|
||||
var name_id: int = int(placement.get("name_id", -1))
|
||||
if name_id < 0 or name_id >= m2_names.size():
|
||||
continue
|
||||
|
||||
var normalized_relative_path := _normalize_relative_path(m2_names[name_id])
|
||||
if normalized_relative_path.is_empty():
|
||||
continue
|
||||
|
||||
var world_position: Vector3 = placement.get("pos", Vector3.ZERO)
|
||||
var local_position := world_position - tile_origin
|
||||
var rotation_radians: Vector3 = placement.get("rot", Vector3.ZERO)
|
||||
var scale_value := float(placement.get("scale", 1.0))
|
||||
var placement_basis: Basis = placement_transform_resolver.resolve_basis(
|
||||
rotation_radians,
|
||||
normalized_relative_path
|
||||
)
|
||||
var origin_offset: Vector3 = placement_transform_resolver.resolve_origin_offset(
|
||||
rotation_radians,
|
||||
normalized_relative_path,
|
||||
scale_value
|
||||
)
|
||||
var local_transform := Transform3D(
|
||||
placement_basis.scaled(Vector3.ONE * maxf(scale_value, 0.0001)),
|
||||
local_position + origin_offset
|
||||
)
|
||||
|
||||
if not groups.has(normalized_relative_path):
|
||||
groups[normalized_relative_path] = []
|
||||
(groups[normalized_relative_path] as Array).append(local_transform)
|
||||
return groups
|
||||
|
||||
|
||||
func _normalize_relative_path(relative_path: String) -> String:
|
||||
var normalized_relative_path := relative_path.replace("\\", "/")
|
||||
if (
|
||||
normalized_relative_path.ends_with(".mdx")
|
||||
or normalized_relative_path.ends_with(".mdl")
|
||||
):
|
||||
normalized_relative_path = normalized_relative_path.get_basename() + ".m2"
|
||||
return normalized_relative_path
|
||||
Reference in New Issue
Block a user