saumwacht-godot/tools/model_reference_sheet.gd
Martin Stickelbroeck c2b447610c Baseline: Saumwacht 0.15.0 (Phase 20A) vor dem Umbau zu Champions of Luneraria
Unveränderter Ausgangsstand inklusive Masterprompt und Konzeptbildern
unter assets/. .godot/ und docs/screenshots/ bleiben laut .gitignore
unversioniert; letztere sind unter ../backups gesichert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 20:00:36 +02:00

89 lines
4.3 KiB
GDScript

extends Node
## Direct icon/model comparisons; original PNGs stay unchanged.
const STAGE: Script = preload("res://tools/model_gallery_stage.gd")
var _sheet: Control
func _ready() -> void:
get_tree().create_timer(90).timeout.connect(func(): get_tree().quit(1))
var faction: String = "glutpakt"
for arg: String in OS.get_cmdline_user_args():
if arg.begins_with("--faction="):
faction = arg.trim_prefix("--faction=")
var data: Dictionary = JSON.parse_string(FileAccess.get_file_as_string("res://assets/phase4_manifest.json"))
var icons: Dictionary = JSON.parse_string(FileAccess.get_file_as_string("res://assets/phase3_manifest.json"))
var paths: Dictionary = {}
for asset: Dictionary in icons["assets"]:
paths[str(asset["id"])] = str(asset["resource_path"])
paths["worker"] = paths.get("worker_funkenleser", "")
var selected: Array[Dictionary] = []
for asset: Dictionary in data["assets"]:
if str(asset["faction"]) == faction and paths.has(str(asset["id"])):
selected.append(asset)
get_window().size = Vector2i(1600, 960)
for start: int in range(0, selected.size(), 2):
_sheet = Control.new()
_sheet.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
add_child(_sheet)
var backdrop: ColorRect = ColorRect.new()
backdrop.color = Color("10141b")
backdrop.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
_sheet.add_child(backdrop)
var margin: MarginContainer = MarginContainer.new()
margin.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
for edge: String in ["left", "top", "right", "bottom"]:
margin.add_theme_constant_override("margin_" + edge, 24)
_sheet.add_child(margin)
var layout: VBoxContainer = VBoxContainer.new()
layout.add_theme_constant_override("separation", 16)
margin.add_child(layout)
layout.add_child(_label("SAUMWACHT / " + faction.to_upper(), 29, Color("ddc898")))
layout.add_child(_label("Bildreferenz und überarbeitetes 3D-Modell · Gleiche Einheit, direkte Gegenüberstellung", 18, Color("adb6c5")))
var row: HBoxContainer = HBoxContainer.new()
row.size_flags_vertical = Control.SIZE_EXPAND_FILL
row.add_theme_constant_override("separation", 12)
layout.add_child(row)
for index: int in range(start, mini(start + 2, selected.size())):
var asset: Dictionary = selected[index]
for reference: bool in [true, false]:
var card: VBoxContainer = VBoxContainer.new()
card.size_flags_horizontal = Control.SIZE_EXPAND_FILL
row.add_child(card)
card.add_child(_label("ICON · PHASE 3" if reference else "3D-MODELL", 16, Color("aab3c2")))
if reference:
var icon: TextureRect = TextureRect.new()
# Compare against native PNG pixels, not the 256px gameplay import.
var source_image: Image = Image.load_from_file(str(paths[str(asset["id"])]))
icon.texture = ImageTexture.create_from_image(source_image)
icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
icon.custom_minimum_size.x = 350
icon.size_flags_vertical = Control.SIZE_EXPAND_FILL
card.add_child(icon)
else:
var view: Dictionary = STAGE.create(card, Vector2(350, 450))
STAGE.show_asset(view, asset)
(view["camera"] as Camera3D).size = 3.5
card.add_child(_label(str(asset["id"]).to_upper() + " · " + str(asset["name"]), 19, Color("eee6d8")))
card.add_child(_label("Originalillustration" if reference else str(int(asset["triangles"])) + " Dreiecke · GLB", 15, Color("9ca9bc")))
layout.add_child(_label("3D-Darstellung aus Godot · Modellierte Formdetails und PBR-Materialien · Bearbeitbare Blender-Quellen", 14, Color("8491a3")))
await get_tree().process_frame
await get_tree().process_frame
await RenderingServer.frame_post_draw
await get_tree().create_timer(0.2).timeout
var output: String = "res://docs/screenshots/phase4/reference-" + str(selected[start]["id"]) + ".png"
var error: Error = get_viewport().get_texture().get_image().save_png(output)
if error != OK:
printerr("Reference screenshot failed: ", output)
get_tree().quit(1)
return
print("REFERENCE_CAPTURED ", output)
_sheet.free()
get_tree().quit(0)
func _label(text: String, size: int, color: Color) -> Label:
var label: Label = Label.new()
label.text = text
label.add_theme_font_size_override("font_size", size)
label.add_theme_color_override("font_color", color)
return label