extends SceneTree ## Beweis-Probe (Karte t_b0edb807, WEGWERF — nicht Teil der Suite): ## Editor-Renderprobe für „Farbe je Objekt“ — 3 verschieden gefärbte Objekte ## (tint-Feld) im echten Map Builder, ungefärbtes Objekt daneben als Referenz ## (Pack-Farbe). Speichert einen Screenshot (PROBE_PNG-Umgebungsvariable). ## Aufruf: xvfb-run -a godot4 --path . --rendering-driver opengl3 \ ## -s res://tests/probe_tint_render.gd const PLATZ := [ {"id": "barrel_001", "pos": [8.0, 0.0, 8.0], "scale": 1.5, "rot_y_deg": 30.0, "tint": [0.5, 0.52, 0.3]}, # Oliv (Palette) {"id": "box_001", "pos": [14.0, 0.0, 6.0], "scale": 1.0, "rot_y_deg": 0.0, "tint": [0.92, 0.92, 0.92]}, # Weiß (Palette) {"id": "tank_001", "pos": [2.0, 0.0, 16.0], "scale": 1.0, "rot_y_deg": 200.0, "tint": [0.32, 0.23, 0.14]}, # Dunkelbraun (Palette) {"id": "apc_001", "pos": [-8.0, 0.0, 14.0], "scale": 1.0, "rot_y_deg": 0.0}, ] func _initialize() -> void: _run.call_deferred() func _run() -> void: # GLB-Quelle = Client-Repo (dort liegen NACH D11-Camo die aktuellen GLBs # mit Camo-Textur). Damit zeigen Editor-Probe und Client-Probe DENSELBEN # Asset-Stand — genau das ist der Beweis (Editor-Ansicht == Spiel-Ansicht). # Ohne diese Zeile würde der Editor die Alt-GLBs aus dem Match-Server- # Lager laden (Quelle 1 hat Vorrang) und der Farb-Beweis vergliche # unterschiedliche Asset-Stände. ProjectSettings.set_setting("scopedvr/editor/glb_quellen", ["../scopedvr-client/assets/objekte"]) load("res://src/viewport/glb_mesh_store.gd").call("cache_leeren") var scene: PackedScene = load("res://scenes/main.tscn") var main = scene.instantiate() root.add_child(main) await process_frame await process_frame # Erst NACH _ready setzen — die Main-UI setzt ihren Fensterzustand selbst # (maximiert/Lage-Restore) und überschreibt frühere Größen (xvfb ohne WM). DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) DisplayServer.window_set_size(Vector2i(2328, 1310)) for p in PLATZ: (main.doc["objects"] as Array).append(p.duplicate(true)) main.call("_after_structure_change") await process_frame await process_frame var cam = main.get("camera") if cam != null: cam.set("distance", 28.0) # nah ran — Objekte sollen das Bild füllen cam.call("focus_on", Vector3(4.0, 0.0, 10.0)) await process_frame await process_frame # Beweis-Zeilen: die 3 tint-Objekte tragen das Surface-Override mit der # doc-Farbe (bei echten GLBs UND bei Platzhaltern); das ungefärbte echte # GLB hat KEINEN Surface-Override (Pack-Farbe bleibt sichtbar). # (VOR der Auswahl geprüft — die Auswahl legt ihr eigenes # material_override auf das markierte Objekt.) var builder = main.get("view_builder") var pruef_ok := true for i in PLATZ.size(): var marker = builder.object_markers[i] var mi := marker.get_child(0) as MeshInstance3D var ov := mi.get_surface_override_material(0) var obj: Dictionary = PLATZ[i] if obj.has("tint"): var soll_c := Color(obj["tint"][0], obj["tint"][1], obj["tint"][2]) var ok := ov is BaseMaterial3D \ and (ov as BaseMaterial3D).albedo_color.is_equal_approx(soll_c) if not ok: pruef_ok = false print("PRUEF FAIL: obj %d (%s) albedo=%s (soll %s)" % [i, obj["id"], str((ov as BaseMaterial3D).albedo_color if ov is BaseMaterial3D else "?"), str(soll_c)]) else: print("PRUEF ok: obj %d (%s) albedo=%s" % [i, obj["id"], str((ov as BaseMaterial3D).albedo_color)]) else: var ok2 := ov == null and mi.material_override == null if not ok2: pruef_ok = false print("PRUEF FAIL: obj %d (%s) hat Override ohne tint-Feld" % [i, obj["id"]]) else: print("PRUEF ok: obj %d (%s) ohne Override (Pack-Farbe)" % [i, obj["id"]]) await process_frame await process_frame await process_frame await process_frame # APC (ungefärbt, Objekt 3) auswählen — NUR für den Screenshot: der # Inspektor zeigt dann das Farbfeld-Raster mit „Farbe: Pack-Farbe“, # während die 3 gefärbten Objekte ihre tint-Farben unverändert zeigen. # PROBE_NO_SELECT=1 → kein Auswahl (reiner Farb-Vergleich zum Client). if OS.get_environment("PROBE_NO_SELECT") == "": main.interaction.call("select_object", 3) await process_frame await process_frame var pfad := OS.get_environment("PROBE_PNG") if pfad.is_empty(): pfad = "user://probe_tint_editor.png" var img := root.get_viewport().get_texture().get_image() img.save_png(pfad) print("Bild: %s (%dx%d)" % [pfad, img.get_width(), img.get_height()]) print("PROBE_TINT_EDITOR_%s" % ("OK" if pruef_ok else "FAIL")) quit(0 if pruef_ok else 1)