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>
89 lines
4.3 KiB
GDScript
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
|