extends SceneTree ## Beweis-Probe (Karte t_639135dd, WEGWERF — nicht Teil der Suite): ## U6 dezente Auswahl — dasselbe Objekt (fass, echtes GLB mit Textur) auf ## Sand und auf Fels, Auswahl-Markierung im Bild. Zwei Modi über Env: ## U6_MODUS=vorher → alter Baumzustand (Vollorange) — Beweis „vorher“ ## U6_MODUS=nachher → neuer Baumzustand (Kontur, Textur sichtbar) ## Das Terrain ist eine echte Material-Schicht: linke Hälfte Sand (1), ## rechte Hälfte Fels (2) — das Objekt wird je Bild auf die eine oder ## andere Hälfte gesetzt. ## Aufruf: xvfb-run -a godot4 --path . --rendering-driver opengl3 \ ## -s res://tests/probe_u6_render.gd (mit ../scopedvr-client) const SAND := 1 const FELS := 2 func _initialize() -> void: _run.call_deferred() func _mats_halbe(res: int) -> PackedByteArray: # Linke Kartenhälfte (x < Mitte) Sand, rechte Fels — Zeile für Zeile. var mats := PackedByteArray() mats.resize(res * res) var i := 0 for z in res: for x in res: mats[i] = SAND if x < res / 2 else FELS i += 1 return mats func _x_von_material(material: int, size: float) -> float: # Objekt-Anker je Hälfte: Sand links (−35 % Größe), Fels rechts (+35 %). return -0.35 * size if material == SAND else 0.35 * size func _shot(pfad: String) -> void: await process_frame await RenderingServer.frame_post_draw 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()]) ## „Modelle fehlen“-AcceptDialog schließen (kommt erst nach 2 Frames von ## utils/modelle_status.gd — mehrfach probieren, mit Wartezeit dazwischen). func _dismiss_dialogs() -> void: for i in 6: await process_frame var stack: Array = [root] while not stack.is_empty(): var n: Node = stack.pop_back() if n is AcceptDialog: (n as AcceptDialog).hide() n.queue_free() stack.append_array(n.get_children()) ## UI-Panels ausblenden: die 3D-Ansicht bekommt fast das ganze Fenster — ## das Beweisbild zeigt die Kontur groß statt im schmalen Streifen. Vom ## SubViewport-Container aufwärts werden alle GESCHWISTER versteckt. func _maximiere_3d(main: Node) -> void: var vp_container: Node = null var stack: Array = [main] while not stack.is_empty(): var n: Node = stack.pop_back() if n is SubViewportContainer: vp_container = n break stack.append_array(n.get_children()) if vp_container == null: return var laeufer: Node = vp_container while laeufer != null and laeufer != main: var elter: Node = laeufer.get_parent() if elter == null: break for kind in elter.get_children(): if kind != laeufer and kind is Control: (kind as Control).visible = false laeufer = elter func _run() -> void: var modus := OS.get_environment("U6_MODUS") if modus.is_empty(): modus = "nachher" var material := SAND if OS.get_environment("U6_BODEN") != "fels" else FELS var scene: PackedScene = load("res://scenes/main.tscn") var main = scene.instantiate() root.add_child(main) await process_frame await process_frame await _dismiss_dialogs() _maximiere_3d(main) DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) DisplayServer.window_set_size(Vector2i(2328, 1310)) # Echte Karte: flaches Terrain, Material-Schicht Sand/Fels. var size := 1024.0 var res := 129 var doc: Dictionary = SvmapDocument.create_new("U6Probe", size, "mittag") var terrain: Dictionary = doc.get("terrain", {}) terrain["materials_r8_b64"] = SvmapIO.encode_materials(_mats_halbe(res)) var x := _x_von_material(material, size) (doc["objects"] as Array).append({ "id": "fass", "pos": [x, 0.0, 0.0], "scale": 1.0, "rot_y_deg": 20.0, }) main.doc = doc main.call("_after_structure_change") await process_frame await process_frame var cam = main.get("camera") if cam != null: # Nah dran: Distanz 5 m, Pivot 1,2 m westlich vom Fass — das Fass # füllt sichtbar Fläche und sitzt nicht hinter dem Pivot-Gizmo. cam.set("distance", 5.0) cam.position = Vector3(x + 2.5, 1.8, 4.0) cam.call("focus_on", Vector3(x - 1.2, 0.6, 0.0)) await process_frame await process_frame # Objekt über die ECHTE Auswahl anwählen (wie ein Klick ins Editor-UI). main.interaction.call("select_object", 0) await process_frame await process_frame # Zustands-Beleg in der Konsole (je Modus die passende Beobachtung). var builder = main.get("view_builder") var marker: Node3D = builder.object_markers[0] var mi := marker.get_child(0) as MeshInstance3D if cam != null: print("PRUEF cam: pos=%s target=%s fly=%s dist=%s" % [ str(cam.position), str(cam.get("target")), str(cam.call("fly_active")), str(cam.get("distance"))]) var hat_outline: bool = marker.has_meta("outline") \ and is_instance_valid(marker.get_meta("outline")) print("PRUEF modus=%s boden=%s glb=%s material_override=%s outline=%s" % [ modus, "sand" if material == SAND else "fels", str(bool(marker.get_meta("glb", false))), str(mi.material_override != null), str(hat_outline)]) var dir := OS.get_environment("U6_DIR") if dir.is_empty(): dir = "/tmp/u6_beweise" DirAccess.make_dir_recursive_absolute(dir) var name := "u6_%s_%s.png" % [modus, "sand" if material == SAND else "fels"] await _shot(dir.path_join(name)) print("PROBE_U6_%s_%s" % [modus.to_upper(), "OK"]) quit(0)